[PATCH vkd3d 6/9] vkd3d: Add support for optional instance extensions.
Józef Kucia
joseph.kucia at gmail.com
Fri Aug 17 02:57:00 CDT 2018
From: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
include/vkd3d.h | 11 +++++
libs/vkd3d/device.c | 116 ++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 109 insertions(+), 18 deletions(-)
diff --git a/include/vkd3d.h b/include/vkd3d.h
index d089ada56b72..fcff16681fec 100644
--- a/include/vkd3d.h
+++ b/include/vkd3d.h
@@ -40,6 +40,8 @@ enum vkd3d_structure_type
VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO,
+ VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO,
+
VKD3D_FORCE_32_BIT_ENUM(VKD3D_STRUCTURE_TYPE),
};
@@ -69,6 +71,15 @@ struct vkd3d_instance_create_info
uint32_t instance_extension_count;
};
+struct vkd3d_optional_instance_extensions_info
+{
+ enum vkd3d_structure_type type;
+ const void *next;
+
+ const char * const *extensions;
+ uint32_t extension_count;
+};
+
struct vkd3d_device_create_info
{
enum vkd3d_structure_type type;
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 47b56e5975fd..c11f474a28d2 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -20,6 +20,27 @@
#include <dlfcn.h>
+struct vkd3d_struct
+{
+ enum vkd3d_structure_type type;
+ const void *next;
+};
+
+#define vkd3d_find_struct(c, t) vkd3d_find_struct_(c, VKD3D_STRUCTURE_TYPE_##t)
+static const void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
+ enum vkd3d_structure_type type)
+{
+ while (chain)
+ {
+ if (chain->type == type)
+ return chain;
+
+ chain = chain->next;
+ }
+
+ return NULL;
+}
+
struct vkd3d_optional_extension_info
{
const char *extension_name;
@@ -88,7 +109,8 @@ static unsigned int vkd3d_check_extensions(const VkExtensionProperties *extensio
const char * const *required_extensions, unsigned int required_extension_count,
const struct vkd3d_optional_extension_info *optional_extensions, unsigned int optional_extension_count,
const char * const *user_extensions, unsigned int user_extension_count,
- struct vkd3d_vulkan_info *vulkan_info, const char *extension_type)
+ const char * const *optional_user_extensions, unsigned int optional_user_extension_count,
+ bool *user_extension_supported, struct vkd3d_vulkan_info *vulkan_info, const char *extension_type)
{
unsigned int extension_count = 0;
unsigned int i;
@@ -123,6 +145,38 @@ static unsigned int vkd3d_check_extensions(const VkExtensionProperties *extensio
++extension_count;
}
+ assert(!optional_user_extension_count || user_extension_supported);
+ for (i = 0; i < optional_user_extension_count; ++i)
+ {
+ if (has_extension(extensions, count, optional_user_extensions[i], false))
+ {
+ user_extension_supported[i] = true;
+ ++extension_count;
+ }
+ else
+ {
+ user_extension_supported[i] = false;
+ WARN("Optional user %s extension %s is not supported.\n",
+ extension_type, debugstr_a(optional_user_extensions[i]));
+ }
+ }
+
+ return extension_count;
+}
+
+static unsigned int vkd3d_append_extension(const char *extensions[],
+ unsigned int extension_count, const char *extension_name)
+{
+ unsigned int i;
+
+ /* avoid duplicates */
+ for (i = 0; i < extension_count; ++i)
+ {
+ if (!strcmp(extensions[i], extension_name))
+ return extension_count;
+ }
+
+ extensions[extension_count++] = extension_name;
return extension_count;
}
@@ -130,10 +184,11 @@ static unsigned int vkd3d_enable_extensions(const char *extensions[],
const char * const *required_extensions, unsigned int required_extension_count,
const struct vkd3d_optional_extension_info *optional_extensions, unsigned int optional_extension_count,
const char * const *user_extensions, unsigned int user_extension_count,
- const struct vkd3d_vulkan_info *vulkan_info)
+ const char * const *optional_user_extensions, unsigned int optional_user_extension_count,
+ bool *user_extension_supported, const struct vkd3d_vulkan_info *vulkan_info)
{
unsigned int extension_count = 0;
- unsigned int i, j;
+ unsigned int i;
for (i = 0; i < required_extension_count; ++i)
{
@@ -147,18 +202,17 @@ static unsigned int vkd3d_enable_extensions(const char *extensions[],
if (*supported)
extensions[extension_count++] = optional_extensions[i].extension_name;
}
+
for (i = 0; i < user_extension_count; ++i)
{
- /* avoid duplicates */
- for (j = 0; j < extension_count; ++j)
- {
- if (!strcmp(extensions[j], user_extensions[i]))
- break;
- }
- if (j != extension_count)
+ extension_count = vkd3d_append_extension(extensions, extension_count, user_extensions[i]);
+ }
+ assert(!optional_user_extension_count || user_extension_supported);
+ for (i = 0; i < optional_user_extension_count; ++i)
+ {
+ if (!user_extension_supported[i])
continue;
-
- extensions[extension_count++] = user_extensions[i];
+ extension_count = vkd3d_append_extension(extensions, extension_count, optional_user_extensions[i]);
}
return extension_count;
@@ -166,9 +220,10 @@ static unsigned int vkd3d_enable_extensions(const char *extensions[],
static HRESULT vkd3d_init_instance_caps(struct vkd3d_instance *instance,
const struct vkd3d_instance_create_info *create_info,
- uint32_t *instance_extension_count)
+ uint32_t *instance_extension_count, bool **user_extension_supported)
{
const struct vkd3d_vk_global_procs *vk_procs = &instance->vk_global_procs;
+ const struct vkd3d_optional_instance_extensions_info *optional_extensions;
struct vkd3d_vulkan_info *vulkan_info = &instance->vk_info;
VkExtensionProperties *vk_extensions;
uint32_t count;
@@ -196,10 +251,26 @@ static HRESULT vkd3d_init_instance_caps(struct vkd3d_instance *instance,
return hresult_from_vk_result(vr);
}
+ optional_extensions = vkd3d_find_struct(create_info->next, OPTIONAL_INSTANCE_EXTENSIONS_INFO);
+ if (optional_extensions && optional_extensions->extension_count)
+ {
+ if (!(*user_extension_supported = vkd3d_calloc(optional_extensions->extension_count, sizeof(bool))))
+ {
+ vkd3d_free(vk_extensions);
+ return E_OUTOFMEMORY;
+ }
+ }
+ else
+ {
+ *user_extension_supported = NULL;
+ }
+
*instance_extension_count = vkd3d_check_extensions(vk_extensions, count, NULL, 0,
optional_instance_extensions, ARRAY_SIZE(optional_instance_extensions),
create_info->instance_extensions, create_info->instance_extension_count,
- vulkan_info, "instance");
+ optional_extensions ? optional_extensions->extensions : NULL,
+ optional_extensions ? optional_extensions->extension_count : 0,
+ *user_extension_supported, vulkan_info, "instance");
vkd3d_free(vk_extensions);
return S_OK;
@@ -276,6 +347,8 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
const struct vkd3d_instance_create_info *create_info)
{
const struct vkd3d_vk_global_procs *vk_global_procs = &instance->vk_global_procs;
+ const struct vkd3d_optional_instance_extensions_info *optional_extensions;
+ bool *user_extension_supported = NULL;
VkApplicationInfo application_info;
VkInstanceCreateInfo instance_info;
uint32_t extension_count;
@@ -313,7 +386,8 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
return hr;
}
- if (FAILED(hr = vkd3d_init_instance_caps(instance, create_info, &extension_count)))
+ if (FAILED(hr = vkd3d_init_instance_caps(instance, create_info,
+ &extension_count, &user_extension_supported)))
{
if (instance->libvulkan)
dlclose(instance->libvulkan);
@@ -332,9 +406,12 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
{
if (instance->libvulkan)
dlclose(instance->libvulkan);
+ vkd3d_free(user_extension_supported);
return E_OUTOFMEMORY;
}
+ optional_extensions = vkd3d_find_struct(create_info->next, OPTIONAL_INSTANCE_EXTENSIONS_INFO);
+
instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instance_info.pNext = NULL;
instance_info.flags = 0;
@@ -344,8 +421,11 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
instance_info.enabledExtensionCount = vkd3d_enable_extensions(extensions, NULL, 0,
optional_instance_extensions, ARRAY_SIZE(optional_instance_extensions),
create_info->instance_extensions, create_info->instance_extension_count,
- &instance->vk_info);
+ optional_extensions ? optional_extensions->extensions : NULL,
+ optional_extensions ? optional_extensions->extension_count : 0,
+ user_extension_supported, &instance->vk_info);
instance_info.ppEnabledExtensionNames = extensions;
+ vkd3d_free(user_extension_supported);
vr = vk_global_procs->vkCreateInstance(&instance_info, NULL, &vk_instance);
vkd3d_free(extensions);
@@ -805,7 +885,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
required_device_extensions, ARRAY_SIZE(required_device_extensions),
optional_device_extensions, ARRAY_SIZE(optional_device_extensions),
create_info->device_extensions, create_info->device_extension_count,
- vulkan_info, "device");
+ NULL, 0, NULL, vulkan_info, "device");
vkd3d_free(vk_extensions);
return S_OK;
@@ -1039,7 +1119,7 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
required_device_extensions, ARRAY_SIZE(required_device_extensions),
optional_device_extensions, ARRAY_SIZE(optional_device_extensions),
create_info->device_extensions, create_info->device_extension_count,
- &device->vk_info);
+ NULL, 0, NULL, &device->vk_info);
device_info.ppEnabledExtensionNames = extensions;
device_info.pEnabledFeatures = &device_features;
--
2.16.4
More information about the wine-devel
mailing list