mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 16:31:45 +00:00
winevulkan: Implement vkEnumeratePhysicalDevices.
Signed-off-by: Roderick Colenbrander <thunderbird2k@gmail.com> Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9713e0e74d
commit
a553e88fba
|
@ -90,6 +90,7 @@ FUNCTION_OVERRIDES = {
|
|||
|
||||
# Instance functions
|
||||
"vkDestroyInstance" : {"dispatch" : True, "driver" : True, "thunk" : False },
|
||||
"vkEnumeratePhysicalDevices" : {"dispatch" : True, "driver" : False, "thunk" : False},
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,69 @@ static BOOL wine_vk_init(void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* 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 = NULL;
|
||||
uint32_t num_phys_devs = 0;
|
||||
unsigned int i;
|
||||
|
||||
res = instance->funcs.p_vkEnumeratePhysicalDevices(instance->instance, &num_phys_devs, NULL);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
ERR("Failed to enumerate physical devices, res=%d\n", res);
|
||||
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)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
res = instance->funcs.p_vkEnumeratePhysicalDevices(instance->instance, &num_phys_devs, tmp_phys_devs);
|
||||
if (res != VK_SUCCESS)
|
||||
goto err;
|
||||
|
||||
instance->phys_devs = heap_calloc(num_phys_devs, sizeof(*instance->phys_devs));
|
||||
if (!instance->phys_devs)
|
||||
{
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Wrap each native physical device handle into a dispatchable object for the ICD loader. */
|
||||
for (i = 0; i < num_phys_devs; i++)
|
||||
{
|
||||
struct VkPhysicalDevice_T *phys_dev = heap_alloc(sizeof(*phys_dev));
|
||||
if (!phys_dev)
|
||||
{
|
||||
ERR("Unable to allocate memory for physical device!\n");
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
phys_dev->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
|
||||
phys_dev->instance = instance;
|
||||
phys_dev->phys_dev = tmp_phys_devs[i];
|
||||
|
||||
instance->phys_devs[i] = phys_dev;
|
||||
instance->num_phys_devs = i + 1;
|
||||
}
|
||||
instance->num_phys_devs = num_phys_devs;
|
||||
|
||||
heap_free(tmp_phys_devs);
|
||||
return VK_SUCCESS;
|
||||
|
||||
err:
|
||||
heap_free(tmp_phys_devs);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Helper function used for freeing an instance structure. This function supports full
|
||||
* and partial object cleanups and can thus be used for vkCreateInstance failures.
|
||||
*/
|
||||
|
@ -66,6 +129,17 @@ static void wine_vk_instance_free(struct VkInstance_T *instance)
|
|||
if (!instance)
|
||||
return;
|
||||
|
||||
if (instance->phys_devs)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < instance->num_phys_devs; i++)
|
||||
{
|
||||
heap_free(&instance->phys_devs[i]);
|
||||
}
|
||||
heap_free(instance->phys_devs);
|
||||
}
|
||||
|
||||
if (instance->instance)
|
||||
vk_funcs->p_vkDestroyInstance(instance->instance, NULL /* allocator */);
|
||||
|
||||
|
@ -83,7 +157,7 @@ static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_
|
|||
if (allocator)
|
||||
FIXME("Support for allocation callbacks not implemented yet\n");
|
||||
|
||||
object = heap_alloc(sizeof(*object));
|
||||
object = heap_alloc_zero(sizeof(*object));
|
||||
if (!object)
|
||||
{
|
||||
ERR("Failed to allocate memory for instance\n");
|
||||
|
@ -108,6 +182,18 @@ static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_
|
|||
ALL_VK_INSTANCE_FUNCS()
|
||||
#undef USE_VK_FUNC
|
||||
|
||||
/* Cache physical devices for vkEnumeratePhysicalDevices within the instance as
|
||||
* each vkPhysicalDevice is a dispatchable object, which means we need to wrap
|
||||
* the native physical device and present those the application.
|
||||
* Cleanup happens as part of wine_vkDestroyInstance.
|
||||
*/
|
||||
res = wine_vk_instance_load_physical_devices(object);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
ERR("Failed to cache physical devices, res=%d\n", res);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*instance = object;
|
||||
TRACE("Done, instance=%p native_instance=%p\n", object, object->instance);
|
||||
return VK_SUCCESS;
|
||||
|
@ -134,6 +220,44 @@ static VkResult WINAPI wine_vkEnumerateInstanceExtensionProperties(const char *l
|
|||
return vk_funcs->p_vkEnumerateInstanceExtensionProperties(layer_name, count, properties);
|
||||
}
|
||||
|
||||
VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *device_count,
|
||||
VkPhysicalDevice *devices)
|
||||
{
|
||||
VkResult res;
|
||||
unsigned int i, num_copies;
|
||||
|
||||
TRACE("%p %p %p\n", instance, device_count, devices);
|
||||
|
||||
if (!devices)
|
||||
{
|
||||
*device_count = instance->num_phys_devs;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
if (*device_count < instance->num_phys_devs)
|
||||
{
|
||||
/* Incomplete is a type of success used to signal the application
|
||||
* that not all devices got copied.
|
||||
*/
|
||||
num_copies = *device_count;
|
||||
res = VK_INCOMPLETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_copies = instance->num_phys_devs;
|
||||
res = VK_SUCCESS;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_copies; i++)
|
||||
{
|
||||
devices[i] = instance->phys_devs[i];
|
||||
}
|
||||
*device_count = num_copies;
|
||||
|
||||
TRACE("Returning %u devices\n", *device_count);
|
||||
return res;
|
||||
}
|
||||
|
||||
static PFN_vkVoidFunction WINAPI wine_vkGetInstanceProcAddr(VkInstance instance, const char *name)
|
||||
{
|
||||
void *func;
|
||||
|
|
|
@ -52,7 +52,21 @@ struct VkInstance_T
|
|||
{
|
||||
struct wine_vk_base base;
|
||||
struct vulkan_instance_funcs funcs;
|
||||
|
||||
/* We cache devices as we need to wrap them as they are
|
||||
* dispatchable objects.
|
||||
*/
|
||||
uint32_t num_phys_devs;
|
||||
struct VkPhysicalDevice_T **phys_devs;
|
||||
|
||||
VkInstance instance; /* native instance */
|
||||
};
|
||||
|
||||
struct VkPhysicalDevice_T
|
||||
{
|
||||
struct wine_vk_base base;
|
||||
struct VkInstance_T *instance; /* parent */
|
||||
VkPhysicalDevice phys_dev; /* native physical device */
|
||||
};
|
||||
|
||||
#endif /* __WINE_VULKAN_PRIVATE_H */
|
||||
|
|
|
@ -28,12 +28,6 @@ static VkResult WINAPI wine_vkEnumerateDeviceLayerProperties(VkPhysicalDevice ph
|
|||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
static VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices)
|
||||
{
|
||||
FIXME("stub: %p, %p, %p\n", instance, pPhysicalDeviceCount, pPhysicalDevices);
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
static void WINAPI wine_vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures)
|
||||
{
|
||||
FIXME("stub: %p, %p\n", physicalDevice, pFeatures);
|
||||
|
|
|
@ -8,6 +8,7 @@ void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
|
|||
|
||||
/* Functions for which we have custom implementations outside of the thunks. */
|
||||
void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN;
|
||||
VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) DECLSPEC_HIDDEN;
|
||||
|
||||
/* For use by vkInstance and children */
|
||||
struct vulkan_instance_funcs
|
||||
|
|
Loading…
Reference in a new issue