Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_query.c
4565 views
/*1* Copyright © 2019 Red Hat.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "lvp_private.h"24#include "pipe/p_context.h"2526VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateQueryPool(27VkDevice _device,28const VkQueryPoolCreateInfo* pCreateInfo,29const VkAllocationCallbacks* pAllocator,30VkQueryPool* pQueryPool)31{32LVP_FROM_HANDLE(lvp_device, device, _device);3334enum pipe_query_type pipeq;35switch (pCreateInfo->queryType) {36case VK_QUERY_TYPE_OCCLUSION:37pipeq = PIPE_QUERY_OCCLUSION_COUNTER;38break;39case VK_QUERY_TYPE_TIMESTAMP:40pipeq = PIPE_QUERY_TIMESTAMP;41break;42case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:43pipeq = PIPE_QUERY_SO_STATISTICS;44break;45case VK_QUERY_TYPE_PIPELINE_STATISTICS:46pipeq = PIPE_QUERY_PIPELINE_STATISTICS;47break;48default:49return VK_ERROR_FEATURE_NOT_PRESENT;50}51struct lvp_query_pool *pool;52uint32_t pool_size = sizeof(*pool) + pCreateInfo->queryCount * sizeof(struct pipe_query *);5354pool = vk_zalloc2(&device->vk.alloc, pAllocator,55pool_size, 8,56VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);57if (!pool)58return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);5960vk_object_base_init(&device->vk, &pool->base,61VK_OBJECT_TYPE_QUERY_POOL);62pool->type = pCreateInfo->queryType;63pool->count = pCreateInfo->queryCount;64pool->base_type = pipeq;65pool->pipeline_stats = pCreateInfo->pipelineStatistics;6667*pQueryPool = lvp_query_pool_to_handle(pool);68return VK_SUCCESS;69}7071VKAPI_ATTR void VKAPI_CALL lvp_DestroyQueryPool(72VkDevice _device,73VkQueryPool _pool,74const VkAllocationCallbacks* pAllocator)75{76LVP_FROM_HANDLE(lvp_device, device, _device);77LVP_FROM_HANDLE(lvp_query_pool, pool, _pool);7879if (!pool)80return;8182for (unsigned i = 0; i < pool->count; i++)83if (pool->queries[i])84device->queue.ctx->destroy_query(device->queue.ctx, pool->queries[i]);85vk_object_base_finish(&pool->base);86vk_free2(&device->vk.alloc, pAllocator, pool);87}8889VKAPI_ATTR VkResult VKAPI_CALL lvp_GetQueryPoolResults(90VkDevice _device,91VkQueryPool queryPool,92uint32_t firstQuery,93uint32_t queryCount,94size_t dataSize,95void* pData,96VkDeviceSize stride,97VkQueryResultFlags flags)98{99LVP_FROM_HANDLE(lvp_device, device, _device);100LVP_FROM_HANDLE(lvp_query_pool, pool, queryPool);101VkResult vk_result = VK_SUCCESS;102103lvp_DeviceWaitIdle(_device);104105for (unsigned i = firstQuery; i < firstQuery + queryCount; i++) {106uint8_t *dptr = (uint8_t *)((char *)pData + (stride * (i - firstQuery)));107union pipe_query_result result;108bool ready = false;109if (pool->queries[i]) {110ready = device->queue.ctx->get_query_result(device->queue.ctx,111pool->queries[i],112(flags & VK_QUERY_RESULT_WAIT_BIT),113&result);114} else {115result.u64 = 0;116}117118if (!ready && !(flags & VK_QUERY_RESULT_PARTIAL_BIT))119vk_result = VK_NOT_READY;120if (flags & VK_QUERY_RESULT_64_BIT) {121if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) {122if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {123uint32_t mask = pool->pipeline_stats;124uint64_t *pstats = (uint64_t *)&result.pipeline_statistics;125while (mask) {126uint32_t i = u_bit_scan(&mask);127128*(uint64_t *)dptr = pstats[i];129dptr += 8;130}131} else if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {132*(uint64_t *)dptr = result.so_statistics.num_primitives_written;133dptr += 8;134*(uint64_t *)dptr = result.so_statistics.primitives_storage_needed;135dptr += 8;136} else {137*(uint64_t *)dptr = result.u64;138dptr += 8;139}140} else {141if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT)142dptr += 16;143else144dptr += 8;145}146147} else {148if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) {149if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {150uint32_t mask = pool->pipeline_stats;151uint64_t *pstats = (uint64_t *)&result.pipeline_statistics;152while (mask) {153uint32_t i = u_bit_scan(&mask);154155if (pstats[i] > UINT32_MAX)156*(uint32_t *)dptr = UINT32_MAX;157else158*(uint32_t *)dptr = pstats[i];159dptr += 4;160}161} else if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {162if (result.so_statistics.num_primitives_written > UINT32_MAX)163*(uint32_t *)dptr = UINT32_MAX;164else165*(uint32_t *)dptr = (uint32_t)result.so_statistics.num_primitives_written;166dptr += 4;167if (result.so_statistics.primitives_storage_needed > UINT32_MAX)168*(uint32_t *)dptr = UINT32_MAX;169else170*(uint32_t *)dptr = (uint32_t)result.so_statistics.primitives_storage_needed;171dptr += 4;172} else {173if (result.u64 > UINT32_MAX)174*(uint32_t *)dptr = UINT32_MAX;175else176*(uint32_t *)dptr = result.u32;177dptr += 4;178}179} else180if (pool->type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT)181dptr += 8;182else183dptr += 4;184}185186if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {187if (flags & VK_QUERY_RESULT_64_BIT)188*(uint64_t *)dptr = ready;189else190*(uint32_t *)dptr = ready;191}192}193return vk_result;194}195196VKAPI_ATTR void VKAPI_CALL lvp_ResetQueryPool(197VkDevice _device,198VkQueryPool queryPool,199uint32_t firstQuery,200uint32_t queryCount)201{202LVP_FROM_HANDLE(lvp_device, device, _device);203LVP_FROM_HANDLE(lvp_query_pool, pool, queryPool);204205for (uint32_t i = 0; i < queryCount; i++) {206uint32_t idx = i + firstQuery;207208if (pool->queries[idx]) {209device->queue.ctx->destroy_query(device->queue.ctx, pool->queries[idx]);210pool->queries[idx] = NULL;211}212}213}214215216