vkd3d: Add support for optional device extensions.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2019-03-28 17:07:23 +01:00 committed by Alexandre Julliard
parent 053a2b0f52
commit 6ee8529390
3 changed files with 92 additions and 5 deletions

View File

@ -42,6 +42,8 @@ enum vkd3d_structure_type
VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO, VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO,
VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_STRUCTURE_TYPE), VKD3D_FORCE_32_BIT_ENUM(VKD3D_STRUCTURE_TYPE),
}; };
@ -71,6 +73,7 @@ struct vkd3d_instance_create_info
uint32_t instance_extension_count; uint32_t instance_extension_count;
}; };
/* Extends vkd3d_instance_create_info. */
struct vkd3d_optional_instance_extensions_info struct vkd3d_optional_instance_extensions_info
{ {
enum vkd3d_structure_type type; enum vkd3d_structure_type type;
@ -99,6 +102,16 @@ struct vkd3d_device_create_info
LUID adapter_luid; 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 */ /* vkd3d_image_resource_create_info flags */
#define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001 #define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001
#define VKD3D_RESOURCE_PRESENT_STATE_TRANSITION 0x00000002 #define VKD3D_RESOURCE_PRESENT_STATE_TRANSITION 0x00000002

View File

@ -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, static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
const struct vkd3d_device_create_info *create_info, const struct vkd3d_device_create_info *create_info, VkPhysicalDeviceFeatures2KHR *features2,
VkPhysicalDeviceFeatures2KHR *features2, uint32_t *device_extension_count) uint32_t *device_extension_count, bool **user_extension_supported)
{ {
const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs; const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs;
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_divisor_properties; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_divisor_properties;
const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *divisor_features; const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *divisor_features;
const struct vkd3d_optional_device_extensions_info *optional_extensions;
VkPhysicalDeviceTransformFeedbackPropertiesEXT xfb_properties; VkPhysicalDeviceTransformFeedbackPropertiesEXT xfb_properties;
VkPhysicalDevice physical_device = device->vk_physical_device; VkPhysicalDevice physical_device = device->vk_physical_device;
VkPhysicalDeviceFeatures *features = &features2->features; VkPhysicalDeviceFeatures *features = &features2->features;
@ -1076,11 +1077,27 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
return hresult_from_vk_result(vr); 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, *device_extension_count = vkd3d_check_extensions(vk_extensions, count,
required_device_extensions, ARRAY_SIZE(required_device_extensions), required_device_extensions, ARRAY_SIZE(required_device_extensions),
optional_device_extensions, ARRAY_SIZE(optional_device_extensions), optional_device_extensions, ARRAY_SIZE(optional_device_extensions),
create_info->device_extensions, create_info->device_extension_count, 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); 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 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; const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs;
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features;
const struct vkd3d_optional_device_extensions_info *optional_extensions;
VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features;
struct vkd3d_vulkan_info *vulkan_info = &device->vk_info; struct vkd3d_vulkan_info *vulkan_info = &device->vk_info;
struct vkd3d_device_queue_info device_queue_info; struct vkd3d_device_queue_info device_queue_info;
bool *user_extension_supported = NULL;
VkPhysicalDeviceFeatures2 features2; VkPhysicalDeviceFeatures2 features2;
VkPhysicalDevice physical_device; VkPhysicalDevice physical_device;
VkDeviceCreateInfo device_info; VkDeviceCreateInfo device_info;
@ -1385,11 +1404,17 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
else else
VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &features2.features)); 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; return hr;
if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions)))) if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions))))
{
vkd3d_free(user_extension_supported);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
}
optional_extensions = vkd3d_find_struct(create_info->next, OPTIONAL_DEVICE_EXTENSIONS_INFO);
/* Create device */ /* Create device */
device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 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), required_device_extensions, ARRAY_SIZE(required_device_extensions),
optional_device_extensions, ARRAY_SIZE(optional_device_extensions), optional_device_extensions, ARRAY_SIZE(optional_device_extensions),
create_info->device_extensions, create_info->device_extension_count, 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.ppEnabledExtensionNames = extensions;
device_info.pEnabledFeatures = &features2.features; device_info.pEnabledFeatures = &features2.features;
vkd3d_free(user_extension_supported);
vr = VK_CALL(vkCreateDevice(physical_device, &device_info, NULL, &vk_device)); vr = VK_CALL(vkCreateDevice(physical_device, &device_info, NULL, &vk_device));
vkd3d_free(extensions); vkd3d_free(extensions);

View File

@ -478,6 +478,51 @@ static void test_additional_device_extensions(void)
ok(!refcount, "Instance has %u references left.\n", refcount); 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) static void test_physical_device(void)
{ {
struct vkd3d_device_create_info create_info; struct vkd3d_device_create_info create_info;
@ -1039,6 +1084,7 @@ START_TEST(vkd3d_api)
run_test(test_create_device); run_test(test_create_device);
run_test(test_required_device_extensions); run_test(test_required_device_extensions);
run_test(test_additional_device_extensions); run_test(test_additional_device_extensions);
run_test(test_optional_device_extensions);
run_test(test_physical_device); run_test(test_physical_device);
run_test(test_adapter_luid); run_test(test_adapter_luid);
run_test(test_device_parent); run_test(test_device_parent);