diff options
author | Iago Toral Quiroga <[email protected]> | 2018-01-04 03:45:56 +0100 |
---|---|---|
committer | Iago Toral Quiroga <[email protected]> | 2018-01-18 16:37:06 +0100 |
commit | 7ec6e4e68980c575b0818304920a8a8829ebd240 (patch) | |
tree | 842e29aa93b24353d31b16006c9fd740c68dfbe0 /src/intel/vulkan/genX_query.c | |
parent | c9b2cb78972dd874edd5c612e6a221fb1f4d6e50 (diff) |
anv/query: implement multiview interactions
From the Vulkan spec with KHX extensions:
"If queries are used while executing a render pass instance that has
multiview enabled, the query uses N consecutive query indices
in the query pool (starting at query) where N is the number of bits
set in the view mask in the subpass the query is used in.
How the numerical results of the query are distributed among the
queries is implementation-dependent. For example, some implementations
may write each view's results to a distinct query, while other
implementations may write the total result to the first query and write
zero to the other queries. However, the sum of the results in all the
queries must accurately reflect the total result of the query summed
over all views. Applications can sum the results from all the queries to
compute the total result."
In our case we only really emit a single query (in the first query index)
that stores the aggregated result for all views, but we still need to manage
availability for all the other query indices involved, even if we don't
actually use them.
This is relevant when clients call vkGetQueryPoolResults and pass all N
queries to retrieve the results. In that scenario, without this patch,
we will never see queries other than the first being available since we
never emit them.
v2: we need the same treatment for timestamp queries.
v3 (Jason):
- Better an if instead of an early return.
- We can't write to this memory in the CPU, we should use
MI_STORE_DATA_IMM and emit_query_availability (Jason).
v4 (Jason):
- No need to take the value to write as parameter, just hard code it to 0.
Fixes test failures in some work-in-progress CTS multiview+query tests.
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/intel/vulkan/genX_query.c')
-rw-r--r-- | src/intel/vulkan/genX_query.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/intel/vulkan/genX_query.c b/src/intel/vulkan/genX_query.c index 7683d0d1e31..266163474bf 100644 --- a/src/intel/vulkan/genX_query.c +++ b/src/intel/vulkan/genX_query.c @@ -322,6 +322,30 @@ emit_query_availability(struct anv_cmd_buffer *cmd_buffer, } } +/** + * Goes through a series of consecutive query indices in the given pool + * setting all element values to 0 and emitting them as available. + */ +static void +emit_zero_queries(struct anv_cmd_buffer *cmd_buffer, + struct anv_query_pool *pool, + uint32_t first_index, uint32_t num_queries) +{ + const uint32_t num_elements = pool->stride / sizeof(uint64_t); + + for (uint32_t i = 0; i < num_queries; i++) { + uint32_t slot_offset = (first_index + i) * pool->stride; + for (uint32_t j = 1; j < num_elements; j++) { + anv_batch_emit(&cmd_buffer->batch, GENX(MI_STORE_DATA_IMM), sdi) { + sdi.Address.bo = &pool->bo; + sdi.Address.offset = slot_offset + j * sizeof(uint64_t); + sdi.ImmediateData = 0ull; + } + } + emit_query_availability(cmd_buffer, &pool->bo, slot_offset); + } +} + void genX(CmdResetQueryPool)( VkCommandBuffer commandBuffer, VkQueryPool queryPool, @@ -462,6 +486,21 @@ void genX(CmdEndQuery)( default: unreachable(""); } + + /* When multiview is active the spec requires that N consecutive query + * indices are used, where N is the number of active views in the subpass. + * The spec allows that we only write the results to one of the queries + * but we still need to manage result availability for all the query indices. + * Since we only emit a single query for all active views in the + * first index, mark the other query indices as being already available + * with result 0. + */ + if (cmd_buffer->state.subpass && cmd_buffer->state.subpass->view_mask) { + const uint32_t num_queries = + _mesa_bitcount(cmd_buffer->state.subpass->view_mask); + if (num_queries > 1) + emit_zero_queries(cmd_buffer, pool, query + 1, num_queries - 1); + } } #define TIMESTAMP 0x2358 @@ -504,6 +543,21 @@ void genX(CmdWriteTimestamp)( } emit_query_availability(cmd_buffer, &pool->bo, offset); + + /* When multiview is active the spec requires that N consecutive query + * indices are used, where N is the number of active views in the subpass. + * The spec allows that we only write the results to one of the queries + * but we still need to manage result availability for all the query indices. + * Since we only emit a single query for all active views in the + * first index, mark the other query indices as being already available + * with result 0. + */ + if (cmd_buffer->state.subpass && cmd_buffer->state.subpass->view_mask) { + const uint32_t num_queries = + _mesa_bitcount(cmd_buffer->state.subpass->view_mask); + if (num_queries > 1) + emit_zero_queries(cmd_buffer, pool, query + 1, num_queries - 1); + } } #if GEN_GEN > 7 || GEN_IS_HASWELL |