From b4eb029062a944c428d6214447a852318e36016e Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 5 Oct 2018 18:04:56 +0200 Subject: radv: implement VK_EXT_transform_feedback This implementation should work and potential bugs can be fixed during the release candidates window anyway. Signed-off-by: Samuel Pitoiset Reviewed-by: Dave Airlie --- src/amd/vulkan/radv_query.c | 111 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 10 deletions(-) (limited to 'src/amd/vulkan/radv_query.c') diff --git a/src/amd/vulkan/radv_query.c b/src/amd/vulkan/radv_query.c index 63a2b6a7d7c..5a326c9df54 100644 --- a/src/amd/vulkan/radv_query.c +++ b/src/amd/vulkan/radv_query.c @@ -789,6 +789,9 @@ VkResult radv_CreateQueryPool( case VK_QUERY_TYPE_TIMESTAMP: pool->stride = 8; break; + case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: + pool->stride = 32; + break; default: unreachable("creating unhandled query type"); } @@ -951,6 +954,44 @@ VkResult radv_GetQueryPoolResults( } break; } + case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: { + volatile uint64_t const *src64 = (volatile uint64_t const *)src; + uint64_t num_primitives_written; + uint64_t primitive_storage_needed; + + /* SAMPLE_STREAMOUTSTATS stores this structure: + * { + * u64 NumPrimitivesWritten; + * u64 PrimitiveStorageNeeded; + * } + */ + available = 1; + for (int j = 0; j < 4; j++) { + if (!(src64[j] & 0x8000000000000000UL)) + available = 0; + } + + if (!available && !(flags & VK_QUERY_RESULT_PARTIAL_BIT)) { + result = VK_NOT_READY; + break; + } + + num_primitives_written = src64[3] - src64[1]; + primitive_storage_needed = src64[2] - src64[0]; + + if (flags & VK_QUERY_RESULT_64_BIT) { + *(uint64_t *)dest = num_primitives_written; + dest += 8; + *(uint64_t *)dest = primitive_storage_needed; + dest += 8; + } else { + *(uint32_t *)dest = num_primitives_written; + dest += 4; + *(uint32_t *)dest = primitive_storage_needed; + dest += 4; + } + break; + } default: unreachable("trying to get results of unhandled query type"); } @@ -1109,10 +1150,22 @@ void radv_CmdResetQueryPool( } } +static unsigned event_type_for_stream(unsigned stream) +{ + switch (stream) { + default: + case 0: return V_028A90_SAMPLE_STREAMOUTSTATS; + case 1: return V_028A90_SAMPLE_STREAMOUTSTATS1; + case 2: return V_028A90_SAMPLE_STREAMOUTSTATS2; + case 3: return V_028A90_SAMPLE_STREAMOUTSTATS3; + } +} + static void emit_begin_query(struct radv_cmd_buffer *cmd_buffer, uint64_t va, VkQueryType query_type, - VkQueryControlFlags flags) + VkQueryControlFlags flags, + uint32_t index) { struct radeon_cmdbuf *cs = cmd_buffer->cs; switch (query_type) { @@ -1161,6 +1214,16 @@ static void emit_begin_query(struct radv_cmd_buffer *cmd_buffer, radeon_emit(cs, va); radeon_emit(cs, va >> 32); break; + case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: + radeon_check_space(cmd_buffer->device->ws, cs, 4); + + assert(index < MAX_SO_STREAMS); + + radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 2, 0)); + radeon_emit(cs, EVENT_TYPE(event_type_for_stream(index)) | EVENT_INDEX(3)); + radeon_emit(cs, va); + radeon_emit(cs, va >> 32); + break; default: unreachable("beginning unhandled query type"); } @@ -1169,7 +1232,7 @@ static void emit_begin_query(struct radv_cmd_buffer *cmd_buffer, static void emit_end_query(struct radv_cmd_buffer *cmd_buffer, uint64_t va, uint64_t avail_va, - VkQueryType query_type) + VkQueryType query_type, uint32_t index) { struct radeon_cmdbuf *cs = cmd_buffer->cs; switch (query_type) { @@ -1215,16 +1278,27 @@ static void emit_end_query(struct radv_cmd_buffer *cmd_buffer, avail_va, 0, 1, cmd_buffer->gfx9_eop_bug_va); break; + case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: + radeon_check_space(cmd_buffer->device->ws, cs, 4); + + assert(index < MAX_SO_STREAMS); + + radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 2, 0)); + radeon_emit(cs, EVENT_TYPE(event_type_for_stream(index)) | EVENT_INDEX(3)); + radeon_emit(cs, (va + 16)); + radeon_emit(cs, (va + 16) >> 32); + break; default: unreachable("ending unhandled query type"); } } -void radv_CmdBeginQuery( +void radv_CmdBeginQueryIndexedEXT( VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, - VkQueryControlFlags flags) + VkQueryControlFlags flags, + uint32_t index) { RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); RADV_FROM_HANDLE(radv_query_pool, pool, queryPool); @@ -1247,14 +1321,23 @@ void radv_CmdBeginQuery( va += pool->stride * query; - emit_begin_query(cmd_buffer, va, pool->type, flags); + emit_begin_query(cmd_buffer, va, pool->type, flags, index); } +void radv_CmdBeginQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + VkQueryControlFlags flags) +{ + radv_CmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, 0); +} -void radv_CmdEndQuery( +void radv_CmdEndQueryIndexedEXT( VkCommandBuffer commandBuffer, VkQueryPool queryPool, - uint32_t query) + uint32_t query, + uint32_t index) { RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); RADV_FROM_HANDLE(radv_query_pool, pool, queryPool); @@ -1265,7 +1348,7 @@ void radv_CmdEndQuery( /* Do not need to add the pool BO to the list because the query must * currently be active, which means the BO is already in the list. */ - emit_end_query(cmd_buffer, va, avail_va, pool->type); + emit_end_query(cmd_buffer, va, avail_va, pool->type, index); /* * For multiview we have to emit a query for each bit in the mask, @@ -1282,12 +1365,20 @@ void radv_CmdEndQuery( for (unsigned i = 1; i < util_bitcount(cmd_buffer->state.subpass->view_mask); i++) { va += pool->stride; avail_va += 4; - emit_begin_query(cmd_buffer, va, pool->type, 0); - emit_end_query(cmd_buffer, va, avail_va, pool->type); + emit_begin_query(cmd_buffer, va, pool->type, 0, 0); + emit_end_query(cmd_buffer, va, avail_va, pool->type, 0); } } } +void radv_CmdEndQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query) +{ + radv_CmdEndQueryIndexedEXT(commandBuffer, queryPool, query, 0); +} + void radv_CmdWriteTimestamp( VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, -- cgit v1.2.3