blob: f549fe1b89e17117a55526d12c0a7ee1cdbbfdbb [file] [log] [blame]
/*
* Copyright © 2019 Red Hat.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "lvp_private.h"
#include "pipe/p_context.h"
VkResult lvp_CreateQueryPool(
VkDevice _device,
const VkQueryPoolCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkQueryPool* pQueryPool)
{
LVP_FROM_HANDLE(lvp_device, device, _device);
enum pipe_query_type pipeq;
switch (pCreateInfo->queryType) {
case VK_QUERY_TYPE_OCCLUSION:
pipeq = PIPE_QUERY_OCCLUSION_COUNTER;
break;
case VK_QUERY_TYPE_TIMESTAMP:
pipeq = PIPE_QUERY_TIMESTAMP;
break;
default:
return VK_ERROR_FEATURE_NOT_PRESENT;
}
struct lvp_query_pool *pool;
uint32_t pool_size = sizeof(*pool) + pCreateInfo->queryCount * sizeof(struct pipe_query *);
pool = vk_zalloc2(&device->vk.alloc, pAllocator,
pool_size, 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!pool)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
vk_object_base_init(&device->vk, &pool->base,
VK_OBJECT_TYPE_QUERY_POOL);
pool->type = pCreateInfo->queryType;
pool->count = pCreateInfo->queryCount;
pool->base_type = pipeq;
*pQueryPool = lvp_query_pool_to_handle(pool);
return VK_SUCCESS;
}
void lvp_DestroyQueryPool(
VkDevice _device,
VkQueryPool _pool,
const VkAllocationCallbacks* pAllocator)
{
LVP_FROM_HANDLE(lvp_device, device, _device);
LVP_FROM_HANDLE(lvp_query_pool, pool, _pool);
if (!pool)
return;
for (unsigned i = 0; i < pool->count; i++)
if (pool->queries[i])
device->queue.ctx->destroy_query(device->queue.ctx, pool->queries[i]);
vk_object_base_finish(&pool->base);
vk_free2(&device->vk.alloc, pAllocator, pool);
}
VkResult lvp_GetQueryPoolResults(
VkDevice _device,
VkQueryPool queryPool,
uint32_t firstQuery,
uint32_t queryCount,
size_t dataSize,
void* pData,
VkDeviceSize stride,
VkQueryResultFlags flags)
{
LVP_FROM_HANDLE(lvp_device, device, _device);
LVP_FROM_HANDLE(lvp_query_pool, pool, queryPool);
VkResult vk_result = VK_SUCCESS;
lvp_DeviceWaitIdle(_device);
for (unsigned i = firstQuery; i < firstQuery + queryCount; i++) {
uint8_t *dptr = (uint8_t *)((char *)pData + (stride * (i - firstQuery)));
union pipe_query_result result;
bool ready = false;
if (pool->queries[i]) {
ready = device->queue.ctx->get_query_result(device->queue.ctx,
pool->queries[i],
(flags & VK_QUERY_RESULT_WAIT_BIT),
&result);
} else {
result.u64 = 0;
}
if (!ready && !(flags & VK_QUERY_RESULT_PARTIAL_BIT))
vk_result = VK_NOT_READY;
if (flags & VK_QUERY_RESULT_64_BIT) {
if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT))
*(uint64_t *)dptr = result.u64;
dptr += 8;
} else {
if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) {
if (result.u64 > UINT32_MAX)
*(uint32_t *)dptr = UINT32_MAX;
else
*(uint32_t *)dptr = result.u32;
}
dptr += 4;
}
if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
if (flags & VK_QUERY_RESULT_64_BIT)
*(uint64_t *)dptr = ready;
else
*(uint32_t *)dptr = ready;
}
}
return vk_result;
}