diff --git a/dlls/vulkan-1/vulkan-1.spec b/dlls/vulkan-1/vulkan-1.spec index 79031395a09..8c32b011f25 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 d0a83c32e0c..2672ad77e46 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 96b591ac944..987332e6222 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 353f7af36c0..37af9206402 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 31ea551d531..2a630034101 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 dd85e427008..c9fe0789800 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 dc43ef816b6..c196eb1324a 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 c6e4c59bcb7..6eec0b8a762 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);