From 02e6164b080ec7247f36c15ba6e3b982b7a7d458 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 7 Apr 2021 16:37:33 -0700 Subject: [PATCH] venus: split out vn_query_pool.[ch] Move VkQueryPool functions to the new files. Signed-off-by: Chia-I Wu Reviewed-by: Yiwei Zhang Acked-by: Erik Faye-Lund Reviewed-by: Ryan Neph Part-of: --- src/virtio/vulkan/meson.build | 1 + src/virtio/vulkan/vn_device.c | 173 --------------------------- src/virtio/vulkan/vn_device.h | 11 -- src/virtio/vulkan/vn_query_pool.c | 188 ++++++++++++++++++++++++++++++ src/virtio/vulkan/vn_query_pool.h | 27 +++++ 5 files changed, 216 insertions(+), 184 deletions(-) create mode 100644 src/virtio/vulkan/vn_query_pool.c create mode 100644 src/virtio/vulkan/vn_query_pool.h diff --git a/src/virtio/vulkan/meson.build b/src/virtio/vulkan/meson.build index 014358c8934..f26a3c7d4e7 100644 --- a/src/virtio/vulkan/meson.build +++ b/src/virtio/vulkan/meson.build @@ -37,6 +37,7 @@ libvn_files = files( 'vn_device.c', 'vn_icd.c', 'vn_pipeline.c', + 'vn_query_pool.c', 'vn_ring.c', 'vn_renderer_virtgpu.c', 'vn_renderer_vtest.c', diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c index b353e175dba..6dc07d63523 100644 --- a/src/virtio/vulkan/vn_device.c +++ b/src/virtio/vulkan/vn_device.c @@ -6367,176 +6367,3 @@ vn_ResetEvent(VkDevice device, VkEvent event) return vn_result(dev->instance, result); } - -/* query pool commands */ - -VkResult -vn_CreateQueryPool(VkDevice device, - const VkQueryPoolCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkQueryPool *pQueryPool) -{ - struct vn_device *dev = vn_device_from_handle(device); - const VkAllocationCallbacks *alloc = - pAllocator ? pAllocator : &dev->base.base.alloc; - - struct vn_query_pool *pool = - vk_zalloc(alloc, sizeof(*pool), VN_DEFAULT_ALIGN, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (!pool) - return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); - - vn_object_base_init(&pool->base, VK_OBJECT_TYPE_QUERY_POOL, &dev->base); - - pool->allocator = *alloc; - - switch (pCreateInfo->queryType) { - case VK_QUERY_TYPE_OCCLUSION: - pool->result_array_size = 1; - break; - case VK_QUERY_TYPE_PIPELINE_STATISTICS: - pool->result_array_size = - util_bitcount(pCreateInfo->pipelineStatistics); - break; - case VK_QUERY_TYPE_TIMESTAMP: - pool->result_array_size = 1; - break; - case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: - pool->result_array_size = 2; - break; - default: - unreachable("bad query type"); - break; - } - - VkQueryPool pool_handle = vn_query_pool_to_handle(pool); - vn_async_vkCreateQueryPool(dev->instance, device, pCreateInfo, NULL, - &pool_handle); - - *pQueryPool = pool_handle; - - return VK_SUCCESS; -} - -void -vn_DestroyQueryPool(VkDevice device, - VkQueryPool queryPool, - const VkAllocationCallbacks *pAllocator) -{ - struct vn_device *dev = vn_device_from_handle(device); - struct vn_query_pool *pool = vn_query_pool_from_handle(queryPool); - const VkAllocationCallbacks *alloc; - - if (!pool) - return; - - alloc = pAllocator ? pAllocator : &pool->allocator; - - vn_async_vkDestroyQueryPool(dev->instance, device, queryPool, NULL); - - vn_object_base_fini(&pool->base); - vk_free(alloc, pool); -} - -void -vn_ResetQueryPool(VkDevice device, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount) -{ - struct vn_device *dev = vn_device_from_handle(device); - - vn_async_vkResetQueryPool(dev->instance, device, queryPool, firstQuery, - queryCount); -} - -VkResult -vn_GetQueryPoolResults(VkDevice device, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - size_t dataSize, - 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; - - 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 vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); - } - - /* TODO the renderer should transparently vkCmdCopyQueryPoolResults to a - * coherent memory such that we can memcpy from the coherent memory to - * avoid this serialized round trip. - */ - VkResult result = vn_call_vkGetQueryPoolResults( - dev->instance, 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; - } - } - } - - vk_free(alloc, packed_data); - return vn_result(dev->instance, result); -} diff --git a/src/virtio/vulkan/vn_device.h b/src/virtio/vulkan/vn_device.h index 33dcb089cd3..dcf887ef763 100644 --- a/src/virtio/vulkan/vn_device.h +++ b/src/virtio/vulkan/vn_device.h @@ -344,17 +344,6 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(vn_event, VkEvent, VK_OBJECT_TYPE_EVENT) -struct vn_query_pool { - struct vn_object_base base; - - VkAllocationCallbacks allocator; - uint32_t result_array_size; -}; -VK_DEFINE_NONDISP_HANDLE_CASTS(vn_query_pool, - base.base, - VkQueryPool, - VK_OBJECT_TYPE_QUERY_POOL) - VkResult vn_instance_submit_roundtrip(struct vn_instance *instance, uint32_t *roundtrip_seqno); diff --git a/src/virtio/vulkan/vn_query_pool.c b/src/virtio/vulkan/vn_query_pool.c new file mode 100644 index 00000000000..15268f700f5 --- /dev/null +++ b/src/virtio/vulkan/vn_query_pool.c @@ -0,0 +1,188 @@ +/* + * Copyright 2019 Google LLC + * SPDX-License-Identifier: MIT + * + * based in part on anv and radv which are: + * Copyright © 2015 Intel Corporation + * Copyright © 2016 Red Hat. + * Copyright © 2016 Bas Nieuwenhuizen + */ + +#include "vn_query_pool.h" + +#include "venus-protocol/vn_protocol_driver_query_pool.h" + +#include "vn_device.h" + +/* query pool commands */ + +VkResult +vn_CreateQueryPool(VkDevice device, + const VkQueryPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkQueryPool *pQueryPool) +{ + struct vn_device *dev = vn_device_from_handle(device); + const VkAllocationCallbacks *alloc = + pAllocator ? pAllocator : &dev->base.base.alloc; + + struct vn_query_pool *pool = + vk_zalloc(alloc, sizeof(*pool), VN_DEFAULT_ALIGN, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!pool) + return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + vn_object_base_init(&pool->base, VK_OBJECT_TYPE_QUERY_POOL, &dev->base); + + pool->allocator = *alloc; + + switch (pCreateInfo->queryType) { + case VK_QUERY_TYPE_OCCLUSION: + pool->result_array_size = 1; + break; + case VK_QUERY_TYPE_PIPELINE_STATISTICS: + pool->result_array_size = + util_bitcount(pCreateInfo->pipelineStatistics); + break; + case VK_QUERY_TYPE_TIMESTAMP: + pool->result_array_size = 1; + break; + case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: + pool->result_array_size = 2; + break; + default: + unreachable("bad query type"); + break; + } + + VkQueryPool pool_handle = vn_query_pool_to_handle(pool); + vn_async_vkCreateQueryPool(dev->instance, device, pCreateInfo, NULL, + &pool_handle); + + *pQueryPool = pool_handle; + + return VK_SUCCESS; +} + +void +vn_DestroyQueryPool(VkDevice device, + VkQueryPool queryPool, + const VkAllocationCallbacks *pAllocator) +{ + struct vn_device *dev = vn_device_from_handle(device); + struct vn_query_pool *pool = vn_query_pool_from_handle(queryPool); + const VkAllocationCallbacks *alloc; + + if (!pool) + return; + + alloc = pAllocator ? pAllocator : &pool->allocator; + + vn_async_vkDestroyQueryPool(dev->instance, device, queryPool, NULL); + + vn_object_base_fini(&pool->base); + vk_free(alloc, pool); +} + +void +vn_ResetQueryPool(VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount) +{ + struct vn_device *dev = vn_device_from_handle(device); + + vn_async_vkResetQueryPool(dev->instance, device, queryPool, firstQuery, + queryCount); +} + +VkResult +vn_GetQueryPoolResults(VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + size_t dataSize, + 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; + + 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 vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + /* TODO the renderer should transparently vkCmdCopyQueryPoolResults to a + * coherent memory such that we can memcpy from the coherent memory to + * avoid this serialized round trip. + */ + VkResult result = vn_call_vkGetQueryPoolResults( + dev->instance, 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; + } + } + } + + vk_free(alloc, packed_data); + return vn_result(dev->instance, result); +} diff --git a/src/virtio/vulkan/vn_query_pool.h b/src/virtio/vulkan/vn_query_pool.h new file mode 100644 index 00000000000..dae225978dd --- /dev/null +++ b/src/virtio/vulkan/vn_query_pool.h @@ -0,0 +1,27 @@ +/* + * Copyright 2019 Google LLC + * SPDX-License-Identifier: MIT + * + * based in part on anv and radv which are: + * Copyright © 2015 Intel Corporation + * Copyright © 2016 Red Hat. + * Copyright © 2016 Bas Nieuwenhuizen + */ + +#ifndef VN_QUERY_POOL_H +#define VN_QUERY_POOL_H + +#include "vn_common.h" + +struct vn_query_pool { + struct vn_object_base base; + + VkAllocationCallbacks allocator; + uint32_t result_array_size; +}; +VK_DEFINE_NONDISP_HANDLE_CASTS(vn_query_pool, + base.base, + VkQueryPool, + VK_OBJECT_TYPE_QUERY_POOL) + +#endif /* VN_QUERY_POOL_H */