Path: blob/21.2-virgl/src/virtio/vulkan/vn_query_pool.c
4560 views
/*1* Copyright 2019 Google LLC2* SPDX-License-Identifier: MIT3*4* based in part on anv and radv which are:5* Copyright © 2015 Intel Corporation6* Copyright © 2016 Red Hat.7* Copyright © 2016 Bas Nieuwenhuizen8*/910#include "vn_query_pool.h"1112#include "venus-protocol/vn_protocol_driver_query_pool.h"1314#include "vn_device.h"1516/* query pool commands */1718VkResult19vn_CreateQueryPool(VkDevice device,20const VkQueryPoolCreateInfo *pCreateInfo,21const VkAllocationCallbacks *pAllocator,22VkQueryPool *pQueryPool)23{24struct vn_device *dev = vn_device_from_handle(device);25const VkAllocationCallbacks *alloc =26pAllocator ? pAllocator : &dev->base.base.alloc;2728struct vn_query_pool *pool =29vk_zalloc(alloc, sizeof(*pool), VN_DEFAULT_ALIGN,30VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);31if (!pool)32return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);3334vn_object_base_init(&pool->base, VK_OBJECT_TYPE_QUERY_POOL, &dev->base);3536pool->allocator = *alloc;3738switch (pCreateInfo->queryType) {39case VK_QUERY_TYPE_OCCLUSION:40pool->result_array_size = 1;41break;42case VK_QUERY_TYPE_PIPELINE_STATISTICS:43pool->result_array_size =44util_bitcount(pCreateInfo->pipelineStatistics);45break;46case VK_QUERY_TYPE_TIMESTAMP:47pool->result_array_size = 1;48break;49case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:50pool->result_array_size = 2;51break;52default:53unreachable("bad query type");54break;55}5657VkQueryPool pool_handle = vn_query_pool_to_handle(pool);58vn_async_vkCreateQueryPool(dev->instance, device, pCreateInfo, NULL,59&pool_handle);6061*pQueryPool = pool_handle;6263return VK_SUCCESS;64}6566void67vn_DestroyQueryPool(VkDevice device,68VkQueryPool queryPool,69const VkAllocationCallbacks *pAllocator)70{71struct vn_device *dev = vn_device_from_handle(device);72struct vn_query_pool *pool = vn_query_pool_from_handle(queryPool);73const VkAllocationCallbacks *alloc;7475if (!pool)76return;7778alloc = pAllocator ? pAllocator : &pool->allocator;7980vn_async_vkDestroyQueryPool(dev->instance, device, queryPool, NULL);8182vn_object_base_fini(&pool->base);83vk_free(alloc, pool);84}8586void87vn_ResetQueryPool(VkDevice device,88VkQueryPool queryPool,89uint32_t firstQuery,90uint32_t queryCount)91{92struct vn_device *dev = vn_device_from_handle(device);9394vn_async_vkResetQueryPool(dev->instance, device, queryPool, firstQuery,95queryCount);96}9798VkResult99vn_GetQueryPoolResults(VkDevice device,100VkQueryPool queryPool,101uint32_t firstQuery,102uint32_t queryCount,103size_t dataSize,104void *pData,105VkDeviceSize stride,106VkQueryResultFlags flags)107{108struct vn_device *dev = vn_device_from_handle(device);109struct vn_query_pool *pool = vn_query_pool_from_handle(queryPool);110const VkAllocationCallbacks *alloc = &pool->allocator;111112const size_t result_width = flags & VK_QUERY_RESULT_64_BIT ? 8 : 4;113const size_t result_size = pool->result_array_size * result_width;114const bool result_always_written =115flags & (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_PARTIAL_BIT);116117VkQueryResultFlags packed_flags = flags;118size_t packed_stride = result_size;119if (!result_always_written)120packed_flags |= VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;121if (packed_flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)122packed_stride += result_width;123124const size_t packed_size = packed_stride * queryCount;125void *packed_data;126if (result_always_written && packed_stride == stride) {127packed_data = pData;128} else {129packed_data = vk_alloc(alloc, packed_size, VN_DEFAULT_ALIGN,130VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);131if (!packed_data)132return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);133}134135/* TODO the renderer should transparently vkCmdCopyQueryPoolResults to a136* coherent memory such that we can memcpy from the coherent memory to137* avoid this serialized round trip.138*/139VkResult result = vn_call_vkGetQueryPoolResults(140dev->instance, device, queryPool, firstQuery, queryCount, packed_size,141packed_data, packed_stride, packed_flags);142143if (packed_data == pData)144return vn_result(dev->instance, result);145146const size_t copy_size =147result_size +148(flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT ? result_width : 0);149const void *src = packed_data;150void *dst = pData;151if (result == VK_SUCCESS) {152for (uint32_t i = 0; i < queryCount; i++) {153memcpy(dst, src, copy_size);154src += packed_stride;155dst += stride;156}157} else if (result == VK_NOT_READY) {158assert(!result_always_written &&159(packed_flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));160if (flags & VK_QUERY_RESULT_64_BIT) {161for (uint32_t i = 0; i < queryCount; i++) {162const bool avail = *(const uint64_t *)(src + result_size);163if (avail)164memcpy(dst, src, copy_size);165else if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)166*(uint64_t *)(dst + result_size) = 0;167168src += packed_stride;169dst += stride;170}171} else {172for (uint32_t i = 0; i < queryCount; i++) {173const bool avail = *(const uint32_t *)(src + result_size);174if (avail)175memcpy(dst, src, copy_size);176else if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)177*(uint32_t *)(dst + result_size) = 0;178179src += packed_stride;180dst += stride;181}182}183}184185vk_free(alloc, packed_data);186return vn_result(dev->instance, result);187}188189190