From 6ee852939077dcabf40fd8b3bc5a397e3d1ed03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Thu, 28 Mar 2019 17:07:23 +0100 Subject: [PATCH] vkd3d: Add support for optional device extensions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- include/vkd3d.h | 13 +++++++++++++ libs/vkd3d/device.c | 38 ++++++++++++++++++++++++++++++++----- tests/vkd3d_api.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/include/vkd3d.h b/include/vkd3d.h index 3d560b56..39c4c6bd 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -42,6 +42,8 @@ enum vkd3d_structure_type VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO, + VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO, + VKD3D_FORCE_32_BIT_ENUM(VKD3D_STRUCTURE_TYPE), }; @@ -71,6 +73,7 @@ struct vkd3d_instance_create_info uint32_t instance_extension_count; }; +/* Extends vkd3d_instance_create_info. */ struct vkd3d_optional_instance_extensions_info { enum vkd3d_structure_type type; @@ -99,6 +102,16 @@ struct vkd3d_device_create_info LUID adapter_luid; }; +/* Extends vkd3d_device_create_info. */ +struct vkd3d_optional_device_extensions_info +{ + enum vkd3d_structure_type type; + const void *next; + + const char * const *extensions; + uint32_t extension_count; +}; + /* vkd3d_image_resource_create_info flags */ #define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001 #define VKD3D_RESOURCE_PRESENT_STATE_TRANSITION 0x00000002 diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 60cac0d1..929e846e 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -974,12 +974,13 @@ static void vkd3d_init_feature_level(struct vkd3d_vulkan_info *vk_info, } static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, - const struct vkd3d_device_create_info *create_info, - VkPhysicalDeviceFeatures2KHR *features2, uint32_t *device_extension_count) + const struct vkd3d_device_create_info *create_info, VkPhysicalDeviceFeatures2KHR *features2, + uint32_t *device_extension_count, bool **user_extension_supported) { const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_divisor_properties; const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *divisor_features; + const struct vkd3d_optional_device_extensions_info *optional_extensions; VkPhysicalDeviceTransformFeedbackPropertiesEXT xfb_properties; VkPhysicalDevice physical_device = device->vk_physical_device; VkPhysicalDeviceFeatures *features = &features2->features; @@ -1076,11 +1077,27 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, return hresult_from_vk_result(vr); } + optional_extensions = vkd3d_find_struct(create_info->next, OPTIONAL_DEVICE_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; + } + *device_extension_count = vkd3d_check_extensions(vk_extensions, count, 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, - NULL, 0, NULL, vulkan_info, "device"); + optional_extensions ? optional_extensions->extensions : NULL, + optional_extensions ? optional_extensions->extension_count : 0, + *user_extension_supported, vulkan_info, "device"); divisor_features = vk_find_struct(features2->pNext, PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT); if (get_spec_version(vk_extensions, count, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) >= 3 @@ -1338,9 +1355,11 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, { const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features; + const struct vkd3d_optional_device_extensions_info *optional_extensions; VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; struct vkd3d_vulkan_info *vulkan_info = &device->vk_info; struct vkd3d_device_queue_info device_queue_info; + bool *user_extension_supported = NULL; VkPhysicalDeviceFeatures2 features2; VkPhysicalDevice physical_device; VkDeviceCreateInfo device_info; @@ -1385,11 +1404,17 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, else VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &features2.features)); - if (FAILED(hr = vkd3d_init_device_caps(device, create_info, &features2, &extension_count))) + if (FAILED(hr = vkd3d_init_device_caps(device, create_info, &features2, + &extension_count, &user_extension_supported))) return hr; if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions)))) + { + vkd3d_free(user_extension_supported); return E_OUTOFMEMORY; + } + + optional_extensions = vkd3d_find_struct(create_info->next, OPTIONAL_DEVICE_EXTENSIONS_INFO); /* Create device */ device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; @@ -1403,9 +1428,12 @@ 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, - NULL, 0, NULL, &device->vk_info); + optional_extensions ? optional_extensions->extensions : NULL, + optional_extensions ? optional_extensions->extension_count : 0, + user_extension_supported, &device->vk_info); device_info.ppEnabledExtensionNames = extensions; device_info.pEnabledFeatures = &features2.features; + vkd3d_free(user_extension_supported); vr = VK_CALL(vkCreateDevice(physical_device, &device_info, NULL, &vk_device)); vkd3d_free(extensions); diff --git a/tests/vkd3d_api.c b/tests/vkd3d_api.c index f84409be..89b388fd 100644 --- a/tests/vkd3d_api.c +++ b/tests/vkd3d_api.c @@ -478,6 +478,51 @@ static void test_additional_device_extensions(void) ok(!refcount, "Instance has %u references left.\n", refcount); } +static void test_optional_device_extensions(void) +{ + static const char * const extensions[] = + { + "VK_VKD3D_invalid_extension", + VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, + }; + + struct vkd3d_optional_device_extensions_info optional_extensions; + struct vkd3d_instance_create_info instance_create_info; + struct vkd3d_device_create_info device_create_info; + struct vkd3d_instance *instance; + ID3D12Device *device; + ULONG refcount; + HRESULT hr; + + instance_create_info = instance_default_create_info; + hr = vkd3d_create_instance(&instance_create_info, &instance); + ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr); + + device_create_info = device_default_create_info; + device_create_info.instance = instance; + device_create_info.instance_create_info = NULL; + device_create_info.device_extensions = extensions; + device_create_info.device_extension_count = ARRAY_SIZE(extensions); + hr = vkd3d_create_device(&device_create_info, &IID_ID3D12Device, (void **)&device); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + + optional_extensions.type = VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO; + optional_extensions.next = NULL; + optional_extensions.extensions = extensions; + optional_extensions.extension_count = ARRAY_SIZE(extensions); + + device_create_info.next = &optional_extensions; + device_create_info.device_extensions = NULL; + device_create_info.device_extension_count = 0; + hr = vkd3d_create_device(&device_create_info, &IID_ID3D12Device, (void **)&device); + ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr); + + refcount = ID3D12Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + refcount = vkd3d_instance_decref(instance); + ok(!refcount, "Instance has %u references left.\n", refcount); +} + static void test_physical_device(void) { struct vkd3d_device_create_info create_info; @@ -1039,6 +1084,7 @@ START_TEST(vkd3d_api) run_test(test_create_device); run_test(test_required_device_extensions); run_test(test_additional_device_extensions); + run_test(test_optional_device_extensions); run_test(test_physical_device); run_test(test_adapter_luid); run_test(test_device_parent);