v3dv: push/pop more state during meta operations
Since a meta partial clear starts a new render pass, we need to store all state that can be changed with vkCmdBeginRenderPass. Also, since the meta clear pipeline sets dynamic state, we also have to restore that. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
committed by
Marge Bot
parent
dedff7446a
commit
debdea6cb5
@@ -2680,13 +2680,37 @@ v3dv_cmd_buffer_meta_state_push(struct v3dv_cmd_buffer *cmd_buffer)
|
||||
state->meta.framebuffer = v3dv_framebuffer_to_handle(state->framebuffer);
|
||||
state->meta.pass = v3dv_render_pass_to_handle(state->pass);
|
||||
state->meta.subpass_idx = state->subpass_idx;
|
||||
|
||||
const uint32_t attachment_state_item_size =
|
||||
sizeof(struct v3dv_cmd_buffer_attachment_state);
|
||||
const uint32_t attachment_state_total_size =
|
||||
attachment_state_item_size * state->attachment_count;
|
||||
if (state->meta.attachment_alloc_count < state->attachment_count) {
|
||||
if (state->meta.attachment_alloc_count > 0)
|
||||
vk_free(&cmd_buffer->device->alloc, state->meta.attachments);
|
||||
|
||||
state->meta.attachments = vk_zalloc(&cmd_buffer->device->alloc,
|
||||
attachment_state_total_size, 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
state->meta.attachment_alloc_count = state->attachment_count;
|
||||
}
|
||||
state->meta.attachment_count = state->attachment_count;
|
||||
memcpy(state->meta.attachments, state->attachments,
|
||||
attachment_state_total_size);
|
||||
|
||||
state->meta.tile_aligned_render_area = state->tile_aligned_render_area;
|
||||
memcpy(&state->meta.render_area, &state->render_area, sizeof(VkRect2D));
|
||||
|
||||
if (state->meta.pipeline)
|
||||
memcpy(&state->meta.dynamic, &state->dynamic, sizeof(state->dynamic));
|
||||
}
|
||||
|
||||
/* This resstores command buffer state for a subpass that we interrupted to
|
||||
* emit a meta pass.
|
||||
*/
|
||||
void
|
||||
v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer)
|
||||
v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
uint32_t dirty_dynamic_state)
|
||||
{
|
||||
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
|
||||
assert(state->meta.subpass_idx != -1);
|
||||
@@ -2694,6 +2718,18 @@ v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer)
|
||||
state->pass = v3dv_render_pass_from_handle(state->meta.pass);
|
||||
state->framebuffer = v3dv_framebuffer_from_handle(state->meta.framebuffer);
|
||||
|
||||
assert(state->meta.attachment_count <= state->attachment_count);
|
||||
const uint32_t attachment_state_item_size =
|
||||
sizeof(struct v3dv_cmd_buffer_attachment_state);
|
||||
const uint32_t attachment_state_total_size =
|
||||
attachment_state_item_size * state->meta.attachment_count;
|
||||
state->attachment_count = state->meta.attachment_count;
|
||||
memcpy(state->attachments, state->meta.attachments,
|
||||
attachment_state_total_size);
|
||||
|
||||
state->tile_aligned_render_area = state->meta.tile_aligned_render_area;
|
||||
memcpy(&state->render_area, &state->meta.render_area, sizeof(VkRect2D));
|
||||
|
||||
struct v3dv_job *job =
|
||||
v3dv_cmd_buffer_subpass_start(cmd_buffer, state->meta.subpass_idx);
|
||||
if (job) {
|
||||
@@ -2702,6 +2738,8 @@ v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer)
|
||||
v3dv_CmdBindPipeline(v3dv_cmd_buffer_to_handle(cmd_buffer),
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
state->meta.pipeline);
|
||||
memcpy(&state->dynamic, &state->meta.dynamic, sizeof(state->dynamic));
|
||||
state->dirty |= dirty_dynamic_state;
|
||||
} else {
|
||||
state->pipeline = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
@@ -524,6 +524,7 @@ emit_color_clear_rect(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
* for each selected layer of the attachment and then renders a scissored
|
||||
* quad in the clear color.
|
||||
*/
|
||||
uint32_t dirty_dynamic_state = 0;
|
||||
for (uint32_t i = 0; i < rect->layerCount; i++) {
|
||||
attachment_layer_view.first_layer =
|
||||
subpass_fb->attachments[rt_idx]->first_layer + rect->baseArrayLayer + i;
|
||||
@@ -598,8 +599,13 @@ emit_color_clear_rect(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
v3dv_DestroyFramebuffer(device_handle, fb, &cmd_buffer->device->alloc);
|
||||
}
|
||||
|
||||
/* The clear pipeline sets viewport and scissor state, so we need
|
||||
* to restore it
|
||||
*/
|
||||
dirty_dynamic_state = V3DV_CMD_DIRTY_VIEWPORT | V3DV_CMD_DIRTY_SCISSOR;
|
||||
|
||||
fail_job_start:
|
||||
v3dv_cmd_buffer_meta_state_pop(cmd_buffer);
|
||||
v3dv_cmd_buffer_meta_state_pop(cmd_buffer, dirty_dynamic_state);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -725,6 +725,15 @@ struct v3dv_cmd_buffer_state {
|
||||
VkRenderPass pass;
|
||||
VkPipeline pipeline;
|
||||
VkFramebuffer framebuffer;
|
||||
|
||||
uint32_t attachment_alloc_count;
|
||||
uint32_t attachment_count;
|
||||
struct v3dv_cmd_buffer_attachment_state *attachments;
|
||||
|
||||
bool tile_aligned_render_area;
|
||||
VkRect2D render_area;
|
||||
|
||||
struct v3dv_dynamic_state dynamic;
|
||||
} meta;
|
||||
};
|
||||
|
||||
@@ -786,7 +795,8 @@ struct v3dv_job *v3dv_cmd_buffer_subpass_start(struct v3dv_cmd_buffer *cmd_buffe
|
||||
void v3dv_cmd_buffer_subpass_finish(struct v3dv_cmd_buffer *cmd_buffer);
|
||||
|
||||
void v3dv_cmd_buffer_meta_state_push(struct v3dv_cmd_buffer *cmd_buffer);
|
||||
void v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer);
|
||||
void v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
uint32_t dirty_dynamic_state);
|
||||
|
||||
void v3dv_render_pass_setup_render_target(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
int rt,
|
||||
|
||||
Reference in New Issue
Block a user