[PATCH 5/8] winevulkan: Implement VK_KHR_device_group_creation.

Józef Kucia jkucia at codeweavers.com
Thu Jul 12 04:39:43 CDT 2018


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/vulkan-1/vulkan-1.spec      |  2 +-
 dlls/winevulkan/make_vulkan      |  5 +++
 dlls/winevulkan/vulkan.c         | 91 +++++++++++++++++++++++++++++++---------
 dlls/winevulkan/vulkan_private.h |  2 +-
 dlls/winevulkan/vulkan_thunks.c  |  3 ++
 dlls/winevulkan/vulkan_thunks.h  |  6 +++
 dlls/winevulkan/winevulkan.spec  |  2 +-
 include/wine/vulkan.h            |  6 +++
 8 files changed, 95 insertions(+), 22 deletions(-)

diff --git a/dlls/vulkan-1/vulkan-1.spec b/dlls/vulkan-1/vulkan-1.spec
index 79031395a099..8c32b011f251 100644
--- a/dlls/vulkan-1/vulkan-1.spec
+++ b/dlls/vulkan-1/vulkan-1.spec
@@ -149,7 +149,7 @@
 @ stdcall vkEnumerateInstanceExtensionProperties(str ptr ptr)
 @ stdcall vkEnumerateInstanceLayerProperties(ptr ptr)
 @ stub vkEnumerateInstanceVersion
-@ stub vkEnumeratePhysicalDeviceGroups
+@ stdcall vkEnumeratePhysicalDeviceGroups(ptr ptr ptr) winevulkan.wine_vkEnumeratePhysicalDeviceGroups
 @ stdcall vkEnumeratePhysicalDevices(ptr ptr ptr) winevulkan.wine_vkEnumeratePhysicalDevices
 @ stdcall vkFlushMappedMemoryRanges(ptr long ptr) winevulkan.wine_vkFlushMappedMemoryRanges
 @ stdcall vkFreeCommandBuffers(ptr int64 long ptr) winevulkan.wine_vkFreeCommandBuffers
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index d0a83c32e0cb..2672ad77e46c 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -86,6 +86,7 @@ EXT_BLOCK_SIZE = 1000
 # and need custom wrappers due to e.g. win32 / X11 specific code.
 # List of supported instance extensions.
 SUPPORTED_INSTANCE_EXTENSIONS = [
+    "VK_KHR_device_group_creation",
     "VK_KHR_get_physical_device_properties2",
     "VK_KHR_surface",
     "VK_KHR_win32_surface",
@@ -150,6 +151,7 @@ FUNCTION_OVERRIDES = {
     "vkDestroyInstance" : {"dispatch" : False, "driver" : True, "thunk" : False },
     "vkEnumerateDeviceExtensionProperties" : {"dispatch" : True, "driver" : False, "thunk" : False},
     "vkEnumeratePhysicalDevices" : {"dispatch" : True, "driver" : False, "thunk" : False},
+    "vkEnumeratePhysicalDeviceGroups" : {"dispatch" : True, "driver" : False, "thunk" : False},
 
     # Device functions
     "vkAllocateCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False},
@@ -177,6 +179,9 @@ FUNCTION_OVERRIDES = {
     "vkDestroySwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
     "vkGetSwapchainImagesKHR": {"dispatch" : True, "driver" : True, "thunk" : True},
     "vkQueuePresentKHR": {"dispatch" : True, "driver" : True, "thunk" : True},
+
+    # VK_KHR_device_group_creation
+    "vkEnumeratePhysicalDeviceGroupsKHR" : {"dispatch" : True, "driver" : False, "thunk" : False},
 }
 
 
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 96b591ac944c..987332e62225 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -390,34 +390,31 @@ static void wine_vk_instance_convert_create_info(const VkInstanceCreateInfo *src
 /* Helper function which stores wrapped physical devices in the instance object. */
 static VkResult wine_vk_instance_load_physical_devices(struct VkInstance_T *instance)
 {
-    VkResult res;
-    struct VkPhysicalDevice_T **tmp_phys_devs;
-    uint32_t num_phys_devs = 0;
+    VkPhysicalDevice *tmp_phys_devs;
+    uint32_t phys_dev_count;
     unsigned int i;
+    VkResult res;
 
-    res = instance->funcs.p_vkEnumeratePhysicalDevices(instance->instance, &num_phys_devs, NULL);
+    res = instance->funcs.p_vkEnumeratePhysicalDevices(instance->instance, &phys_dev_count, NULL);
     if (res != VK_SUCCESS)
     {
         ERR("Failed to enumerate physical devices, res=%d\n", res);
         return res;
     }
+    if (!phys_dev_count)
+        return res;
 
-    /* Don't bother with any of the rest if the system just lacks devices. */
-    if (num_phys_devs == 0)
-        return VK_SUCCESS;
-
-    tmp_phys_devs = heap_calloc(num_phys_devs, sizeof(*tmp_phys_devs));
-    if (!tmp_phys_devs)
+    if (!(tmp_phys_devs = heap_calloc(phys_dev_count, sizeof(*tmp_phys_devs))))
         return VK_ERROR_OUT_OF_HOST_MEMORY;
 
-    res = instance->funcs.p_vkEnumeratePhysicalDevices(instance->instance, &num_phys_devs, tmp_phys_devs);
+    res = instance->funcs.p_vkEnumeratePhysicalDevices(instance->instance, &phys_dev_count, tmp_phys_devs);
     if (res != VK_SUCCESS)
     {
         heap_free(tmp_phys_devs);
         return res;
     }
 
-    instance->phys_devs = heap_calloc(num_phys_devs, sizeof(*instance->phys_devs));
+    instance->phys_devs = heap_calloc(phys_dev_count, sizeof(*instance->phys_devs));
     if (!instance->phys_devs)
     {
         heap_free(tmp_phys_devs);
@@ -425,7 +422,7 @@ static VkResult wine_vk_instance_load_physical_devices(struct VkInstance_T *inst
     }
 
     /* Wrap each native physical device handle into a dispatchable object for the ICD loader. */
-    for (i = 0; i < num_phys_devs; i++)
+    for (i = 0; i < phys_dev_count; i++)
     {
         struct VkPhysicalDevice_T *phys_dev = wine_vk_physical_device_alloc(instance, tmp_phys_devs[i]);
         if (!phys_dev)
@@ -436,14 +433,30 @@ static VkResult wine_vk_instance_load_physical_devices(struct VkInstance_T *inst
         }
 
         instance->phys_devs[i] = phys_dev;
-        instance->num_phys_devs = i + 1;
+        instance->phys_dev_count = i + 1;
     }
-    instance->num_phys_devs = num_phys_devs;
+    instance->phys_dev_count = phys_dev_count;
 
     heap_free(tmp_phys_devs);
     return VK_SUCCESS;
 }
 
+static struct VkPhysicalDevice_T *wine_vk_instance_wrap_physical_device(struct VkInstance_T *instance,
+        VkPhysicalDevice physical_device)
+{
+    unsigned int i;
+
+    for (i = 0; i < instance->phys_dev_count; ++i)
+    {
+        struct VkPhysicalDevice_T *current = instance->phys_devs[i];
+        if (current->phys_dev == physical_device)
+            return current;
+    }
+
+    ERR("Unrecognized physical device %p.\n", physical_device);
+    return NULL;
+}
+
 /* Helper function used for freeing an instance structure. This function supports full
  * and partial object cleanups and can thus be used for vkCreateInstance failures.
  */
@@ -456,7 +469,7 @@ static void wine_vk_instance_free(struct VkInstance_T *instance)
     {
         unsigned int i;
 
-        for (i = 0; i < instance->num_phys_devs; i++)
+        for (i = 0; i < instance->phys_dev_count; i++)
         {
             wine_vk_physical_device_free(instance->phys_devs[i]);
         }
@@ -826,18 +839,18 @@ VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *c
 
     if (!devices)
     {
-        *count = instance->num_phys_devs;
+        *count = instance->phys_dev_count;
         return VK_SUCCESS;
     }
 
-    *count = min(*count, instance->num_phys_devs);
+    *count = min(*count, instance->phys_dev_count);
     for (i = 0; i < *count; i++)
     {
         devices[i] = instance->phys_devs[i];
     }
 
     TRACE("Returning %u devices.\n", *count);
-    return *count < instance->num_phys_devs ? VK_INCOMPLETE : VK_SUCCESS;
+    return *count < instance->phys_dev_count ? VK_INCOMPLETE : VK_SUCCESS;
 }
 
 void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool, uint32_t count,
@@ -1016,6 +1029,46 @@ err:
     return res;
 }
 
+static VkResult wine_vk_enumerate_physical_device_groups(struct VkInstance_T *instance,
+        VkResult (*p_vkEnumeratePhysicalDeviceGroups)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *),
+        uint32_t *count, VkPhysicalDeviceGroupProperties *properties)
+{
+    unsigned int i, j;
+    VkResult res;
+
+    res = p_vkEnumeratePhysicalDeviceGroups(instance->instance, count, properties);
+    if (res < 0 || !properties)
+        return res;
+
+    for (i = 0; i < *count; ++i)
+    {
+        VkPhysicalDeviceGroupProperties *current = &properties[i];
+        for (j = 0; j < current->physicalDeviceCount; ++j)
+        {
+            VkPhysicalDevice dev = current->physicalDevices[j];
+            if (!(current->physicalDevices[j] = wine_vk_instance_wrap_physical_device(instance, dev)))
+                return VK_ERROR_INITIALIZATION_FAILED;
+        }
+    }
+
+    return res;
+}
+
+VkResult WINAPI wine_vkEnumeratePhysicalDeviceGroups(VkInstance instance,
+        uint32_t *count, VkPhysicalDeviceGroupProperties *properties)
+{
+    TRACE("%p, %p, %p\n", instance, count, properties);
+    return wine_vk_enumerate_physical_device_groups(instance,
+            instance->funcs.p_vkEnumeratePhysicalDeviceGroups, count, properties);
+}
+
+VkResult WINAPI wine_vkEnumeratePhysicalDeviceGroupsKHR(VkInstance instance,
+        uint32_t *count, VkPhysicalDeviceGroupProperties *properties)
+{
+    TRACE("%p, %p, %p\n", instance, count, properties);
+    return wine_vk_enumerate_physical_device_groups(instance,
+            instance->funcs.p_vkEnumeratePhysicalDeviceGroupsKHR, count, properties);
+}
 
 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
 {
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index 353f7af36c0d..37af92064028 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -86,7 +86,7 @@ struct VkInstance_T
      * dispatchable objects.
      */
     struct VkPhysicalDevice_T **phys_devs;
-    uint32_t num_phys_devs;
+    uint32_t phys_dev_count;
 
     unsigned int quirks;
 };
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index 31ea551d5314..2a6300341015 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -2919,6 +2919,8 @@ static const struct vulkan_func vk_instance_dispatch_table[] =
     {"vkDestroySurfaceKHR", &wine_vkDestroySurfaceKHR},
     {"vkEnumerateDeviceExtensionProperties", &wine_vkEnumerateDeviceExtensionProperties},
     {"vkEnumerateDeviceLayerProperties", &wine_vkEnumerateDeviceLayerProperties},
+    {"vkEnumeratePhysicalDeviceGroups", &wine_vkEnumeratePhysicalDeviceGroups},
+    {"vkEnumeratePhysicalDeviceGroupsKHR", &wine_vkEnumeratePhysicalDeviceGroupsKHR},
     {"vkEnumeratePhysicalDevices", &wine_vkEnumeratePhysicalDevices},
     {"vkGetPhysicalDeviceFeatures", &wine_vkGetPhysicalDeviceFeatures},
     {"vkGetPhysicalDeviceFeatures2", &wine_vkGetPhysicalDeviceFeatures2},
@@ -3048,6 +3050,7 @@ static const char * const vk_device_extensions[] =
 
 static const char * const vk_instance_extensions[] =
 {
+    "VK_KHR_device_group_creation",
     "VK_KHR_get_physical_device_properties2",
     "VK_KHR_surface",
     "VK_KHR_win32_surface",
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index dd85e4270087..c9fe07898000 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -45,6 +45,8 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDev
 void WINAPI wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator);
 void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator);
 VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties);
+VkResult WINAPI wine_vkEnumeratePhysicalDeviceGroups(VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties);
+VkResult WINAPI wine_vkEnumeratePhysicalDeviceGroupsKHR(VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices);
 void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers);
 PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *pName);
@@ -942,6 +944,8 @@ struct vulkan_instance_funcs
     void (*p_vkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *);
     VkResult (*p_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice, const char *, uint32_t *, VkExtensionProperties *);
     VkResult (*p_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice, uint32_t *, VkLayerProperties *);
+    VkResult (*p_vkEnumeratePhysicalDeviceGroups)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *);
+    VkResult (*p_vkEnumeratePhysicalDeviceGroupsKHR)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *);
     VkResult (*p_vkEnumeratePhysicalDevices)(VkInstance, uint32_t *, VkPhysicalDevice *);
     void (*p_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice, VkPhysicalDeviceFeatures *);
     void (*p_vkGetPhysicalDeviceFeatures2)(VkPhysicalDevice, VkPhysicalDeviceFeatures2 *);
@@ -1180,6 +1184,8 @@ struct vulkan_instance_funcs
     USE_VK_FUNC(vkDestroySurfaceKHR) \
     USE_VK_FUNC(vkEnumerateDeviceExtensionProperties) \
     USE_VK_FUNC(vkEnumerateDeviceLayerProperties) \
+    USE_VK_FUNC(vkEnumeratePhysicalDeviceGroups) \
+    USE_VK_FUNC(vkEnumeratePhysicalDeviceGroupsKHR) \
     USE_VK_FUNC(vkEnumeratePhysicalDevices) \
     USE_VK_FUNC(vkGetPhysicalDeviceFeatures) \
     USE_VK_FUNC(vkGetPhysicalDeviceFeatures2) \
diff --git a/dlls/winevulkan/winevulkan.spec b/dlls/winevulkan/winevulkan.spec
index dc43ef816b60..c196eb1324a4 100644
--- a/dlls/winevulkan/winevulkan.spec
+++ b/dlls/winevulkan/winevulkan.spec
@@ -150,7 +150,7 @@
 @ stdcall wine_vkEnumerateDeviceLayerProperties(ptr ptr ptr)
 @ stdcall wine_vkEnumerateInstanceExtensionProperties(str ptr ptr)
 @ stub vkEnumerateInstanceVersion
-@ stub vkEnumeratePhysicalDeviceGroups
+@ stdcall wine_vkEnumeratePhysicalDeviceGroups(ptr ptr ptr)
 @ stdcall wine_vkEnumeratePhysicalDevices(ptr ptr ptr)
 @ stdcall wine_vkFlushMappedMemoryRanges(ptr long ptr)
 @ stdcall wine_vkFreeCommandBuffers(ptr int64 long ptr)
diff --git a/include/wine/vulkan.h b/include/wine/vulkan.h
index c6e4c59bcb7f..6eec0b8a7625 100644
--- a/include/wine/vulkan.h
+++ b/include/wine/vulkan.h
@@ -137,6 +137,8 @@
 #define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote"
 #define VK_KHR_MAINTENANCE1_SPEC_VERSION 2
 #define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1"
+#define VK_KHR_DEVICE_GROUP_CREATION_SPEC_VERSION 1
+#define VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME "VK_KHR_device_group_creation"
 #define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 2
 #define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor"
 #define VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR 1
@@ -4290,6 +4292,8 @@ typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysica
 typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice, uint32_t *, VkLayerProperties *);
 typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *);
 typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t *, VkLayerProperties *);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroupsKHR)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *);
 typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance, uint32_t *, VkPhysicalDevice *);
 typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice, uint32_t, const VkMappedMemoryRange *);
 typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice, VkCommandPool, uint32_t, const VkCommandBuffer *);
@@ -4495,6 +4499,8 @@ VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physic
 VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties);
 VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties);
 VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pPropertyCount, VkLayerProperties *pProperties);
+VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties);
+VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroupsKHR(VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties);
 VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices);
 VkResult VKAPI_CALL vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges);
 void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers);
-- 
2.16.4




More information about the wine-devel mailing list