tu: Implement multiview query interactions
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5720>
This commit is contained in:
@@ -76,7 +76,7 @@ struct PACKED primitive_query_slot {
|
||||
/* Returns the IOVA of a given uint64_t field in a given slot of a query
|
||||
* pool. */
|
||||
#define query_iova(type, pool, query, field, value_index) \
|
||||
pool->bo.iova + pool->stride * query + offsetof(type, field) + \
|
||||
pool->bo.iova + pool->stride * (query) + offsetof(type, field) + \
|
||||
offsetof(struct slot_value, values[value_index])
|
||||
|
||||
#define occlusion_query_iova(pool, query, field) \
|
||||
@@ -726,6 +726,44 @@ emit_end_xfb_query(struct tu_cmd_buffer *cmdbuf,
|
||||
tu_cs_emit_qw(cs, 0x1);
|
||||
}
|
||||
|
||||
/* Implement this bit of spec text from section 17.2 "Query Operation":
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Since we execute all views at once, we write zero to the other queries.
|
||||
* Furthermore, because queries must be reset before use, and we set the
|
||||
* result to 0 in vkCmdResetQueryPool(), we just need to mark it as available.
|
||||
*/
|
||||
|
||||
static void
|
||||
handle_multiview_queries(struct tu_cmd_buffer *cmd,
|
||||
struct tu_query_pool *pool,
|
||||
uint32_t query)
|
||||
{
|
||||
if (!cmd->state.pass || !cmd->state.subpass->multiview_mask)
|
||||
return;
|
||||
|
||||
unsigned views = util_bitcount(cmd->state.subpass->multiview_mask);
|
||||
struct tu_cs *cs = &cmd->draw_epilogue_cs;
|
||||
|
||||
for (uint32_t i = 1; i < views; i++) {
|
||||
tu_cs_emit_pkt7(cs, CP_MEM_WRITE, 4);
|
||||
tu_cs_emit_qw(cs, query_available_iova(pool, query + i));
|
||||
tu_cs_emit_qw(cs, 0x1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tu_CmdEndQuery(VkCommandBuffer commandBuffer,
|
||||
VkQueryPool queryPool,
|
||||
@@ -749,6 +787,8 @@ tu_CmdEndQuery(VkCommandBuffer commandBuffer,
|
||||
assert(!"Invalid query type");
|
||||
}
|
||||
|
||||
handle_multiview_queries(cmdbuf, pool, query);
|
||||
|
||||
tu_bo_list_add(&cmdbuf->bo_list, &pool->bo, MSM_SUBMIT_BO_WRITE);
|
||||
}
|
||||
|
||||
@@ -825,4 +865,31 @@ tu_CmdWriteTimestamp(VkCommandBuffer commandBuffer,
|
||||
tu_cs_emit_pkt7(cs, CP_MEM_WRITE, 4);
|
||||
tu_cs_emit_qw(cs, query_available_iova(pool, query));
|
||||
tu_cs_emit_qw(cs, 0x1);
|
||||
|
||||
/* From the spec for vkCmdWriteTimestamp:
|
||||
*
|
||||
* If vkCmdWriteTimestamp is called while executing a render pass
|
||||
* instance that has multiview enabled, the timestamp uses N consecutive
|
||||
* query indices in the query pool (starting at query) where N is the
|
||||
* number of bits set in the view mask of the subpass the command is
|
||||
* executed in. The resulting query values are determined by an
|
||||
* implementation-dependent choice of one of the following behaviors:
|
||||
*
|
||||
* - The first query is a timestamp value and (if more than one bit is
|
||||
* set in the view mask) zero is written to the remaining queries.
|
||||
* If two timestamps are written in the same subpass, the sum of the
|
||||
* execution time of all views between those commands is the
|
||||
* difference between the first query written by each command.
|
||||
*
|
||||
* - All N queries are timestamp values. If two timestamps are written
|
||||
* in the same subpass, the sum of the execution time of all views
|
||||
* between those commands is the sum of the difference between
|
||||
* corresponding queries written by each command. The difference
|
||||
* between corresponding queries may be the execution time of a
|
||||
* single view.
|
||||
*
|
||||
* We execute all views in the same draw call, so we implement the first
|
||||
* option, the same as regular queries.
|
||||
*/
|
||||
handle_multiview_queries(cmd, pool, query);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user