From 89ccc8ba2b4395cb9977c576e5d2d1bd9d5f383e Mon Sep 17 00:00:00 2001 From: Aaron Ruby Date: Wed, 23 Jul 2025 14:11:42 -0400 Subject: [PATCH] gfxstream: Pre-fetch the VkQueue objects from the host .. and refactor vk_queue initialization entirely to store the queue information at device-creation time. Reviewed-by: Gurchetan Singh Part-of: --- .../codegen/scripts/cereal/functable.py | 2 +- .../guest/vulkan/gfxstream_vk_device.cpp | 123 +++++++++++------- .../guest/vulkan_enc/gfxstream_vk_private.h | 7 +- 3 files changed, 77 insertions(+), 55 deletions(-) diff --git a/src/gfxstream/codegen/scripts/cereal/functable.py b/src/gfxstream/codegen/scripts/cereal/functable.py index 51f5ce1cd80..001e54fda77 100644 --- a/src/gfxstream/codegen/scripts/cereal/functable.py +++ b/src/gfxstream/codegen/scripts/cereal/functable.py @@ -127,7 +127,6 @@ NON_AUTOGEN_ENTRYPOINTS = [ "vkCreateDevice", "vkDestroyDevice", # Manual alloc/free + vk_*_init/free() call w/ special params - "vkGetDeviceQueue2", # Command pool/buffer handling "vkCreateCommandPool", "vkDestroyCommandPool", @@ -144,6 +143,7 @@ NON_AUTOGEN_ENTRYPOINTS = [ # Use vk_common_* entrypoints; usually just dispatches to the "vk*2()" API variant "vkGetDeviceQueue", + "vkGetDeviceQueue2", "vkGetPhysicalDeviceProperties", ] diff --git a/src/gfxstream/guest/vulkan/gfxstream_vk_device.cpp b/src/gfxstream/guest/vulkan/gfxstream_vk_device.cpp index e63bc50c437..cbb9425e779 100644 --- a/src/gfxstream/guest/vulkan/gfxstream_vk_device.cpp +++ b/src/gfxstream/guest/vulkan/gfxstream_vk_device.cpp @@ -453,6 +453,72 @@ VkResult gfxstream_vk_EnumerateDeviceExtensionProperties(VkPhysicalDevice physic return vk_outarray_status(&out); } +static VkResult gfxstream_vk_queue_init(struct gfxstream_vk_device* dev, + struct gfxstream_vk_queue* queue, + const VkDeviceQueueCreateInfo* queue_info, + uint32_t queue_index) { + VkResult result = vk_queue_init(&queue->vk, &dev->vk, queue_info, queue_index); + if (result != VK_SUCCESS) return result; + + const VkDeviceQueueInfo2 device_queue_info = { + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2, + .pNext = NULL, + .flags = queue_info->flags, + .queueFamilyIndex = queue_info->queueFamilyIndex, + .queueIndex = queue_index, + }; + + // Make encoder call to host to get VkQueue internal_object + auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder(); + vkEnc->vkGetDeviceQueue2(dev->internal_object, &device_queue_info, &queue->internal_object, + true /* do lock */); + + queue->device = dev; + + return VK_SUCCESS; +} + +static void gfxstream_vk_queue_fini(struct gfxstream_vk_queue* queue) { + vk_queue_finish(&queue->vk); +} + +static VkResult gfxstream_vk_device_init_queues(struct gfxstream_vk_device* dev, + const VkDeviceCreateInfo* create_info) { + const VkAllocationCallbacks* alloc = &dev->vk.alloc; + + uint32_t count = 0; + for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) + count += create_info->pQueueCreateInfos[i].queueCount; + + struct gfxstream_vk_queue* queues = (struct gfxstream_vk_queue*)vk_zalloc( + alloc, sizeof(*queues) * count, GFXSTREAM_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + if (!queues) return VK_ERROR_OUT_OF_HOST_MEMORY; + + count = 0; + for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) { + VkResult result; + + const VkDeviceQueueCreateInfo* queue_info = &create_info->pQueueCreateInfos[i]; + for (uint32_t j = 0; j < queue_info->queueCount; j++) { + result = gfxstream_vk_queue_init(dev, &queues[count], queue_info, j); + if (result != VK_SUCCESS) { + for (uint32_t k = 0; k < count; k++) gfxstream_vk_queue_fini(&queues[k]); + vk_free(alloc, queues); + + return result; + } + + // Move to next queue allocation + count++; + } + } + + dev->queues = queues; + dev->queue_count = count; + + return VK_SUCCESS; +} + VkResult gfxstream_vk_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) { @@ -546,35 +612,8 @@ VkResult gfxstream_vk_CreateDevice(VkPhysicalDevice physicalDevice, vk_free(pMesaAllocator, gfxstream_device); } - // alloc/init all vk_queue objects if (result == VK_SUCCESS) { - gfxstream_device->queue_family_count = pCreateInfo->queueCreateInfoCount; - gfxstream_device->queue_families = (struct gfxstream_vk_device::queue_family_info*)vk_zalloc( - pMesaAllocator, gfxstream_device->queue_family_count * sizeof(*gfxstream_device->queue_families), GFXSTREAM_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - result = gfxstream_device->queue_families ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY; - if (result == VK_SUCCESS) { - for (uint32_t qfi = 0; qfi < gfxstream_device->queue_family_count; qfi++) { - gfxstream_device->queue_families[qfi].queue_count = pCreateInfo->pQueueCreateInfos[qfi].queueCount; - gfxstream_device->queue_families[qfi].queues = (struct gfxstream_vk_queue*)vk_zalloc( - pMesaAllocator, gfxstream_device->queue_families[qfi].queue_count * sizeof(struct gfxstream_vk_queue), GFXSTREAM_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - result =gfxstream_device->queue_families[qfi].queues ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY; - if (result != VK_SUCCESS) { - break; - } - } - if (result == VK_SUCCESS) { - for (uint32_t qfi = 0; qfi < gfxstream_device->queue_family_count; qfi++) { - for (uint32_t queue_index = 0; queue_index < gfxstream_device->queue_families[qfi].queue_count; queue_index++) { - struct gfxstream_vk_queue *gfxstream_queue = &gfxstream_device->queue_families[qfi].queues[queue_index]; - result = vk_queue_init(&gfxstream_queue->vk, &gfxstream_device->vk, &pCreateInfo->pQueueCreateInfos[qfi], queue_index); - if (result != VK_SUCCESS) { - break; - } - gfxstream_queue->device = gfxstream_device; - } - } - } - } + result = gfxstream_vk_device_init_queues(gfxstream_device, pCreateInfo); } return result; @@ -585,32 +624,18 @@ void gfxstream_vk_DestroyDevice(VkDevice device, const VkAllocationCallbacks* pA VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device); if (device == VK_NULL_HANDLE) return; + const VkAllocationCallbacks* alloc = pAllocator ? pAllocator : &gfxstream_device->vk.alloc; + + for (uint32_t i = 0; i < gfxstream_device->queue_count; i++) + gfxstream_vk_queue_fini(&gfxstream_device->queues[i]); + auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder(); vkEnc->vkDestroyDevice(gfxstream_device->internal_object, pAllocator, true /* do lock */); - /* Must destroy device queues manually */ - vk_foreach_queue_safe(queue, &gfxstream_device->vk) { - vk_queue_finish(queue); - vk_free(&gfxstream_device->vk.alloc, queue); - } - vk_free(&gfxstream_device->vk.alloc, gfxstream_device->queue_families); + vk_free(alloc, gfxstream_device->queues); vk_device_finish(&gfxstream_device->vk); - vk_free(&gfxstream_device->vk.alloc, gfxstream_device); -} - -void gfxstream_vk_GetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, - VkQueue* pQueue) { - MESA_TRACE_SCOPE("vkGetDeviceQueue2"); - VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device); - assert(pQueueInfo->queueFamilyIndex < gfxstream_device->queue_family_count); - assert(pQueueInfo->queueIndex < gfxstream_device->queue_families[pQueueInfo->queueFamilyIndex].queue_count); - /* Queue objects must have been allocated during CreateDevice() */ - struct gfxstream_vk_queue *gfxstream_queue = &gfxstream_device->queue_families[pQueueInfo->queueFamilyIndex].queues[pQueueInfo->queueIndex]; - auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder(); - vkEnc->vkGetDeviceQueue2(gfxstream_device->internal_object, pQueueInfo, - &gfxstream_queue->internal_object, true /* do lock */); - *pQueue = gfxstream_vk_queue_to_handle(gfxstream_queue); + vk_free(alloc, gfxstream_device); } /* The loader wants us to expose a second GetInstanceProcAddr function diff --git a/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h b/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h index e75934dd95e..8b736db840b 100644 --- a/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h +++ b/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h @@ -82,11 +82,8 @@ struct gfxstream_vk_device { struct vk_device_dispatch_table cmd_dispatch; struct gfxstream_vk_physical_device* physical_device; - uint32_t queue_family_count; - struct queue_family_info { - uint32_t queue_count; - struct gfxstream_vk_queue* queues; - } *queue_families; + struct gfxstream_vk_queue* queues; + uint32_t queue_count; VkDevice internal_object; };