venus: refactor more cmd states into cmd builder

This change:
- adds helpers for cmd begin/end rendering
- simplifies cmd reset
- updates ordering to align with cmd builder

Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24103>
This commit is contained in:
Yiwei Zhang
2023-07-11 19:49:43 -07:00
committed by Marge Bot
parent 10c791619c
commit e47da97be6
2 changed files with 95 additions and 90 deletions
+75 -72
View File
@@ -536,7 +536,7 @@ vn_cmd_query_batch_push(struct vn_command_buffer *cmd,
batch->query_pool = query_pool;
batch->query = query;
batch->query_count = query_count;
list_add(&batch->head, &cmd->query_batches);
list_add(&batch->head, &cmd->builder.query_batches);
return true;
}
@@ -552,7 +552,7 @@ static void
vn_cmd_record_batched_query_feedback(struct vn_command_buffer *cmd)
{
list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
&cmd->query_batches, head) {
&cmd->builder.query_batches, head) {
vn_feedback_query_cmd_record(vn_command_buffer_to_handle(cmd),
vn_query_pool_to_handle(batch->query_pool),
batch->query, batch->query_count, true);
@@ -566,8 +566,8 @@ vn_cmd_merge_batched_query_feedback(struct vn_command_buffer *primary_cmd,
struct vn_command_buffer *secondary_cmd)
{
list_for_each_entry_safe(struct vn_command_buffer_query_batch,
secondary_batch, &secondary_cmd->query_batches,
head) {
secondary_batch,
&secondary_cmd->builder.query_batches, head) {
if (!vn_cmd_query_batch_push(primary_cmd, secondary_batch->query_pool,
secondary_batch->query,
secondary_batch->query_count)) {
@@ -587,10 +587,9 @@ vn_cmd_begin_render_pass(struct vn_command_buffer *cmd,
assert(cmd->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
cmd->builder.render_pass = pass;
cmd->in_render_pass = true;
cmd->subpass_index = 0;
cmd->view_mask = vn_render_pass_get_subpass_view_mask(pass, 0);
cmd->builder.in_render_pass = true;
cmd->builder.subpass_index = 0;
cmd->builder.view_mask = vn_render_pass_get_subpass_view_mask(pass, 0);
if (!pass->present_count)
return;
@@ -638,12 +637,12 @@ vn_cmd_end_render_pass(struct vn_command_buffer *cmd)
{
const struct vn_render_pass *pass = cmd->builder.render_pass;
cmd->builder.render_pass = NULL;
vn_cmd_record_batched_query_feedback(cmd);
cmd->in_render_pass = false;
cmd->subpass_index = 0;
cmd->view_mask = 0;
cmd->builder.render_pass = NULL;
cmd->builder.in_render_pass = false;
cmd->builder.subpass_index = 0;
cmd->builder.view_mask = 0;
if (!pass->present_count || !cmd->builder.present_src_images)
return;
@@ -663,8 +662,43 @@ vn_cmd_end_render_pass(struct vn_command_buffer *cmd)
static inline void
vn_cmd_next_subpass(struct vn_command_buffer *cmd)
{
cmd->view_mask = vn_render_pass_get_subpass_view_mask(
cmd->builder.render_pass, ++cmd->subpass_index);
cmd->builder.view_mask = vn_render_pass_get_subpass_view_mask(
cmd->builder.render_pass, ++cmd->builder.subpass_index);
}
static inline void
vn_cmd_begin_rendering(struct vn_command_buffer *cmd,
const VkRenderingInfo *rendering_info)
{
cmd->builder.in_render_pass = true;
cmd->builder.suspending =
rendering_info->flags & VK_RENDERING_SUSPENDING_BIT;
cmd->builder.view_mask = rendering_info->viewMask;
}
static inline void
vn_cmd_end_rendering(struct vn_command_buffer *cmd)
{
/* XXX query feedback is broken for suspended render pass instance
*
* If resume occurs in a different cmd (only needed for parallel render
* pass recording), the batched query feedbacks here are never recorded.
* Query result retrieval will end up with device lost.
*
* In practice, explicit query usages within the suspended render pass
* instance is a minor (not seeing any so far). Will fix once hit. The
* potential options are:
* - doing a synchronous query pool results retrieval as a fallback
* - store the deferred query feedback in a cmd and inject upon submit
*/
if (!cmd->builder.suspending)
vn_cmd_record_batched_query_feedback(cmd);
else
vn_log(cmd->pool->device->instance, "query dropped by suspended pass");
cmd->builder.in_render_pass = false;
cmd->builder.suspending = false;
cmd->builder.view_mask = 0;
}
/* command pool commands */
@@ -734,7 +768,7 @@ vn_DestroyCommandPool(VkDevice device,
vk_free(alloc, cmd->builder.present_src_images);
list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
&cmd->query_batches, head)
&cmd->builder.query_batches, head)
vk_free(alloc, batch);
vk_free(alloc, cmd);
@@ -756,22 +790,19 @@ vn_cmd_reset(struct vn_command_buffer *cmd)
{
vn_cs_encoder_reset(&cmd->cs);
cmd->builder.render_pass = NULL;
if (cmd->builder.present_src_images) {
vk_free(&cmd->pool->allocator, cmd->builder.present_src_images);
cmd->builder.present_src_images = NULL;
}
cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
cmd->draw_cmd_batched = 0;
cmd->in_render_pass = false;
cmd->suspends = false;
cmd->subpass_index = 0;
cmd->view_mask = 0;
if (cmd->builder.present_src_images)
vk_free(&cmd->pool->allocator, cmd->builder.present_src_images);
list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
&cmd->query_batches, head)
&cmd->builder.query_batches, head)
vn_cmd_query_batch_pop(cmd, batch);
memset(&cmd->builder, 0, sizeof(cmd->builder));
list_inithead(&cmd->builder.query_batches);
}
VkResult
@@ -837,14 +868,13 @@ vn_AllocateCommandBuffers(VkDevice device,
&dev->base);
cmd->pool = pool;
cmd->level = pAllocateInfo->level;
list_addtail(&cmd->head, &pool->command_buffers);
cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
vn_cs_encoder_init(&cmd->cs, dev->instance,
VN_CS_ENCODER_STORAGE_SHMEM_POOL, 16 * 1024);
list_inithead(&cmd->query_batches);
list_inithead(&cmd->builder.query_batches);
list_addtail(&cmd->head, &pool->command_buffers);
VkCommandBuffer cmd_handle = vn_command_buffer_to_handle(cmd);
pCommandBuffers[i] = cmd_handle;
@@ -877,14 +907,14 @@ vn_FreeCommandBuffers(VkDevice device,
if (!cmd)
continue;
if (cmd->builder.present_src_images)
vk_free(alloc, cmd->builder.present_src_images);
vn_cs_encoder_fini(&cmd->cs);
list_del(&cmd->head);
if (cmd->builder.present_src_images)
vk_free(alloc, cmd->builder.present_src_images);
list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
&cmd->query_batches, head)
&cmd->builder.query_batches, head)
vn_cmd_query_batch_pop(cmd, batch);
vn_object_base_fini(&cmd->base);
@@ -1035,7 +1065,7 @@ vn_BeginCommandBuffer(VkCommandBuffer commandBuffer,
pBeginInfo->pInheritanceInfo;
if (inheritance_info) {
cmd->in_render_pass = local_begin_info.in_render_pass;
cmd->builder.in_render_pass = local_begin_info.in_render_pass;
if (local_begin_info.has_inherited_pass) {
const struct vn_render_pass *pass =
vn_render_pass_from_handle(inheritance_info->renderPass);
@@ -1048,7 +1078,7 @@ vn_BeginCommandBuffer(VkCommandBuffer commandBuffer,
/* Store the viewMask from the inherited render pass subpass for
* query feedback.
*/
cmd->view_mask = vn_render_pass_get_subpass_view_mask(
cmd->builder.view_mask = vn_render_pass_get_subpass_view_mask(
pass, inheritance_info->subpass);
} else {
/* Store the viewMask from the
@@ -1060,7 +1090,7 @@ vn_BeginCommandBuffer(VkCommandBuffer commandBuffer,
COMMAND_BUFFER_INHERITANCE_RENDERING_INFO);
if (inheritance_rendering_info)
cmd->view_mask = inheritance_rendering_info->viewMask;
cmd->builder.view_mask = inheritance_rendering_info->viewMask;
}
}
@@ -1269,13 +1299,8 @@ void
vn_CmdBeginRendering(VkCommandBuffer commandBuffer,
const VkRenderingInfo *pRenderingInfo)
{
struct vn_command_buffer *cmd =
vn_command_buffer_from_handle(commandBuffer);
cmd->in_render_pass = true;
cmd->view_mask = pRenderingInfo->viewMask;
cmd->suspends = pRenderingInfo->flags & VK_RENDERING_SUSPENDING_BIT;
vn_cmd_begin_rendering(vn_command_buffer_from_handle(commandBuffer),
pRenderingInfo);
VN_CMD_ENQUEUE(vkCmdBeginRendering, commandBuffer, pRenderingInfo);
}
@@ -1283,31 +1308,9 @@ vn_CmdBeginRendering(VkCommandBuffer commandBuffer,
void
vn_CmdEndRendering(VkCommandBuffer commandBuffer)
{
struct vn_command_buffer *cmd =
vn_command_buffer_from_handle(commandBuffer);
VN_CMD_ENQUEUE(vkCmdEndRendering, commandBuffer);
/* XXX query feedback is broken for suspended render pass instance
*
* If resume occurs in a different cmd (only needed for parallel render
* pass recording), the batched query feedbacks here are never recorded.
* Query result retrieval will end up with device lost.
*
* In practice, explicit query usages within the suspended render pass
* instance is a minor (not seeing any so far). Will fix once hit. The
* potential options are:
* - doing a synchronous query pool results retrieval as a fallback
* - store the deferred query feedback in a cmd and inject upon submit
*/
if (!cmd->suspends)
vn_cmd_record_batched_query_feedback(cmd);
else
vn_log(cmd->pool->device->instance, "query dropped by suspended pass");
cmd->in_render_pass = false;
cmd->suspends = false;
cmd->view_mask = 0;
vn_cmd_end_rendering(vn_command_buffer_from_handle(commandBuffer));
}
void
@@ -1809,7 +1812,7 @@ vn_cmd_add_query_feedback(VkCommandBuffer cmd_handle,
/* Outside the render pass instance, vkCmdCopyQueryPoolResults can be
* directly appended. Otherwise, defer the copy cmd until outside.
*/
if (!cmd->in_render_pass) {
if (!cmd->builder.in_render_pass) {
vn_feedback_query_cmd_record(cmd_handle, pool_handle, query, 1, true);
return;
}
@@ -1824,7 +1827,7 @@ vn_cmd_add_query_feedback(VkCommandBuffer cmd_handle,
* bits set in the view mask in the subpass the query is used in."
*/
const uint32_t query_count =
cmd->view_mask ? util_bitcount(cmd->view_mask) : 1;
cmd->builder.view_mask ? util_bitcount(cmd->builder.view_mask) : 1;
if (!vn_cmd_query_batch_push(cmd, pool, query, query_count))
cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
}
@@ -1983,11 +1986,11 @@ vn_CmdExecuteCommands(VkCommandBuffer commandBuffer,
struct vn_command_buffer *primary_cmd =
vn_command_buffer_from_handle(commandBuffer);
if (primary_cmd->in_render_pass) {
if (primary_cmd->builder.in_render_pass) {
for (uint32_t i = 0; i < commandBufferCount; i++) {
struct vn_command_buffer *secondary_cmd =
vn_command_buffer_from_handle(pCommandBuffers[i]);
assert(secondary_cmd->in_render_pass);
assert(secondary_cmd->builder.in_render_pass);
vn_cmd_merge_batched_query_feedback(primary_cmd, secondary_cmd);
}
}
+20 -18
View File
@@ -48,39 +48,41 @@ enum vn_command_buffer_state {
VN_COMMAND_BUFFER_STATE_INVALID,
};
/* command buffer builder to:
* - fix wsi image ownership and layout transitions
* - scrub ignored bits in VkCommandBufferBeginInfo
* - support asynchronization query optimization (query feedback)
*/
struct vn_command_buffer_builder {
/* track the active legacy render pass */
const struct vn_render_pass *render_pass;
/* track the wsi images requiring layout fixes */
const struct vn_image **present_src_images;
/* track if inside a render pass instance */
bool in_render_pass;
/* track whether the active render pass instance is suspending */
bool suspending;
/* track the active subpass for view mask used in the subpass */
uint32_t subpass_index;
/* track the active view mask inside a render pass instance */
uint32_t view_mask;
/* track the query feedbacks deferred outside the render pass instance */
struct list_head query_batches;
};
struct vn_command_buffer {
struct vn_object_base base;
struct vn_command_pool *pool;
VkCommandBufferLevel level;
struct list_head head;
struct vn_command_buffer_builder builder;
enum vn_command_buffer_state state;
struct vn_cs_encoder cs;
uint32_t draw_cmd_batched;
/* For batching query feedback in render passes */
/* in_render_pass remains true when a render pass is suspended */
bool in_render_pass;
bool suspends;
/* viewMask is stored per subpass for legacy render pass */
uint32_t subpass_index;
/* view_mask is set when passed in by dynamic rendering/secondary cmd
* buffers or on each subpass iteration for legacy render pass with
* the above variables.
*/
uint32_t view_mask;
struct list_head query_batches;
struct vn_command_buffer_builder builder;
struct list_head head;
};
VK_DEFINE_HANDLE_CASTS(vn_command_buffer,
base.base,