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:
Iago Toral Quiroga
2020-04-03 09:41:45 +02:00
committed by Marge Bot
parent dedff7446a
commit debdea6cb5
3 changed files with 57 additions and 3 deletions
+39 -1
View File
@@ -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;
}
+7 -1
View File
@@ -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
+11 -1
View File
@@ -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,