Commit 9721ec92 authored by Roderick Colenbrander's avatar Roderick Colenbrander Committed by Alexandre Julliard

winevulkan: Implement vkGetDeviceQueue.

parent 7b07952c
......@@ -113,6 +113,7 @@ FUNCTION_OVERRIDES = {
# Device functions
"vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : False},
"vkGetDeviceProcAddr" : {"dispatch" : True, "driver" : True, "thunk" : False},
"vkGetDeviceQueue" : {"dispatch": True, "driver" : False, "thunk" : False},
# VK_KHR_surface
"vkDestroySurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
......@@ -396,9 +397,6 @@ class VkFunction(object):
if self.name == "vkCreateSwapchainKHR":
return False
if self.params[0].type != "VkPhysicalDevice":
return True
if self.is_device_func():
return True
......
......@@ -52,6 +52,36 @@ static void wine_vk_physical_device_free(struct VkPhysicalDevice_T *phys_dev);
static const struct vulkan_funcs *vk_funcs = NULL;
/* Helper function to create queues for a given family index. */
static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
uint32_t family_index, uint32_t queue_count)
{
struct VkQueue_T *queues;
unsigned int i;
if (!(queues = heap_calloc(queue_count, sizeof(*queues))))
{
ERR("Failed to allocate memory for queues\n");
return NULL;
}
for (i = 0; i < queue_count; i++)
{
struct VkQueue_T *queue = &queues[i];
queue->device = device;
/* The native device was already allocated with the required number of queues,
* so just fetch them from there.
*/
device->funcs.p_vkGetDeviceQueue(device->device, family_index, i, &queue->queue);
/* Set special header for ICD loader. */
((struct wine_vk_base *)queue)->loader_magic = VULKAN_ICD_MAGIC_VALUE;
}
return queues;
}
/* Helper function used for freeing a device structure. This function supports full
* and partial object cleanups and can thus be used for vkCreateDevice failures.
*/
......@@ -60,6 +90,17 @@ static void wine_vk_device_free(struct VkDevice_T *device)
if (!device)
return;
if (device->queues)
{
unsigned int i;
for (i = 0; i < device->max_queue_families; i++)
{
heap_free(device->queues[i]);
}
heap_free(device->queues);
device->queues = NULL;
}
if (device->device && device->funcs.p_vkDestroyDevice)
{
device->funcs.p_vkDestroyDevice(device->device, NULL /* pAllocator */);
......@@ -328,14 +369,14 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
const VkAllocationCallbacks *allocator, VkDevice *device)
{
struct VkDevice_T *object = NULL;
uint32_t max_queue_families;
VkResult res;
unsigned int i;
TRACE("%p %p %p %p\n", phys_dev, create_info, allocator, device);
if (allocator)
{
FIXME("Support for allocation callbacks not implemented yet\n");
}
object = heap_alloc_zero(sizeof(*object));
if (!object)
......@@ -367,6 +408,37 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
ALL_VK_DEVICE_FUNCS()
#undef USE_VK_FUNC
/* We need to cache all queues within the device as each requires wrapping since queues are
* dispatchable objects.
*/
phys_dev->instance->funcs.p_vkGetPhysicalDeviceQueueFamilyProperties(phys_dev->phys_dev,
&max_queue_families, NULL);
object->max_queue_families = max_queue_families;
TRACE("Max queue families: %d\n", object->max_queue_families);
object->queues = heap_calloc(max_queue_families, sizeof(*object->queues));
if (!object->queues)
{
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto err;
}
for (i = 0; i < create_info->queueCreateInfoCount; i++)
{
uint32_t family_index = create_info->pQueueCreateInfos[i].queueFamilyIndex;
uint32_t queue_count = create_info->pQueueCreateInfos[i].queueCount;
TRACE("queueFamilyIndex %u, queueCount %u\n", family_index, queue_count);
object->queues[family_index] = wine_vk_device_alloc_queues(object, family_index, queue_count);
if (!object->queues[family_index])
{
res = VK_ERROR_OUT_OF_HOST_MEMORY;
ERR("Failed to allocate memory for queues\n");
goto err;
}
}
*device = object;
return VK_SUCCESS;
......@@ -660,6 +732,14 @@ PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *
return NULL;
}
void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t family_index,
uint32_t queue_index, VkQueue *queue)
{
TRACE("%p %u %u %p\n", device, family_index, queue_index, queue);
*queue = &device->queues[family_index][queue_index];
}
static PFN_vkVoidFunction WINAPI wine_vkGetInstanceProcAddr(VkInstance instance, const char *name)
{
void *func;
......
......@@ -53,6 +53,10 @@ struct VkDevice_T
struct wine_vk_base base;
struct vulkan_device_funcs funcs;
struct VkPhysicalDevice_T *phys_dev; /* parent */
uint32_t max_queue_families;
struct VkQueue_T **queues;
VkDevice device; /* native device */
};
......@@ -81,4 +85,11 @@ struct VkPhysicalDevice_T
VkPhysicalDevice phys_dev; /* native physical device */
};
struct VkQueue_T
{
struct wine_vk_base base;
VkDevice device; /* parent */
VkQueue queue; /* native queue */
};
#endif /* __WINE_VULKAN_PRIVATE_H */
......@@ -685,11 +685,6 @@ static void WINAPI wine_vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMem
FIXME("stub: %p, 0x%s, %p\n", device, wine_dbgstr_longlong(memory), pCommittedMemoryInBytes);
}
static void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue)
{
FIXME("stub: %p, %u, %u, %p\n", device, queueFamilyIndex, queueIndex, pQueue);
}
static VkResult WINAPI wine_vkGetEventStatus(VkDevice device, VkEvent event)
{
FIXME("stub: %p, 0x%s\n", device, wine_dbgstr_longlong(event));
......
......@@ -26,6 +26,7 @@ void WINAPI wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain
VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) DECLSPEC_HIDDEN;
VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) DECLSPEC_HIDDEN;
PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *pName) DECLSPEC_HIDDEN;
void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) DECLSPEC_HIDDEN;
VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) DECLSPEC_HIDDEN;
VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) DECLSPEC_HIDDEN;
VkResult WINAPI wine_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment