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

Georg Lehmann dadschoorse at gmail.com
Thu Jul 1 16:01:09 CDT 2021



On 01.07.21 21:59, Zebediah Figura (she/her) wrote:
> On 6/25/21 1:57 PM, Derek Lesho wrote:
>> Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
>> ---
>> v10:
>>    - Address comments
>>    - Minor adjustment to test_cross_process_resource parameters.
>> ---
>>   dlls/vulkan-1/tests/vulkan.c | 401 +++++++++++++++++++++++++++++++++++
>>   dlls/winevulkan/make_vulkan  |   5 +-
>>   2 files changed, 404 insertions(+), 2 deletions(-)
>>
>> diff --git a/dlls/vulkan-1/tests/vulkan.c b/dlls/vulkan-1/tests/vulkan.c
>> index f222c631232..fdf5716a914 100644
>> --- a/dlls/vulkan-1/tests/vulkan.c
>> +++ b/dlls/vulkan-1/tests/vulkan.c
>> @@ -548,6 +548,375 @@ 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)
> 
> Missing "static".
> 
>> +{
>> +    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(VkPhysicalDeviceIDPropertiesKHR 
>> *device_id_properties, BOOL kmt, HANDLE handle)
>> +{
>> +    char driver_uuid[VK_UUID_SIZE * 2 + 1], device_uuid[VK_UUID_SIZE 
>> * 2 + 1];
>> +    STARTUPINFOA si = { sizeof(si) };
>> +    PROCESS_INFORMATION info;
>> +    char **argv, buf[MAX_PATH];
>> +    unsigned int i;
>> +    BOOL res;
>> +
>> +    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",
>> +    "VK_KHR_get_physical_device_properties2",
>> +};
>> +
>> +static void test_external_memory(VkInstance vk_instance, 
>> VkPhysicalDevice vk_physical_device)
>> +{
>> +    PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR 
>> pfn_vkGetPhysicalDeviceExternalBufferPropertiesKHR;
>> +    PFN_vkGetPhysicalDeviceProperties2 
>> pfn_vkGetPhysicalDeviceProperties2;
>> +    PFN_vkGetMemoryWin32HandleKHR pfn_vkGetMemoryWin32HandleKHR;
>> +    VkPhysicalDeviceExternalBufferInfoKHR external_buffer_info;
>> +    VkExternalBufferPropertiesKHR external_buffer_properties;
>> +    VkMemoryDedicatedAllocateInfoKHR dedicated_alloc_info;
>> +    VkPhysicalDeviceIDPropertiesKHR device_id_properties;
>> +    VkExportMemoryWin32HandleInfoKHR export_handle_info;
>> +    VkImportMemoryWin32HandleInfoKHR import_handle_info;
>> +    VkPhysicalDeviceProperties2KHR device_properties;
>> +    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");
>> +
>> +    pfn_vkGetPhysicalDeviceProperties2 =
>> +        (void*) vkGetInstanceProcAddr(vk_instance, 
>> "vkGetPhysicalDeviceProperties2KHR");
>> +
>> +    if (pfn_vkGetPhysicalDeviceProperties2)
>> +    {
>> +        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);
>> +    }
>> +
>> +    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;
> 
> We aren't actually using it, though (although we could...)
> 

The spec requires us to request some usage flags though. I'm not sure if 
you imply that we should test if using the buffer actually work. If 
that's the case I'm inclined to disagree since that's already guaranteed 
by running on a conformant host vulkan driver.

>> +    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)))
> 
> Don't we need a VkExternalMemoryBufferCreateInfo structure here? From 
> the Vulkan 1.2 specification § 12.1:
> 
> "A VkExternalMemoryBufferCreateInfo structure with a non-zero 
> handleTypes field must be included in the creation parameters for a 
> buffer that will be bound to memory that is either exported or imported."
> 

Yes indeed, so the buffer has to be created per handle type that we try 
and only if that type is supported.

>> +    {
>> +        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;
> 
> Nitpick, but could you please move this down closer to where you use it? 
> I'm misled into thinking it's used for the 
> vkGetPhysicalDeviceExternalBufferPropertiesKHR() call.
> 
>> +
>> +    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);
> 
> Any reason not to include the by-name tests here?
> 
> For that matter, you could add a helper function to test both in-process 
> and cross-process import.
> 
>> +
>> +        return;
>> +    }
>> +
>> +    if 
>> (!(external_buffer_properties.externalMemoryProperties.externalMemoryFeatures 
>> &
>> +            
>> (VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR))) 
>>
> 
> If we need it to be both exportable and importable, this won't do the 
> right thing. Same below.
> 
>> +        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);
>> +
>> +        if (pfn_vkGetPhysicalDeviceProperties2)
>> +            test_cross_process_resource(&device_id_properties, FALSE, 
>> handle);
>> +        else
>> +            skip("Skipping cross process shared resource test due to 
>> lack of VK_KHR_get_physical_device_properties2.\n");
>> +
>> +        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);
>> +
>> +        if (pfn_vkGetPhysicalDeviceProperties2)
>> +            test_cross_process_resource(&device_id_properties, TRUE, 
>> handle);
>> +        else
>> +            skip("Skipping cross process shared resource test due to 
>> lack of VK_KHR_get_physical_device_properties2.\n");
>> +
>> +        vkFreeMemory(vk_device, vk_memory, NULL);
>> +    }
>> +
>> +    vkDestroyBuffer(vk_device, vk_buffer, NULL);
>> +    vkDestroyDevice(vk_device, NULL);
>> +}
>> +
>> +/* VK_KHR_get_physical_device_properties2 must be an included 
>> extension */
>> +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))
> 
> Could we instead use for_each_device_instance(), and match the UUID in 
> the callback?
> 
> Also: I'm having some trouble finding this in the specification; could 
> you please point out where it says that the device and driver UUIDs have 
> to match?
> 

44.1 Additional Image Capabilities: Table 78. External memory handle 
types compatibility

>> +{
>> +    PFN_vkGetPhysicalDeviceProperties2 
>> pfn_vkGetPhysicalDeviceProperties2;
>> +    VkPhysicalDeviceIDPropertiesKHR device_id_properties;
>> +    VkPhysicalDeviceProperties2KHR device_properties;
>> +    VkPhysicalDevice *vk_physical_devices;
>> +    VkInstance vk_instance;
>> +    unsigned int i;
>> +    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 =
>> +        (void*) 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);
>> +
>> +        if (!memcmp(device_id_properties.driverUUID, driver_uuid, 
>> VK_UUID_SIZE) &&
>> +            !memcmp(device_id_properties.deviceUUID, device_uuid, 
>> VK_UUID_SIZE))
>> +        {
>> +            if (test_func_instance)
>> +                test_func_instance(vk_instance, vk_physical_devices[i]);
>> +            else
>> +                test_func(vk_physical_devices[i]);
> 
> This isn't new, but it strikes me as really awkward. Can't we just pass 
> a VkInstance to the callback and leave it unused?
> 
>> +
>> +            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 +963,37 @@ 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 +1004,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 c46ef02dcb9..5c4c4f0fe26 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.
>> @@ -127,7 +126,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.
>>
> 
> This doesn't look like it belongs in this patch.
> 

In my opinion it does belong here, without it the necessary types, 
functions and enum values won't be generated in include/wine/vulkan.h



More information about the wine-devel mailing list