diff --git a/src/imagination/csbgen/rogue_cr.xml b/src/imagination/csbgen/rogue_cr.xml index a3f6903175e..2d04f678525 100644 --- a/src/imagination/csbgen/rogue_cr.xml +++ b/src/imagination/csbgen/rogue_cr.xml @@ -551,6 +551,10 @@ SOFTWARE. + + + + diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index 08a21422b8c..6361ab5ebf9 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -1087,6 +1087,18 @@ struct pvr_graphics_pipeline { struct pvr_fragment_shader_state fragment_shader_state; }; +struct pvr_query_pool { + struct vk_object_base base; + + /* Stride of result_buffer to get to the start of the results for the next + * Phantom. + */ + uint32_t result_stride; + + struct pvr_bo *result_buffer; + struct pvr_bo *availability_buffer; +}; + struct pvr_render_target { struct pvr_rt_dataset *rt_dataset; @@ -1359,6 +1371,10 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(pvr_pipeline, base, VkPipeline, VK_OBJECT_TYPE_PIPELINE) +VK_DEFINE_NONDISP_HANDLE_CASTS(pvr_query_pool, + base, + VkQueryPool, + VK_OBJECT_TYPE_QUERY_POOL) VK_DEFINE_NONDISP_HANDLE_CASTS(pvr_framebuffer, base, VkFramebuffer, diff --git a/src/imagination/vulkan/pvr_query.c b/src/imagination/vulkan/pvr_query.c index 0c6300730f2..ecfb07b1afa 100644 --- a/src/imagination/vulkan/pvr_query.c +++ b/src/imagination/vulkan/pvr_query.c @@ -21,22 +21,98 @@ * SOFTWARE. */ +#include +#include +#include +#include + +#include "pvr_bo.h" +#include "pvr_csb.h" +#include "pvr_device_info.h" #include "pvr_private.h" +#include "util/macros.h" +#include "vk_log.h" +#include "vk_object.h" VkResult pvr_CreateQueryPool(VkDevice _device, const VkQueryPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) { - assert(!"Unimplemented"); + PVR_FROM_HANDLE(pvr_device, device, _device); + const uint32_t core_count = device->pdevice->dev_runtime_info.core_count; + const uint32_t query_size = pCreateInfo->queryCount * sizeof(uint32_t); + struct pvr_query_pool *pool; + uint64_t alloc_size; + VkResult result; + + /* Vulkan 1.0 supports only occlusion, timestamp, and pipeline statistics + * query. + * We don't currently support timestamp queries. + * VkQueueFamilyProperties->timestampValidBits = 0. + * We don't currently support pipeline statistics queries. + * VkPhysicalDeviceFeatures->pipelineStatisticsQuery = false. + */ + assert(!device->features.pipelineStatisticsQuery); + assert(pCreateInfo->queryType == VK_QUERY_TYPE_OCCLUSION); + + pool = vk_object_alloc(&device->vk, + pAllocator, + sizeof(*pool), + VK_OBJECT_TYPE_QUERY_POOL); + if (!pool) + return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + + pool->result_stride = + ALIGN_POT(query_size, PVRX(CR_ISP_OCLQRY_BASE_ADDR_ALIGNMENT)); + + /* Each Phantom writes to a separate offset within the vis test heap so + * allocate space for the total number of Phantoms. + */ + alloc_size = pool->result_stride * core_count; + + result = pvr_bo_alloc(device, + device->heaps.vis_test_heap, + alloc_size, + PVRX(CR_ISP_OCLQRY_BASE_ADDR_ALIGNMENT), + PVR_BO_ALLOC_FLAG_CPU_MAPPED, + &pool->result_buffer); + if (result != VK_SUCCESS) + goto err_free_pool; + + result = pvr_bo_alloc(device, + device->heaps.vis_test_heap, + query_size, + sizeof(uint32_t), + PVR_BO_ALLOC_FLAG_CPU_MAPPED, + &pool->availability_buffer); + if (result != VK_SUCCESS) + goto err_free_result_buffer; + + *pQueryPool = pvr_query_pool_to_handle(pool); + return VK_SUCCESS; + +err_free_result_buffer: + pvr_bo_free(device, pool->result_buffer); + +err_free_pool: + vk_object_free(&device->vk, pAllocator, pool); + + return result; } void pvr_DestroyQueryPool(VkDevice _device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator) { - assert(!"Unimplemented"); + PVR_FROM_HANDLE(pvr_query_pool, pool, queryPool); + PVR_FROM_HANDLE(pvr_device, device, _device); + + pvr_bo_free(device, pool->availability_buffer); + pvr_bo_free(device, pool->result_buffer); + + vk_object_free(&device->vk, pAllocator, pool); } VkResult pvr_GetQueryPoolResults(VkDevice _device,