<html>
<head>
<meta http-equiv="Content-Type" content="text/html"/>
</head>
<body>
<div style="color: black;">
<p style="margin: 0 0 1em 0; color: black; font-family: sans-serif;">On January 17, 2018 23:06:23 Iago Toral <itoral@igalia.com> wrote:</p>
<p style="margin: 0 0 1em 0; color: black; font-family: sans-serif;">> On Wed, 2018-01-17 at 13:14 -0800, Jason Ekstrand wrote:<br>
>> On Wed, Jan 17, 2018 at 4:59 AM, Iago Toral Quiroga <itoral@igalia.co<br>
>> m> wrote:<br>
>> > From the Vulkan spec with KHX extensions:<br>
>> > <br>
>> > <br>
>> > <br>
>> > "If queries are used while executing a render pass instance that<br>
>> > has<br>
>> > <br>
>> > multiview enabled, the query uses N consecutive query indices<br>
>> > <br>
>> > in the query pool (starting at query) where N is the number of<br>
>> > bits<br>
>> > <br>
>> > set in the view mask in the subpass the query is used in.<br>
>> > <br>
>> > <br>
>> > <br>
>> > How the numerical results of the query are distributed among the<br>
>> > <br>
>> > queries is implementation-dependent. For example, some<br>
>> > implementations<br>
>> > <br>
>> > may write each view's results to a distinct query, while other<br>
>> > <br>
>> > implementations may write the total result to the first query<br>
>> > and write<br>
>> > <br>
>> > zero to the other queries. However, the sum of the results in<br>
>> > all the<br>
>> > <br>
>> > queries must accurately reflect the total result of the query<br>
>> > summed<br>
>> > <br>
>> > over all views. Applications can sum the results from all the<br>
>> > queries to<br>
>> > <br>
>> > compute the total result."<br>
>> > <br>
>> > <br>
>> > <br>
>> > In our case we only really emit a single query (in the first query<br>
>> > index)<br>
>> > <br>
>> > that stores the aggregated result for all views, but we still need<br>
>> > to manage<br>
>> > <br>
>> > availability for all the other query indices involved, even if we<br>
>> > don't<br>
>> > <br>
>> > actually use them.<br>
>> > <br>
>> > <br>
>> > <br>
>> > This is relevant when clients call vkGetQueryPoolResults and pass<br>
>> > all N<br>
>> > <br>
>> > queries to retrieve the results. In that scenario, without this<br>
>> > patch,<br>
>> > <br>
>> > we will never see queries other than the first being available<br>
>> > since we<br>
>> > <br>
>> > never emit them.<br>
>> > <br>
>> > <br>
>> > <br>
>> > v2: we need the same tratment for timestamp queries.<br>
>> > <br>
>> > <br>
>> > <br>
>> > v3 (Jason):<br>
>> > <br>
>> > - Better and if instead of an early return.<br>
>> > <br>
>> > - We can't write to this memory in the CPU, we should use<br>
>> > <br>
>> > MI_STORE_DATA_IMM and emit_query_availability (Jason).<br>
>> > <br>
>> > <br>
>> > <br>
>> > Fixes test failures in some work-in-progress CTS multiview+query<br>
>> > tests.<br>
>> > <br>
>> > ---<br>
>> > <br>
>> > src/intel/vulkan/genX_query.c | 54<br>
>> > +++++++++++++++++++++++++++++++++++++++++++<br>
>> > <br>
>> > 1 file changed, 54 insertions(+)<br>
>> > <br>
>> > <br>
>> > <br>
>> > diff --git a/src/intel/vulkan/genX_query.c<br>
>> > b/src/intel/vulkan/genX_query.c<br>
>> > <br>
>> > index 7683d0d1e3..8db3d7b561 100644<br>
>> > <br>
>> > --- a/src/intel/vulkan/genX_query.c<br>
>> > <br>
>> > +++ b/src/intel/vulkan/genX_query.c<br>
>> > <br>
>> > @@ -322,6 +322,30 @@ emit_query_availability(struct anv_cmd_buffer<br>
>> > *cmd_buffer,<br>
>> > <br>
>> > }<br>
>> > <br>
>> > }<br>
>> > <br>
>> > <br>
>> > <br>
>> > +/**<br>
>> > <br>
>> > + * Goes through a series of consecutive query indices in the given<br>
>> > pool,<br>
>> > <br>
>> > + * sets all elements to the provided value and emits the queries.<br>
>> > <br>
>> > + */<br>
>> > <br>
>> > +static void<br>
>> > <br>
>> > +emit_preset_queries(struct anv_cmd_buffer *cmd_buffer,<br>
>> > <br>
>> > + struct anv_query_pool *pool,<br>
>> > <br>
>> > + uint32_t first_index, uint32_t num_queries,<br>
>> > uint64_t value)<br>
>> <br>
>> I don't know that having a value passed in is all that useful. We<br>
>> may as well make it emit_zero_query or emit_null_query.<br>
><br>
> Ok.<br>
>> > +{<br>
>> > <br>
>> > + const uint32_t num_elements = pool->stride / sizeof(uint64_t); <br>
>> > <br>
>> > +<br>
>> > <br>
>> > + for (uint32_t i = 0; i < num_queries; i++) {<br>
>> > <br>
>> > + uint32_t slot = (first_index + i) * pool->stride;<br>
</p>
<p style="margin: 0 0 1em 0; color: black;"><br>
slot_offset might be a better name.<br>
</p>
<p style="margin: 0 0 1em 0; color: black; font-family: sans-serif;"><br>
>> I think you probably want to start with i = 1 instead of i = 0. <br>
>> write_availability below will set the first uint64_t for you; this<br>
>> loop only needs to set the others.<br>
><br>
> This is looping through the queries that need to be emitted as 0, the<br>
> loop below handles writing 0's to all their value elements,<br>
> first_index is the index of the first query that needs to be set to 0<br>
> and num_elements represents the number of queries (starting at<br>
> first_index that need to be set to 0), so I think the loop is fine. The<br>
> loop below is the one that takes care of setting a single query to 0,<br>
> and that one starts at 1 like you suggest, so I think this is fine,<br>
> right?</p>
<p style="margin: 0 0 1em 0; color: black;"></p>
<p style="margin: 0 0 1em 0; color: black;">Your right. I didn't read clearly enough. What you have is correct. Rb stands.<br>
</p>
<p style="margin: 0 0 1em 0; color: black; font-family: sans-serif;"><br>
>> With those two adjustments made, this would be<br>
>> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net><br>
>> <br>
>> > + for (uint32_t j = 1; j < num_elements; j++) {<br>
>> > <br>
>> > + anv_batch_emit(&cmd_buffer->batch,<br>
>> > GENX(MI_STORE_DATA_IMM), sdi) {<br>
>> > <br>
>> > + sdi.Address.bo = &pool->bo;<br>
>> > <br>
>> > + sdi.Address.offset = slot + j * sizeof(uint64_t);<br>
>> > <br>
>> > + sdi.ImmediateData = value;<br>
>> > <br>
>> > + }<br>
>> > <br>
>> > + }<br>
>> > <br>
>> > + emit_query_availability(cmd_buffer, &pool->bo, slot);<br>
>> > <br>
>> > + }<br>
>> > <br>
>> > +}<br>
>> > <br>
>> > +<br>
>> > <br>
>> > void genX(CmdResetQueryPool)(<br>
>> > <br>
>> > VkCommandBuffer commandBuffer,<br>
>> > <br>
>> > VkQueryPool queryPool,<br>
>> > <br>
>> > @@ -462,6 +486,21 @@ void genX(CmdEndQuery)(<br>
>> > <br>
>> > default:<br>
>> > <br>
>> > unreachable("");<br>
>> > <br>
>> > }<br>
>> > <br>
>> > +<br>
>> > <br>
>> > + /* When multiview is active the spec requires that N<br>
>> > consecutive query<br>
>> > <br>
>> > + * indices are used, where N is the number of active views in<br>
>> > the subpass.<br>
>> > <br>
>> > + * The spec allows that we only write the results to one of the<br>
>> > queries<br>
>> > <br>
>> > + * but we still need to manage result availability for all the<br>
>> > query indices.<br>
>> > <br>
>> > + * Since we only emit a single query for all active views in<br>
>> > the<br>
>> > <br>
>> > + * first index, mark the other query indices as being already<br>
>> > available<br>
>> > <br>
>> > + * with result 0.<br>
>> > <br>
>> > + */<br>
>> > <br>
>> > + if (cmd_buffer->state.subpass && cmd_buffer->state.subpass-<br>
>> > >view_mask) {<br>
>> > <br>
>> > + const uint32_t num_queries =<br>
>> > <br>
>> > + _mesa_bitcount(cmd_buffer->state.subpass->view_mask);<br>
>> > <br>
>> > + if (num_queries > 1)<br>
>> > <br>
>> > + emit_preset_queries(cmd_buffer, pool, query + 1,<br>
>> > num_queries - 1, 0LL);<br>
>> > <br>
>> > + }<br>
>> > <br>
>> > }<br>
>> > <br>
>> > <br>
>> > <br>
>> > #define TIMESTAMP 0x2358<br>
>> > <br>
>> > @@ -504,6 +543,21 @@ void genX(CmdWriteTimestamp)(<br>
>> > <br>
>> > }<br>
>> > <br>
>> > <br>
>> > <br>
>> > emit_query_availability(cmd_buffer, &pool->bo, offset);<br>
>> > <br>
>> > +<br>
>> > <br>
>> > + /* When multiview is active the spec requires that N<br>
>> > consecutive query<br>
>> > <br>
>> > + * indices are used, where N is the number of active views in<br>
>> > the subpass.<br>
>> > <br>
>> > + * The spec allows that we only write the results to one of the<br>
>> > queries<br>
>> > <br>
>> > + * but we still need to manage result availability for all the<br>
>> > query indices.<br>
>> > <br>
>> > + * Since we only emit a single query for all active views in<br>
>> > the<br>
>> > <br>
>> > + * first index, mark the other query indices as being already<br>
>> > available<br>
>> > <br>
>> > + * with result 0.<br>
>> > <br>
>> > + */<br>
>> > <br>
>> > + if (cmd_buffer->state.subpass && cmd_buffer->state.subpass-<br>
>> > >view_mask) {<br>
>> > <br>
>> > + const uint32_t num_queries =<br>
>> > <br>
>> > + _mesa_bitcount(cmd_buffer->state.subpass->view_mask);<br>
>> > <br>
>> > + if (num_queries > 1)<br>
>> > <br>
>> > + emit_preset_queries(cmd_buffer, pool, query + 1,<br>
>> > num_queries - 1, 0LL);<br>
>> > <br>
>> > + }<br>
>> > <br>
>> > }<br>
>> > <br>
>> > <br>
>> > <br>
>> > #if GEN_GEN > 7 || GEN_IS_HASWELL<br>
>> > <br>
>> > --<br>
>> > <br>
>> > 2.14.1<br>
>> > <br>
>> > <br>
>> > <br>
</p>
</div>
</body>
</html>