[PATCH v9 2/4] vulkan-1/tests: Add tests for VK_KHR_external_memory_win32.

Derek Lesho dlesho at codeweavers.com
Wed Jun 9 14:32:17 CDT 2021


Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
---
v9: Add tests for accessing shared resources across device and process boundaries.
---
 dlls/vulkan-1/tests/vulkan.c | 402 +++++++++++++++++++++++++++++++++++
 dlls/winevulkan/make_vulkan  |   5 +-
 2 files changed, 405 insertions(+), 2 deletions(-)

diff --git a/dlls/vulkan-1/tests/vulkan.c b/dlls/vulkan-1/tests/vulkan.c
index f222c631232..0bfee72cd59 100644
--- a/dlls/vulkan-1/tests/vulkan.c
+++ b/dlls/vulkan-1/tests/vulkan.c
@@ -548,6 +548,379 @@ static void test_null_hwnd(VkInstance vk_instance, VkPhysicalDevice vk_physical_
     vkDestroySurfaceKHR(vk_instance, surface, NULL);
 }
 
+uint32_t find_memory_type(VkPhysicalDevice vk_physical_device, VkMemoryPropertyFlagBits flags, uint32_t mask)
+{
+    VkPhysicalDeviceMemoryProperties properties = {0};
+    unsigned int i;
+
+    vkGetPhysicalDeviceMemoryProperties(vk_physical_device, &properties);
+
+    for(i = 0; i < properties.memoryTypeCount; i++)
+    {
+        if ((1u << i) & mask && properties.memoryTypes[i].propertyFlags & flags)
+            return i;
+    }
+    return -1;
+}
+
+static void test_cross_process_resource(VkInstance vk_instance, VkPhysicalDevice vk_physical_device, BOOL kmt, HANDLE handle)
+{
+    char driver_uuid[VK_UUID_SIZE * 2 + 1], device_uuid[VK_UUID_SIZE * 2 + 1];
+    PFN_vkGetPhysicalDeviceProperties2 pfn_vkGetPhysicalDeviceProperties2;
+    VkPhysicalDeviceIDPropertiesKHR device_id_properties;
+    VkPhysicalDeviceProperties2KHR device_properties;
+    STARTUPINFOA si = { sizeof(si) };
+    PROCESS_INFORMATION info;
+    char **argv, buf[MAX_PATH];
+    unsigned int i;
+    BOOL res;
+
+    if (!(pfn_vkGetPhysicalDeviceProperties2
+            = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2")))
+        pfn_vkGetPhysicalDeviceProperties2
+            = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2KHR");
+    if (!pfn_vkGetPhysicalDeviceProperties2)
+    {
+        skip("Skipping cross process shared resource test due to lack of VK_KHR_get_physical_device_properties2.\n");
+        return;
+    }
+
+    device_id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR;
+    device_id_properties.pNext = NULL;
+
+    device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
+    device_properties.pNext = &device_id_properties;
+
+    pfn_vkGetPhysicalDeviceProperties2(vk_physical_device, &device_properties);
+
+    for (i = 0; i < VK_UUID_SIZE; i++)
+    {
+        sprintf(&driver_uuid[i * 2], "%02X",  device_id_properties.driverUUID[i]);
+        sprintf(&device_uuid[i * 2], "%02X",  device_id_properties.deviceUUID[i]);
+    }
+    driver_uuid[i * 2] = 0;
+    device_uuid[i * 2] = 0;
+
+    winetest_get_mainargs(&argv);
+    sprintf(buf, "\"%s\" vulkan resource %s %s %s %p", argv[0], driver_uuid, device_uuid,
+                                                        kmt ? "kmt" : "nt", handle);
+    res = CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0L, NULL, NULL, &si, &info);
+    ok(res, "CreateProcess failed: %u\n", GetLastError());
+    CloseHandle(info.hThread);
+
+    wait_child_process(info.hProcess);
+}
+
+static const char *test_external_memory_extensions[] =
+{
+    "VK_KHR_external_memory_capabilities",
+};
+
+static void test_external_memory(VkInstance vk_instance, VkPhysicalDevice vk_physical_device)
+{
+    PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR pfn_vkGetPhysicalDeviceExternalBufferPropertiesKHR;
+    PFN_vkGetMemoryWin32HandleKHR pfn_vkGetMemoryWin32HandleKHR;
+    VkPhysicalDeviceExternalBufferInfoKHR external_buffer_info;
+    VkExternalBufferPropertiesKHR external_buffer_properties;
+    VkMemoryDedicatedAllocateInfoKHR dedicated_alloc_info;
+    VkExportMemoryWin32HandleInfoKHR export_handle_info;
+    VkImportMemoryWin32HandleInfoKHR import_handle_info;
+    VkExportMemoryAllocateInfoKHR export_memory_info;
+    VkMemoryGetWin32HandleInfoKHR get_handle_info;
+    VkDeviceMemory vk_memory, vk_memory_import;
+    VkMemoryRequirements memory_requirements;
+    VkBufferCreateInfo buffer_create_info;
+    VkMemoryAllocateInfo alloc_info;
+    uint32_t queue_family_index;
+    SECURITY_ATTRIBUTES sa;
+    VkBuffer vk_buffer;
+    VkDevice vk_device;
+    HANDLE handle;
+    VkResult vr;
+    char **argv;
+    int argc;
+
+    static const char *extensions[] =
+    {
+        "VK_KHR_dedicated_allocation",
+        "VK_KHR_external_memory",
+        "VK_KHR_external_memory_win32",
+    };
+
+    pfn_vkGetPhysicalDeviceExternalBufferPropertiesKHR =
+        (void*) vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
+
+    if ((vr = create_device(vk_physical_device, ARRAY_SIZE(extensions), extensions, NULL, &vk_device)))
+    {
+        skip("Failed to create device with external memory extensions, VkResult %d.\n", vr);
+        return;
+    }
+
+    pfn_vkGetMemoryWin32HandleKHR = (void *) vkGetDeviceProcAddr(vk_device, "vkGetMemoryWin32HandleKHR");
+
+    find_queue_family(vk_physical_device, VK_QUEUE_GRAPHICS_BIT, &queue_family_index);
+
+    /* Most implementations only support exporting dedicated allocations */
+
+    buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buffer_create_info.pNext = NULL;
+    buffer_create_info.flags = 0;
+    buffer_create_info.size = 1;
+    buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+    buffer_create_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
+    buffer_create_info.queueFamilyIndexCount = 1;
+    buffer_create_info.pQueueFamilyIndices = &queue_family_index;
+    if ((vr = vkCreateBuffer(vk_device, &buffer_create_info, NULL, &vk_buffer)))
+    {
+        skip("Failed to create generic buffer, VkResult %d.\n", vr);
+        vkDestroyDevice(vk_device, NULL);
+        return;
+    }
+
+    dedicated_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR;
+    dedicated_alloc_info.pNext = NULL;
+    dedicated_alloc_info.image = VK_NULL_HANDLE;
+    dedicated_alloc_info.buffer = vk_buffer;
+
+    external_buffer_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR;
+    external_buffer_info.pNext = NULL;
+    external_buffer_info.flags = 0;
+    external_buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+    external_buffer_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
+
+    memset(&external_buffer_properties, 0, sizeof(external_buffer_properties));
+    external_buffer_properties.sType = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR;
+
+    pfn_vkGetPhysicalDeviceExternalBufferPropertiesKHR(vk_physical_device, &external_buffer_info, &external_buffer_properties);
+
+    vkGetBufferMemoryRequirements(vk_device, vk_buffer, &memory_requirements);
+
+    alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    alloc_info.allocationSize = memory_requirements.size;
+    alloc_info.memoryTypeIndex = find_memory_type(vk_physical_device, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memory_requirements.memoryTypeBits);
+
+    argc = winetest_get_mainargs(&argv);
+    if (argc > 3 && !strcmp(argv[2], "resource"))
+    {
+        sscanf(argv[6], "%p", &handle);
+
+        import_handle_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
+        import_handle_info.pNext = &dedicated_alloc_info;
+        import_handle_info.handleType = strcmp(argv[5], "kmt") ?
+            VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR :
+            VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
+        import_handle_info.handle = handle;
+        import_handle_info.name = NULL;
+
+        alloc_info.pNext = &import_handle_info;
+
+        vr = vkAllocateMemory(vk_device, &alloc_info, NULL, &vk_memory);
+        ok(vr == VK_SUCCESS, "vkAllocateMemory failed, VkResult %d.\n", vr);
+
+        vkFreeMemory(vk_device, vk_memory, NULL);
+        vkDestroyBuffer(vk_device, vk_buffer, NULL);
+        vkDestroyDevice(vk_device, NULL);
+
+        return;
+    }
+
+    if (!(external_buffer_properties.externalMemoryProperties.externalMemoryFeatures &
+            (VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)))
+        skip("With desired parameters, buffers are not exportable to and importable from an NT handle.\n");
+    else
+    {
+        ok(external_buffer_properties.externalMemoryProperties.compatibleHandleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR,
+            "Unexpected compatibleHandleTypes %#x.\n", external_buffer_properties.externalMemoryProperties.compatibleHandleTypes);
+
+        export_memory_info.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
+        export_memory_info.pNext = &dedicated_alloc_info;
+        export_memory_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
+
+        sa.nLength = sizeof(sa);
+        sa.lpSecurityDescriptor = NULL;
+        sa.bInheritHandle = TRUE;
+
+        export_handle_info.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
+        export_handle_info.pNext = &export_memory_info;
+        export_handle_info.name = L"wine_test_buffer_export_name";
+        export_handle_info.dwAccess = GENERIC_ALL;
+        export_handle_info.pAttributes = &sa;
+
+        alloc_info.pNext = &export_handle_info;
+
+        ok(alloc_info.memoryTypeIndex != -1, "Device local memory type index was not found.\n");
+
+        vr = vkAllocateMemory(vk_device, &alloc_info, NULL, &vk_memory);
+        ok(vr == VK_SUCCESS, "vkAllocateMemory failed, VkResult %d.\n", vr);
+
+        get_handle_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
+        get_handle_info.pNext = NULL;
+        get_handle_info.memory = vk_memory;
+        get_handle_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
+
+        vr = pfn_vkGetMemoryWin32HandleKHR(vk_device, &get_handle_info, &handle);
+        ok(vr == VK_SUCCESS, "vkGetMemoryWin32HandleKHR failed, VkResult %d.\n", vr);
+
+        import_handle_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
+        import_handle_info.pNext = &dedicated_alloc_info;
+        import_handle_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
+        import_handle_info.handle = handle;
+        import_handle_info.name = NULL;
+
+        alloc_info.pNext = &import_handle_info;
+
+        vr = vkAllocateMemory(vk_device, &alloc_info, NULL, &vk_memory_import);
+        ok(vr == VK_SUCCESS, "vkAllocateMemory failed, VkResult %d.\n", vr);
+        ok(vk_memory_import != vk_memory, "Expected new memory object.\n");
+
+        vkFreeMemory(vk_device, vk_memory_import, NULL);
+
+        import_handle_info.handle = NULL;
+        import_handle_info.name = L"wine_test_buffer_export_name";
+
+        vr = vkAllocateMemory(vk_device, &alloc_info, NULL, &vk_memory_import);
+        ok(vr == VK_SUCCESS, "vkAllocateMemory failed, VkResult %d.\n", vr);
+        ok(vk_memory_import != vk_memory, "Expected new memory object.\n");
+
+        vkFreeMemory(vk_device, vk_memory_import, NULL);
+
+        test_cross_process_resource(vk_instance, vk_physical_device, FALSE, handle);
+
+        vkFreeMemory(vk_device, vk_memory, NULL);
+        CloseHandle(handle);
+    }
+
+    external_buffer_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
+
+    memset(&external_buffer_properties, 0, sizeof(external_buffer_properties));
+    external_buffer_properties.sType = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR;
+
+    pfn_vkGetPhysicalDeviceExternalBufferPropertiesKHR(vk_physical_device, &external_buffer_info, &external_buffer_properties);
+
+    if (!(external_buffer_properties.externalMemoryProperties.externalMemoryFeatures &
+            (VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)))
+        skip("With desired parameters, buffers are not exportable to and importable from a KMT handle.\n");
+    else
+    {
+        ok(external_buffer_properties.externalMemoryProperties.compatibleHandleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR,
+            "Unexpected compatibleHandleTypes %#x.\n", external_buffer_properties.externalMemoryProperties.compatibleHandleTypes);
+
+        export_memory_info.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
+        export_memory_info.pNext = &dedicated_alloc_info;
+        export_memory_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
+
+        alloc_info.pNext = &export_memory_info;
+
+        ok(alloc_info.memoryTypeIndex != -1, "Device local memory type index was not found.\n");
+
+        vr = vkAllocateMemory(vk_device, &alloc_info, NULL, &vk_memory);
+        ok(vr == VK_SUCCESS, "vkAllocateMemory failed, VkResult %d.\n", vr);
+
+        get_handle_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
+        get_handle_info.pNext = NULL;
+        get_handle_info.memory = vk_memory;
+        get_handle_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
+
+        vr = pfn_vkGetMemoryWin32HandleKHR(vk_device, &get_handle_info, &handle);
+        ok(vr == VK_SUCCESS, "vkGetMemoryWin32HandleKHR failed, VkResult %d.\n", vr);
+
+        import_handle_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
+        import_handle_info.pNext = &dedicated_alloc_info;
+        import_handle_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
+        import_handle_info.handle = handle;
+        import_handle_info.name = NULL;
+
+        alloc_info.pNext = &import_handle_info;
+
+        vr = vkAllocateMemory(vk_device, &alloc_info, NULL, &vk_memory_import);
+        ok(vr == VK_SUCCESS, "vkAllocateMemory failed, VkResult %d.\n", vr);
+        ok(vk_memory_import != vk_memory, "Expected new memory object.\n");
+
+        vkFreeMemory(vk_device, vk_memory_import, NULL);
+
+        test_cross_process_resource(vk_instance, vk_physical_device, TRUE, handle);
+
+        vkFreeMemory(vk_device, vk_memory, NULL);
+    }
+
+    vkDestroyBuffer(vk_device, vk_buffer, NULL);
+    vkDestroyDevice(vk_device, NULL);
+}
+
+static void test_unique_device(uint8_t driver_uuid[VK_UUID_SIZE], uint8_t device_uuid[VK_UUID_SIZE],
+        uint32_t extension_count, const char * const *enabled_extensions,
+        void (*test_func_instance)(VkInstance, VkPhysicalDevice), void (*test_func)(VkPhysicalDevice))
+{
+    PFN_vkGetPhysicalDeviceProperties2 pfn_vkGetPhysicalDeviceProperties2;
+    VkPhysicalDeviceIDPropertiesKHR device_id_properties;
+    VkPhysicalDeviceProperties2KHR device_properties;
+    VkPhysicalDevice *vk_physical_devices;
+    VkInstance vk_instance;
+    unsigned int i, j;
+    uint32_t count;
+    VkResult vr;
+
+    if ((vr = create_instance_skip(extension_count, enabled_extensions, &vk_instance)) < 0)
+        return;
+    ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+
+    pfn_vkGetPhysicalDeviceProperties2
+            = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2");
+    if (!pfn_vkGetPhysicalDeviceProperties2)
+        pfn_vkGetPhysicalDeviceProperties2
+            = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2KHR");
+    if (!pfn_vkGetPhysicalDeviceProperties2)
+    {
+        skip("Skipping cross process shared resource test due to lack of VK_KHR_get_physical_device_properties2.\n");
+        return;
+    }
+
+    vr = vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
+    if (vr || !count)
+    {
+        skip("No physical devices. VkResult %d.\n", vr);
+        vkDestroyInstance(vk_instance, NULL);
+        return;
+    }
+
+    vk_physical_devices = heap_calloc(count, sizeof(*vk_physical_devices));
+    ok(!!vk_physical_devices, "Failed to allocated memory.\n");
+    vr = vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
+    ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+
+    for (i = 0; i < count; i++)
+    {
+        device_id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR;
+        device_id_properties.pNext = NULL;
+
+        device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
+        device_properties.pNext = &device_id_properties;
+
+        pfn_vkGetPhysicalDeviceProperties2(vk_physical_devices[i], &device_properties);
+
+        for (j = 0; j < VK_UUID_SIZE; j++)
+        {
+            if (device_id_properties.driverUUID[j] != driver_uuid[j] || device_id_properties.deviceUUID[j] != device_uuid[j])
+                break;
+        }
+
+        if (j == VK_UUID_SIZE)
+        {
+            if (test_func_instance)
+                test_func_instance(vk_instance, vk_physical_devices[i]);
+            else
+                test_func(vk_physical_devices[i]);
+
+            break;
+        }
+    }
+    ok(i != count, "Failed to find matching physical device.\n");
+
+    heap_free(vk_physical_devices);
+
+    vkDestroyInstance(vk_instance, NULL);
+}
+
 static void for_each_device_instance(uint32_t extension_count, const char * const *enabled_extensions,
         void (*test_func_instance)(VkInstance, VkPhysicalDevice), void (*test_func)(VkPhysicalDevice))
 {
@@ -594,6 +967,34 @@ static void for_each_device(void (*test_func)(VkPhysicalDevice))
 
 START_TEST(vulkan)
 {
+    unsigned int val;
+    unsigned int i;
+    char **argv;
+    int argc;
+
+    argc = winetest_get_mainargs(&argv);
+
+    if (argc > 3)
+    {
+        if (!strcmp(argv[2], "resource"))
+        {
+            uint8_t driver_uuid[VK_UUID_SIZE], device_uuid[VK_UUID_SIZE];
+
+            ok(argc >= 7, "Missing launch arguments\n");
+
+            for (i = 0; i < VK_UUID_SIZE; i++)
+            {
+                /* %02hhX overflows to write 4 bytes on win32 */
+                sscanf(&argv[3][i * 2], "%02X", &val); driver_uuid[i] = val;
+                sscanf(&argv[4][i * 2], "%02X", &val); device_uuid[i] = val;
+            }
+
+            test_unique_device(driver_uuid, device_uuid,
+                ARRAY_SIZE(test_external_memory_extensions), test_external_memory_extensions, test_external_memory, NULL);
+            return;
+        }
+    }
+
     test_instance_version();
     for_each_device(enumerate_physical_device);
     test_enumerate_physical_device2();
@@ -604,4 +1005,5 @@ START_TEST(vulkan)
     for_each_device(test_unsupported_device_extensions);
     for_each_device(test_private_data);
     for_each_device_instance(ARRAY_SIZE(test_null_hwnd_extensions), test_null_hwnd_extensions, test_null_hwnd, NULL);
+    for_each_device_instance(ARRAY_SIZE(test_external_memory_extensions), test_external_memory_extensions, test_external_memory, NULL);
 }
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index d226057c69e..f640cc81ded 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -99,7 +99,6 @@ UNSUPPORTED_EXTENSIONS = [
     "VK_EXT_pipeline_creation_feedback",
     "VK_GOOGLE_display_timing",
     "VK_KHR_external_fence_win32",
-    "VK_KHR_external_memory_win32",
     "VK_KHR_external_semaphore_win32",
     # Relates to external_semaphore and needs type conversions in bitflags.
     "VK_KHR_shared_presentable_image", # Needs WSI work.
@@ -123,7 +122,9 @@ UNSUPPORTED_EXTENSIONS = [
 # Either internal extensions which aren't present on the win32 platform which
 # winevulkan may nonetheless use, or extensions we want to generate headers for
 # but not expose to applications (useful for test commits)
-UNEXPOSED_EXTENSIONS = {}
+UNEXPOSED_EXTENSIONS = {
+    "VK_KHR_external_memory_win32",
+}
 
 # The Vulkan loader provides entry-points for core functionality and important
 # extensions. Based on vulkan-1.def this amounts to WSI extensions on 1.0.51.
-- 
2.31.1




More information about the wine-devel mailing list