winevulkan: Implement VK_KHR_device_group_creation.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2018-07-12 11:39:43 +02:00 committed by Alexandre Julliard
parent 0f11534656
commit b27b3aeaf6
8 changed files with 95 additions and 22 deletions

View file

@ -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

View file

@ -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},
}

View file

@ -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)
{

View file

@ -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;
};

View file

@ -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",

View file

@ -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) \

View file

@ -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)

View file

@ -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);