From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- include/vkd3d.h | 3 ++ libs/vkd3d-utils/vkd3d_utils_main.c | 7 +-- libs/vkd3d/device.c | 92 ++++++++++++++++++++++++++++--------- 3 files changed, 76 insertions(+), 26 deletions(-)
diff --git a/include/vkd3d.h b/include/vkd3d.h index ac37c26f4a9a..0eb85ea27d2e 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -52,6 +52,9 @@ struct vkd3d_instance_create_info
/* If set to NULL, libvkd3d loads libvulkan. */ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr_pfn; + + const char * const *instance_extensions; + uint32_t instance_extension_count; };
struct vkd3d_device_create_info diff --git a/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d-utils/vkd3d_utils_main.c index f68c47badd5c..fb4344ebf086 100644 --- a/libs/vkd3d-utils/vkd3d_utils_main.c +++ b/libs/vkd3d-utils/vkd3d_utils_main.c @@ -37,16 +37,13 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, if (adapter) FIXME("Ignoring adapter %p.\n", adapter);
+ memset(&instance_create_info, 0, sizeof(instance_create_info)); instance_create_info.signal_event_pfn = vkd3d_signal_event; - instance_create_info.create_thread_pfn = NULL; - instance_create_info.join_thread_pfn = NULL; instance_create_info.wchar_size = sizeof(WCHAR); - instance_create_info.vkGetInstanceProcAddr_pfn = NULL;
+ memset(&device_create_info, 0, sizeof(device_create_info)); device_create_info.minimum_feature_level = minimum_feature_level; - device_create_info.instance = NULL; device_create_info.instance_create_info = &instance_create_info; - device_create_info.vk_physical_device = VK_NULL_HANDLE;
return vkd3d_create_device(&device_create_info, riid, device); } diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 7a9951122e4d..21e09f10fad8 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -38,9 +38,6 @@ static const struct vkd3d_optional_extension_info optional_instance_extensions[] offsetof(struct vkd3d_vulkan_info, KHR_get_physical_device_properties2)}, };
-#define MAX_INSTANCE_EXTENSION_COUNT \ - (ARRAY_SIZE(required_instance_extensions) + ARRAY_SIZE(optional_instance_extensions)) - static const char * const required_device_extensions[] = { VK_KHR_MAINTENANCE1_EXTENSION_NAME, @@ -90,11 +87,13 @@ static bool has_extension(const VkExtensionProperties *extensions, return false; }
-static void vkd3d_check_extensions(const VkExtensionProperties *extensions, unsigned int count, +static unsigned int vkd3d_check_extensions(const VkExtensionProperties *extensions, unsigned int count, const char * const *required_extensions, unsigned int required_extension_count, const struct vkd3d_optional_extension_info *optional_extensions, unsigned int optional_extension_count, + const char * const *user_extensions, unsigned int user_extension_count, struct vkd3d_vulkan_info *vulkan_info, const char *extension_type) { + unsigned int extension_count = 0; unsigned int i;
for (i = 0; i < required_extension_count; ++i) @@ -102,6 +101,7 @@ static void vkd3d_check_extensions(const VkExtensionProperties *extensions, unsi if (!has_extension(extensions, count, required_extensions[i])) ERR("Required %s extension %s is not supported.\n", extension_type, debugstr_a(required_extensions[i])); + ++extension_count; }
for (i = 0; i < optional_extension_count; ++i) @@ -111,34 +111,64 @@ static void vkd3d_check_extensions(const VkExtensionProperties *extensions, unsi bool *supported = (void *)((uintptr_t)vulkan_info + offset);
if ((*supported = has_extension(extensions, count, extension_name))) + { TRACE("Found %s extension.\n", debugstr_a(extension_name)); + ++extension_count; + } + } + + for (i = 0; i < user_extension_count; ++i) + { + if (!has_extension(extensions, count, user_extensions[i])) + ERR("Required user %s extension %s is not supported.\n", + extension_type, debugstr_a(required_extensions[i])); + ++extension_count; } + + return extension_count; }
static unsigned int vkd3d_enable_extensions(const char *extensions[], const char * const *required_extensions, unsigned int required_extension_count, const struct vkd3d_optional_extension_info *optional_extensions, unsigned int optional_extension_count, + const char * const *user_extensions, unsigned int user_extension_count, const struct vkd3d_vulkan_info *vulkan_info) { + unsigned int extension_count = 0; unsigned int i, j;
for (i = 0; i < required_extension_count; ++i) { - extensions[i] = required_extensions[i]; + extensions[extension_count++] = required_extensions[i]; } - for (j = 0; j < optional_extension_count; ++j) + for (i = 0; i < optional_extension_count; ++i) { - ptrdiff_t offset = optional_extensions[j].vulkan_info_offset; + ptrdiff_t offset = optional_extensions[i].vulkan_info_offset; const bool *supported = (void *)((uintptr_t)vulkan_info + offset);
if (*supported) - extensions[i++] = optional_extensions[j].extension_name; + extensions[extension_count++] = optional_extensions[i].extension_name; + } + for (i = 0; i < user_extension_count; ++i) + { + /* avoid duplicates */ + for (j = 0; j < extension_count; ++j) + { + if (!strcmp(extensions[j], user_extensions[i])) + break; + } + if (j != extension_count) + continue; + + extensions[extension_count++] = user_extensions[i]; }
- return i; + return extension_count; }
-static void vkd3d_init_instance_caps(struct vkd3d_instance *instance) +static HRESULT vkd3d_init_instance_caps(struct vkd3d_instance *instance, + const struct vkd3d_instance_create_info *create_info, + uint32_t *instance_extension_count) { const struct vkd3d_vk_global_procs *vk_procs = &instance->vk_global_procs; struct vkd3d_vulkan_info *vulkan_info = &instance->vk_info; @@ -146,31 +176,36 @@ static void vkd3d_init_instance_caps(struct vkd3d_instance *instance) uint32_t count; VkResult vr;
+ memset(vulkan_info, 0, sizeof(*vulkan_info)); + *instance_extension_count = 0; + if ((vr = vk_procs->vkEnumerateInstanceExtensionProperties(NULL, &count, NULL)) < 0) { ERR("Failed to enumerate instance extensions, vr %d.\n", vr); - return; + return hresult_from_vk_result(vr); } if (!count) - return; + return S_OK;
if (!(vk_extensions = vkd3d_calloc(count, sizeof(*vk_extensions)))) - return; + return E_OUTOFMEMORY;
TRACE("Enumerating %u instance extensions.\n", count); if ((vr = vk_procs->vkEnumerateInstanceExtensionProperties(NULL, &count, vk_extensions)) < 0) { ERR("Failed to enumerate instance extensions, vr %d.\n", vr); vkd3d_free(vk_extensions); - return; + return hresult_from_vk_result(vr); }
- vkd3d_check_extensions(vk_extensions, count, + *instance_extension_count = vkd3d_check_extensions(vk_extensions, count, required_instance_extensions, ARRAY_SIZE(required_instance_extensions), optional_instance_extensions, ARRAY_SIZE(optional_instance_extensions), + create_info->instance_extensions, create_info->instance_extension_count, vulkan_info, "instance");
vkd3d_free(vk_extensions); + return S_OK; }
static HRESULT vkd3d_init_vk_global_procs(struct vkd3d_instance *instance, @@ -214,9 +249,10 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, const struct vkd3d_instance_create_info *create_info) { const struct vkd3d_vk_global_procs *vk_global_procs = &instance->vk_global_procs; - const char *extensions[MAX_INSTANCE_EXTENSION_COUNT]; VkApplicationInfo application_info; VkInstanceCreateInfo instance_info; + uint32_t extension_count; + const char **extensions; VkInstance vk_instance; VkResult vr; HRESULT hr; @@ -248,8 +284,12 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, return hr; }
- memset(&instance->vk_info, 0, sizeof(instance->vk_info)); - vkd3d_init_instance_caps(instance); + if (FAILED(hr = vkd3d_init_instance_caps(instance, create_info, &extension_count))) + { + if (instance->libvulkan) + dlclose(instance->libvulkan); + return hr; + }
application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; application_info.pNext = NULL; @@ -259,6 +299,13 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, application_info.engineVersion = 0; application_info.apiVersion = VK_API_VERSION_1_0;
+ if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions)))) + { + if (instance->libvulkan) + dlclose(instance->libvulkan); + return E_OUTOFMEMORY; + } + instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instance_info.pNext = NULL; instance_info.flags = 0; @@ -268,10 +315,13 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, instance_info.enabledExtensionCount = vkd3d_enable_extensions(extensions, required_instance_extensions, ARRAY_SIZE(required_instance_extensions), optional_instance_extensions, ARRAY_SIZE(optional_instance_extensions), + create_info->instance_extensions, create_info->instance_extension_count, &instance->vk_info); instance_info.ppEnabledExtensionNames = extensions;
- if ((vr = vk_global_procs->vkCreateInstance(&instance_info, NULL, &vk_instance))) + vr = vk_global_procs->vkCreateInstance(&instance_info, NULL, &vk_instance); + vkd3d_free(extensions); + if (vr < 0) { ERR("Failed to create Vulkan instance, vr %d.\n", vr); if (instance->libvulkan) @@ -699,7 +749,7 @@ static void vkd3d_init_device_caps(struct d3d12_device *device, vkd3d_check_extensions(vk_extensions, count, required_device_extensions, ARRAY_SIZE(required_device_extensions), optional_device_extensions, ARRAY_SIZE(optional_device_extensions), - vulkan_info, "device"); + NULL, 0, vulkan_info, "device");
vkd3d_free(vk_extensions); } @@ -917,7 +967,7 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, VkPhysicalDev device_info.enabledExtensionCount = vkd3d_enable_extensions(extensions, required_device_extensions, ARRAY_SIZE(required_device_extensions), optional_device_extensions, ARRAY_SIZE(optional_device_extensions), - &device->vk_info); + NULL, 0, &device->vk_info); device_info.ppEnabledExtensionNames = extensions; device_info.pEnabledFeatures = &device_features;
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- include/vkd3d.h | 2 ++ libs/vkd3d/device.c | 16 +++++++++++----- libs/vkd3d/vkd3d_main.c | 8 ++++---- libs/vkd3d/vkd3d_private.h | 4 +++- tests/vkd3d_api.c | 23 +++++++++++++++++++++++ 5 files changed, 43 insertions(+), 10 deletions(-)
diff --git a/include/vkd3d.h b/include/vkd3d.h index 0eb85ea27d2e..033017e78f2f 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -65,6 +65,8 @@ struct vkd3d_device_create_info const struct vkd3d_instance_create_info *instance_create_info;
VkPhysicalDevice vk_physical_device; + + LUID adapter_luid; };
/* resource flags */ diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 21e09f10fad8..e6210fc4dc9d 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2052,7 +2052,11 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface
static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, LUID *luid) { - FIXME("iface %p, luid %p stub!\n", iface, luid); + struct d3d12_device *device = impl_from_ID3D12Device(iface); + + TRACE("iface %p, luid %p.\n", iface, luid); + + *luid = device->adapter_luid;
return luid; } @@ -2117,7 +2121,7 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface) }
static HRESULT d3d12_device_init(struct d3d12_device *device, - struct vkd3d_instance *instance, VkPhysicalDevice vk_physical_device) + struct vkd3d_instance *instance, const struct vkd3d_device_create_info *create_info) { HRESULT hr;
@@ -2131,7 +2135,9 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, device->join_thread = instance->join_thread; device->wchar_size = instance->wchar_size;
- if (FAILED(hr = vkd3d_create_vk_device(device, vk_physical_device))) + device->adapter_luid = create_info->adapter_luid; + + if (FAILED(hr = vkd3d_create_vk_device(device, create_info->vk_physical_device))) { vkd3d_instance_decref(device->vkd3d_instance); return hr; @@ -2163,7 +2169,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, }
HRESULT d3d12_device_create(struct vkd3d_instance *instance, - VkPhysicalDevice vk_physical_device, struct d3d12_device **device) + const struct vkd3d_device_create_info *create_info, struct d3d12_device **device) { struct d3d12_device *object; HRESULT hr; @@ -2171,7 +2177,7 @@ HRESULT d3d12_device_create(struct vkd3d_instance *instance, if (!(object = vkd3d_malloc(sizeof(*object)))) return E_OUTOFMEMORY;
- if (FAILED(hr = d3d12_device_init(object, instance, vk_physical_device))) + if (FAILED(hr = d3d12_device_init(object, instance, create_info))) { vkd3d_free(object); return hr; diff --git a/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/vkd3d_main.c index d3b0bf4f6b9d..7dd7a1d915ac 100644 --- a/libs/vkd3d/vkd3d_main.c +++ b/libs/vkd3d/vkd3d_main.c @@ -20,13 +20,13 @@ #include "vkd3d_private.h"
HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, - REFIID riid, void **device) + REFIID iid, void **device) { struct vkd3d_instance *instance; struct d3d12_device *object; HRESULT hr;
- TRACE("create_info %p, riid %s, device %p.\n", create_info, debugstr_guid(riid), device); + TRACE("create_info %p, iid %s, device %p.\n", create_info, debugstr_guid(iid), device);
if (!create_info || !device) return E_INVALIDARG; @@ -64,13 +64,13 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, return E_FAIL; }
- hr = d3d12_device_create(instance, create_info->vk_physical_device, &object); + hr = d3d12_device_create(instance, create_info, &object); vkd3d_instance_decref(instance); if (FAILED(hr)) return hr;
return return_interface((IUnknown *)&object->ID3D12Device_iface, &IID_ID3D12Device, - riid, device); + iid, device); }
/* ID3D12RootSignatureDeserializer */ diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index f4bae9d4c771..b3607853fdc1 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -665,10 +665,12 @@ struct d3d12_device
vkd3d_create_thread_pfn create_thread; vkd3d_join_thread_pfn join_thread; + + LUID adapter_luid; };
HRESULT d3d12_device_create(struct vkd3d_instance *instance, - VkPhysicalDevice vk_physical_device, struct d3d12_device **device) DECLSPEC_HIDDEN; + const struct vkd3d_device_create_info *create_info, struct d3d12_device **device) DECLSPEC_HIDDEN; struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface) DECLSPEC_HIDDEN;
HRESULT vkd3d_create_buffer(struct d3d12_device *device, diff --git a/tests/vkd3d_api.c b/tests/vkd3d_api.c index 8dd7c78f2326..375bd6d4a4f3 100644 --- a/tests/vkd3d_api.c +++ b/tests/vkd3d_api.c @@ -299,6 +299,28 @@ static void test_physical_device(void) ok(!refcount, "Instance has %u references left.\n", refcount); }
+static void test_adapter_luid(void) +{ + struct vkd3d_device_create_info create_info; + ID3D12Device *device; + ULONG refcount; + HRESULT hr; + LUID luid; + + create_info = device_default_create_info; + create_info.adapter_luid.HighPart = 0xdeadc0de; + create_info.adapter_luid.LowPart = 0xdeadbeef; + hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device); + ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr); + + luid = ID3D12Device_GetAdapterLuid(device); + ok(luid.HighPart == 0xdeadc0de && luid.LowPart == 0xdeadbeef, + "Got unexpected LUID %08x:%08x.\n", luid.HighPart, luid.LowPart); + + refcount = ID3D12Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + static void test_vkd3d_queue(void) { ID3D12CommandQueue *direct_queue, *compute_queue, *copy_queue; @@ -362,5 +384,6 @@ START_TEST(vkd3d_api) run_test(test_create_device); run_test(test_required_device_extensions); run_test(test_physical_device); + run_test(test_adapter_luid); run_test(test_vkd3d_queue); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- tests/vkd3d_api.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+)
diff --git a/tests/vkd3d_api.c b/tests/vkd3d_api.c index 375bd6d4a4f3..9efc02a6175a 100644 --- a/tests/vkd3d_api.c +++ b/tests/vkd3d_api.c @@ -19,6 +19,8 @@ #define COBJMACROS #define INITGUID #define WIDL_C_INLINE_WRAPPERS +#define VK_USE_PLATFORM_XCB_KHR +#define VK_USE_PLATFORM_XLIB_KHR #include "vkd3d_test.h" #include <vkd3d.h>
@@ -101,6 +103,102 @@ static void test_create_instance(void) ok(!refcount, "Instance has %u references left.\n", refcount); }
+struct vulkan_extension +{ + const char *name; + bool is_supported; +}; + +static uint32_t check_instance_extensions(const char **enabled_extensions, + struct vulkan_extension *extensions, unsigned int extension_count) +{ + VkExtensionProperties *properties; + uint32_t enabled_extension_count; + unsigned int i, j; + uint32_t count; + VkResult vr; + + vr = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); + ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr); + if (!count) + return 0; + + properties = calloc(count, sizeof(*properties)); + ok(properties, "Failed to allocate memory.\n"); + vr = vkEnumerateInstanceExtensionProperties(NULL, &count, properties); + ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr); + + enabled_extension_count = 0; + for (i = 0; i < count; ++i) + { + for (j = 0; j < extension_count; ++j) + { + if (!strcmp(properties[i].extensionName, extensions[j].name)) + { + extensions[j].is_supported = true; + enabled_extensions[enabled_extension_count++] = extensions[j].name; + } + } + } + free(properties); + return enabled_extension_count; +} + +static void test_additional_instance_extensions(void) +{ + struct vkd3d_instance_create_info create_info; + const char *enabled_extensions[3]; + struct vkd3d_instance *instance; + uint32_t extension_count; + PFN_vkVoidFunction pfn; + VkInstance vk_instance; + unsigned int i; + ULONG refcount; + HRESULT hr; + + struct vulkan_extension extensions[] = + { + {VK_KHR_SURFACE_EXTENSION_NAME}, + {VK_KHR_XCB_SURFACE_EXTENSION_NAME}, + {VK_KHR_XLIB_SURFACE_EXTENSION_NAME}, + }; + + if (!(extension_count = check_instance_extensions(enabled_extensions, + extensions, ARRAY_SIZE(extensions)))) + { + skip("Found 0 extensions.\n"); + return; + } + + create_info = instance_default_create_info; + create_info.instance_extensions = enabled_extensions; + create_info.instance_extension_count = extension_count; + hr = vkd3d_create_instance(&create_info, &instance); + ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr); + vk_instance = vkd3d_instance_get_vk_instance(instance); + ok(vk_instance != VK_NULL_HANDLE, "Failed to get Vulkan instance.\n"); + + for (i = 0; i < ARRAY_SIZE(extensions); ++i) + { + if (!extensions[i].is_supported) + continue; + + if (!strcmp(extensions[i].name, VK_KHR_XCB_SURFACE_EXTENSION_NAME)) + { + pfn = vkGetInstanceProcAddr(vk_instance, "vkCreateXcbSurfaceKHR"); + ok(pfn, "Failed to get proc addr for vkCreateXcbSurfaceKHR.\n"); + } + else if (!strcmp(extensions[i].name, VK_KHR_XLIB_SURFACE_EXTENSION_NAME)) + { + pfn = vkGetInstanceProcAddr(vk_instance, "vkCreateXlibSurfaceKHR"); + ok(pfn, "Failed to get proc addr for vkCreateXlibSurfaceKHR.\n"); + } + } + + refcount = vkd3d_instance_decref(instance); + ok(!refcount, "Instance has %u references left.\n", refcount); +} + static void test_create_device(void) { struct vkd3d_instance *instance, *tmp_instance; @@ -381,6 +479,7 @@ START_TEST(vkd3d_api) }
run_test(test_create_instance); + run_test(test_additional_instance_extensions); run_test(test_create_device); run_test(test_required_device_extensions); run_test(test_physical_device);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com