v3dv: implement interaction of queries with multiview

When multiview is enabled, queries must begin and end in the
same subpass and N consecutive queries are implicitly used,
where N is the number of views enabled in the subpass.
Implementations decide how results are split across queries.

In our case, only one query is really used, but we still need
to flag all N queries as available by the time we flag the one
we use so that the application doesn't receive unexpected errors
when trying to retrieve values from them.

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12034>
This commit is contained in:
Iago Toral Quiroga
2021-07-23 14:49:05 +02:00
committed by Marge Bot
parent 374215de1a
commit c19dcec604
3 changed files with 54 additions and 8 deletions
+35 -1
View File
@@ -3061,6 +3061,27 @@ v3dv_cmd_buffer_end_query(struct v3dv_cmd_buffer *cmd_buffer,
info->pool = pool;
info->query = query;
/* From the Vulkan spec:
*
* "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."
*
* In our case, only the first query is used but this means we still need
* to flag the other queries as available so we don't emit errors when
* the applications attempt to retrive values from them.
*/
struct v3dv_render_pass *pass = cmd_buffer->state.pass;
if (!pass->multiview_enabled) {
info->count = 1;
} else {
struct v3dv_subpass *subpass = &pass->subpasses[state->subpass_idx];
info->count = util_bitcount(subpass->view_mask);
}
} else {
/* Otherwise, schedule the CPU job immediately */
struct v3dv_job *job =
@@ -3071,6 +3092,10 @@ v3dv_cmd_buffer_end_query(struct v3dv_cmd_buffer *cmd_buffer,
job->cpu.query_end.pool = pool;
job->cpu.query_end.query = query;
/* Multiview queries cannot cross subpass boundaries */
job->cpu.query_end.count = 1;
list_addtail(&job->list_link, &cmd_buffer->jobs);
}
@@ -3249,7 +3274,8 @@ v3dv_CmdWriteTimestamp(VkCommandBuffer commandBuffer,
/* If this is called inside a render pass we need to finish the current
* job here...
*/
if (cmd_buffer->state.pass)
struct v3dv_render_pass *pass = cmd_buffer->state.pass;
if (pass)
v3dv_cmd_buffer_finish_job(cmd_buffer);
struct v3dv_job *job =
@@ -3261,6 +3287,14 @@ v3dv_CmdWriteTimestamp(VkCommandBuffer commandBuffer,
job->cpu.query_timestamp.pool = query_pool;
job->cpu.query_timestamp.query = query;
if (!pass || !pass->multiview_enabled) {
job->cpu.query_timestamp.count = 1;
} else {
struct v3dv_subpass *subpass =
&pass->subpasses[cmd_buffer->state.subpass_idx];
job->cpu.query_timestamp.count = util_bitcount(subpass->view_mask);
}
list_addtail(&job->list_link, &cmd_buffer->jobs);
cmd_buffer->state.job = NULL;