Browse Source

turnip: Implement vkCmdEndQuery for occlusion queries

turnip-occlusion-query2
Brian Ho 6 years ago
parent
commit
45812acffd
1 changed files with 54 additions and 4 deletions
  1. 54
    4
      src/freedreno/vulkan/tu_query.c

+ 54
- 4
src/freedreno/vulkan/tu_query.c View File

@@ -48,10 +48,9 @@ struct PACKED occlusion_query_slot {
/* 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,
static uint64_t query_iova(struct tu_query_pool *pool, uint32_t query,
uint32_t index) {
return (pool->bo->iova) + (pool->stride * query) +
(index * sizeof(uint64_t));
return pool->bo->iova + pool->stride * query + index * sizeof(uint64_t);
}

VkResult
@@ -167,7 +166,7 @@ emit_begin_occlusion_query(struct tu_cmd_buffer *cmdbuf,
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_qw(cs, query_iova(pool, query, 1 /* begin */));

tu_cs_emit_pkt7(cs, CP_EVENT_WRITE, 1);
tu_cs_emit(cs, ZPASS_DONE);
@@ -202,11 +201,62 @@ tu_CmdBeginQuery(VkCommandBuffer commandBuffer,
tu_bo_list_add(&cmdbuf->bo_list, pool->bo, MSM_SUBMIT_BO_WRITE);
}

static void
emit_end_occlusion_query(struct tu_cmd_buffer *cmdbuf,
struct tu_cs *cs,
struct tu_query_pool *pool,
uint32_t query) {
/* Ending an occlusion query happens in a few steps:
* 1) Set the query->end to UINT64_MAX.
* 2) Set up the SAMPLE_COUNT registers and trigger a CP_EVENT_WRITE to
* write the current sample count value into query->end.
* 3) Since (2) is asynchronous, wait until query->end is not equal to
* UINT64_MAX to set the query's availability bit via CP_WAIT_REG_MEM.
*/
uint64_t end_iova = query_iova(pool, query, 2 /* end */);
tu_cs_reserve_space(cmdbuf->device, cs, 25);
tu_cs_emit_pkt7(cs, CP_MEM_WRITE, 4);
tu_cs_emit_qw(cs, end_iova);
tu_cs_emit_qw(cs, 0xffffffffffffffffull);
tu_cs_emit_pkt7(cs, CP_WAIT_MEM_WRITES, 0);

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, end_iova);
tu_cs_emit_pkt7(cs, CP_EVENT_WRITE, 1);
tu_cs_emit(cs, ZPASS_DONE);

tu_cs_emit_pkt7(cs, CP_WAIT_REG_MEM, 6);
tu_cs_emit(cs, 0x00000014); // XXX
tu_cs_emit_qw(cs, end_iova);
tu_cs_emit_qw(cs, 0xffffffffffffffffull);
tu_cs_emit(cs, 0x00000010); // XXX
tu_cs_emit_pkt7(cs, CP_MEM_WRITE, 4);
tu_cs_emit_qw(cs, query_iova(pool, query, 0 /* available */));
tu_cs_emit_qw(cs, 0x1);
}

void
tu_CmdEndQuery(VkCommandBuffer commandBuffer,
VkQueryPool queryPool,
uint32_t query)
{
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:
emit_end_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");
}
}

void

Loading…
Cancel
Save