mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
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:
parent
053a2b0f52
commit
6ee8529390
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user