=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: vkd3d: Add support for optional device extensions.

Alexandre Julliard julliard at winehq.org
Thu Mar 28 18:33:18 CDT 2019


Module: vkd3d
Branch: master
Commit: 6ee852939077dcabf40fd8b3bc5a397e3d1ed03f
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=6ee852939077dcabf40fd8b3bc5a397e3d1ed03f

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Thu Mar 28 17:07:23 2019 +0100

vkd3d: Add support for optional device extensions.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 3d560b5..39c4c6b 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 60cac0d..929e846 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 f84409b..89b388f 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);




More information about the wine-cvs mailing list