mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-05 19:10:38 +01:00
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:
parent
374215de1a
commit
c19dcec604
3 changed files with 54 additions and 8 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -896,6 +896,9 @@ struct v3dv_reset_query_cpu_job_info {
|
|||
struct v3dv_end_query_cpu_job_info {
|
||||
struct v3dv_query_pool *pool;
|
||||
uint32_t query;
|
||||
|
||||
/* This is one unless multiview is used */
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
struct v3dv_copy_query_results_cpu_job_info {
|
||||
|
|
@ -947,6 +950,9 @@ struct v3dv_csd_indirect_cpu_job_info {
|
|||
struct v3dv_timestamp_query_cpu_job_info {
|
||||
struct v3dv_query_pool *pool;
|
||||
uint32_t query;
|
||||
|
||||
/* This is one unless multiview is used */
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
struct v3dv_job {
|
||||
|
|
|
|||
|
|
@ -198,9 +198,11 @@ static VkResult
|
|||
handle_end_query_cpu_job(struct v3dv_job *job)
|
||||
{
|
||||
struct v3dv_end_query_cpu_job_info *info = &job->cpu.query_end;
|
||||
assert(info->query < info->pool->query_count);
|
||||
struct v3dv_query *query = &info->pool->queries[info->query];
|
||||
query->maybe_available = true;
|
||||
for (uint32_t i = 0; i < info->count; i++) {
|
||||
assert(info->query + i < info->pool->query_count);
|
||||
struct v3dv_query *query = &info->pool->queries[info->query + i];
|
||||
query->maybe_available = true;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
@ -452,10 +454,14 @@ handle_timestamp_query_cpu_job(struct v3dv_job *job)
|
|||
/* Compute timestamp */
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
assert(info->query < info->pool->query_count);
|
||||
struct v3dv_query *query = &info->pool->queries[info->query];
|
||||
query->maybe_available = true;
|
||||
query->value = t.tv_sec * 1000000000ull + t.tv_nsec;
|
||||
|
||||
for (uint32_t i = 0; i < info->count; i++) {
|
||||
assert(info->query + i < info->pool->query_count);
|
||||
struct v3dv_query *query = &info->pool->queries[info->query + i];
|
||||
query->maybe_available = true;
|
||||
if (i == 0)
|
||||
query->value = t.tv_sec * 1000000000ull + t.tv_nsec;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue