=?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