Roderick Colenbrander : winevulkan: Implement vkGetDeviceQueue.
Alexandre Julliard
julliard at winehq.org
Wed Mar 14 17:37:18 CDT 2018
Module: wine
Branch: master
Commit: 9721ec92b9b7a764ce140e26560d7254ed3065b3
URL: https://source.winehq.org/git/wine.git/?a=commit;h=9721ec92b9b7a764ce140e26560d7254ed3065b3
Author: Roderick Colenbrander <thunderbird2k at gmail.com>
Date: Wed Mar 14 13:11:52 2018 +0100
winevulkan: Implement vkGetDeviceQueue.
Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winevulkan/make_vulkan | 4 +-
dlls/winevulkan/vulkan.c | 84 +++++++++++++++++++++++++++++++++++++++-
dlls/winevulkan/vulkan_private.h | 11 ++++++
dlls/winevulkan/vulkan_thunks.c | 5 ---
dlls/winevulkan/vulkan_thunks.h | 1 +
5 files changed, 95 insertions(+), 10 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index b53203b..abcd425 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -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
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 7b0fb37..e6873e8 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -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;
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index d49366f..203ad12 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -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 */
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index dfda842..ba8b689 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -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));
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index 13c1228..7be86bf 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -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;
More information about the wine-cvs
mailing list