From: Iago Toral Quiroga Date: Fri, 3 Apr 2020 07:41:45 +0000 (+0200) Subject: v3dv: push/pop more state during meta operations X-Git-Tag: upstream/21.0.0~4022 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=debdea6cb5f02e0511f3370e8295a71095fb79c6;p=platform%2Fupstream%2Fmesa.git 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: --- diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 525a85e..520253d 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -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; } diff --git a/src/broadcom/vulkan/v3dv_meta_clear.c b/src/broadcom/vulkan/v3dv_meta_clear.c index 622fed2..a37d443 100644 --- a/src/broadcom/vulkan/v3dv_meta_clear.c +++ b/src/broadcom/vulkan/v3dv_meta_clear.c @@ -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 diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 25f81c9..481d957 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -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,