From c8d9142b1f75cad1111d5c704584694d0c4ce099 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Wed, 1 Apr 2026 12:44:19 -0700 Subject: [PATCH] venus: add vn_get_query_pool_results for non-qfb This is the legacy path. Refactor to a helper to prepare for more robust device lost detection. Part-of: --- src/virtio/vulkan/vn_query_pool.c | 158 +++++++++++++++++------------- 1 file changed, 88 insertions(+), 70 deletions(-) diff --git a/src/virtio/vulkan/vn_query_pool.c b/src/virtio/vulkan/vn_query_pool.c index 66101ebad74..330a92127bd 100644 --- a/src/virtio/vulkan/vn_query_pool.c +++ b/src/virtio/vulkan/vn_query_pool.c @@ -198,6 +198,92 @@ vn_ResetQueryPool(VkDevice device, } } +static VkResult +vn_get_query_pool_results(VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + void *pData, + VkDeviceSize stride, + VkQueryResultFlags flags) +{ + struct vn_device *dev = vn_device_from_handle(device); + struct vn_query_pool *pool = vn_query_pool_from_handle(queryPool); + const VkAllocationCallbacks *alloc = &pool->allocator; + VkResult result; + + const size_t result_width = flags & VK_QUERY_RESULT_64_BIT ? 8 : 4; + const size_t result_size = pool->result_array_size * result_width; + const bool result_always_written = + flags & (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_PARTIAL_BIT); + + VkQueryResultFlags packed_flags = flags; + size_t packed_stride = result_size; + if (!result_always_written) + packed_flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT; + if (packed_flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) + packed_stride += result_width; + + const size_t packed_size = packed_stride * queryCount; + void *packed_data; + if (result_always_written && packed_stride == stride) { + packed_data = pData; + } else { + packed_data = vk_alloc(alloc, packed_size, VN_DEFAULT_ALIGN, + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if (!packed_data) + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + result = vn_call_vkGetQueryPoolResults( + dev->primary_ring, device, queryPool, firstQuery, queryCount, + packed_size, packed_data, packed_stride, packed_flags); + + if (packed_data == pData) + return result; + + const size_t copy_size = + result_size + + (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT ? result_width : 0); + const void *src = packed_data; + void *dst = pData; + if (result == VK_SUCCESS) { + for (uint32_t i = 0; i < queryCount; i++) { + memcpy(dst, src, copy_size); + src += packed_stride; + dst += stride; + } + } else if (result == VK_NOT_READY) { + assert(!result_always_written && + (packed_flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)); + if (flags & VK_QUERY_RESULT_64_BIT) { + for (uint32_t i = 0; i < queryCount; i++) { + const bool avail = *(const uint64_t *)(src + result_size); + if (avail) + memcpy(dst, src, copy_size); + else if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) + *(uint64_t *)(dst + result_size) = 0; + + src += packed_stride; + dst += stride; + } + } else { + for (uint32_t i = 0; i < queryCount; i++) { + const bool avail = *(const uint32_t *)(src + result_size); + if (avail) + memcpy(dst, src, copy_size); + else if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) + *(uint32_t *)(dst + result_size) = 0; + + src += packed_stride; + dst += stride; + } + } + } + + vk_free(alloc, packed_data); + return result; +} + static VkResult vn_get_query_pool_feedback(struct vn_query_pool *pool, uint32_t firstQuery, @@ -311,14 +397,8 @@ vn_GetQueryPoolResults(VkDevice device, { struct vn_device *dev = vn_device_from_handle(device); struct vn_query_pool *pool = vn_query_pool_from_handle(queryPool); - const VkAllocationCallbacks *alloc = &pool->allocator; VkResult result; - const size_t result_width = flags & VK_QUERY_RESULT_64_BIT ? 8 : 4; - const size_t result_size = pool->result_array_size * result_width; - const bool result_always_written = - flags & (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_PARTIAL_BIT); - /* Get results from feedback buffers * Not possible for VK_QUERY_RESULT_PARTIAL_BIT */ @@ -329,73 +409,11 @@ vn_GetQueryPoolResults(VkDevice device, result = vn_get_query_pool_feedback(pool, firstQuery, queryCount, pData, stride, flags); - return vn_result(dev->instance, result); - } - - VkQueryResultFlags packed_flags = flags; - size_t packed_stride = result_size; - if (!result_always_written) - packed_flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT; - if (packed_flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) - packed_stride += result_width; - - const size_t packed_size = packed_stride * queryCount; - void *packed_data; - if (result_always_written && packed_stride == stride) { - packed_data = pData; } else { - packed_data = vk_alloc(alloc, packed_size, VN_DEFAULT_ALIGN, - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); - if (!packed_data) - return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); - } - result = vn_call_vkGetQueryPoolResults( - dev->primary_ring, device, queryPool, firstQuery, queryCount, - packed_size, packed_data, packed_stride, packed_flags); - - if (packed_data == pData) - return vn_result(dev->instance, result); - - const size_t copy_size = - result_size + - (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT ? result_width : 0); - const void *src = packed_data; - void *dst = pData; - if (result == VK_SUCCESS) { - for (uint32_t i = 0; i < queryCount; i++) { - memcpy(dst, src, copy_size); - src += packed_stride; - dst += stride; - } - } else if (result == VK_NOT_READY) { - assert(!result_always_written && - (packed_flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)); - if (flags & VK_QUERY_RESULT_64_BIT) { - for (uint32_t i = 0; i < queryCount; i++) { - const bool avail = *(const uint64_t *)(src + result_size); - if (avail) - memcpy(dst, src, copy_size); - else if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) - *(uint64_t *)(dst + result_size) = 0; - - src += packed_stride; - dst += stride; - } - } else { - for (uint32_t i = 0; i < queryCount; i++) { - const bool avail = *(const uint32_t *)(src + result_size); - if (avail) - memcpy(dst, src, copy_size); - else if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) - *(uint32_t *)(dst + result_size) = 0; - - src += packed_stride; - dst += stride; - } - } + result = vn_get_query_pool_results(device, queryPool, firstQuery, + queryCount, pData, stride, flags); } - vk_free(alloc, packed_data); return vn_result(dev->instance, result); }