| @@ -31,14 +31,29 @@ | |||
| #include <string.h> | |||
| #include <unistd.h> | |||
| #include "registers/adreno_pm4.xml.h" | |||
| #include "registers/adreno_common.xml.h" | |||
| #include "registers/a6xx.xml.h" | |||
| #include "nir/nir_builder.h" | |||
| #include "tu_cs.h" | |||
| struct PACKED occlusion_query_slot { | |||
| uint64_t available; /* 0 when unavailable, 1 when available */ | |||
| uint64_t begin; | |||
| uint64_t end; | |||
| }; | |||
| /* Returns the IOVA of a given uint64_t field in a given slot of a query | |||
| * pool. | |||
| */ | |||
| static uint64_t query_address(struct tu_query_pool *pool, uint32_t query, | |||
| uint32_t index) { | |||
| return (pool->bo->iova) + (pool->stride * query) + | |||
| (index * sizeof(uint64_t)); | |||
| } | |||
| VkResult | |||
| tu_CreateQueryPool(VkDevice _device, | |||
| const VkQueryPoolCreateInfo *pCreateInfo, | |||
| @@ -142,12 +157,49 @@ tu_CmdResetQueryPool(VkCommandBuffer commandBuffer, | |||
| { | |||
| } | |||
| static void | |||
| emit_begin_occlusion_query(struct tu_cmd_buffer *cmdbuf, | |||
| struct tu_cs *cs, | |||
| struct tu_query_pool *pool, | |||
| uint32_t query) { | |||
| tu_cs_reserve_space(cmdbuf->device, cs, 7); | |||
| tu_cs_emit_pkt4(cs, REG_A6XX_RB_SAMPLE_COUNT_CONTROL, 1); | |||
| tu_cs_emit(cs, A6XX_RB_SAMPLE_COUNT_CONTROL_COPY); | |||
| tu_cs_emit_pkt4(cs, REG_A6XX_RB_SAMPLE_COUNT_ADDR_LO, 2); | |||
| tu_cs_emit_qw(cs, query_address(pool, query, 1 /* begin */)); | |||
| tu_cs_emit_pkt7(cs, CP_EVENT_WRITE, 1); | |||
| tu_cs_emit(cs, ZPASS_DONE); | |||
| } | |||
| void | |||
| tu_CmdBeginQuery(VkCommandBuffer commandBuffer, | |||
| VkQueryPool queryPool, | |||
| uint32_t query, | |||
| VkQueryControlFlags flags) | |||
| { | |||
| TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer); | |||
| TU_FROM_HANDLE(tu_query_pool, pool, queryPool); | |||
| struct tu_cs *cs = &cmdbuf->cs; | |||
| assert(query < pool->size); | |||
| switch (pool->type) { | |||
| case VK_QUERY_TYPE_OCCLUSION: | |||
| /* In freedreno, there is no implementation difference between | |||
| * GL_SAMPLES_PASSED and GL_ANY_SAMPLES_PASSED, so we can similarly | |||
| * ignore the VK_QUERY_CONTROL_PRECISE_BIT flag here. | |||
| */ | |||
| emit_begin_occlusion_query(cmdbuf, cs, pool, query); | |||
| break; | |||
| case VK_QUERY_TYPE_PIPELINE_STATISTICS: | |||
| case VK_QUERY_TYPE_TIMESTAMP: | |||
| unreachable("Unimplemented query type"); | |||
| default: | |||
| assert(!"Invalid query type"); | |||
| } | |||
| tu_bo_list_add(&cmdbuf->bo_list, pool->bo, MSM_SUBMIT_BO_WRITE); | |||
| } | |||
| void | |||