From 44cda4dbfe50dc65107fc8da64b3da51ad086032 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Mon, 2 Mar 2020 12:08:19 +0100 Subject: [PATCH] v3dv: fix subpass tracking in the command buffer state When we create a new job for a new subpass, we might have to finish the current job for the previous subpass, so it is important that we we don't get ahead of ourselves and increment the current subpass index in the command buffer state until we are really done finishing the previous job. Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 29 ++++++++++++++++----------- src/broadcom/vulkan/v3dv_meta_copy.c | 12 +++++------ src/broadcom/vulkan/v3dv_private.h | 2 +- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index d1c48784259..fe53eadeb7f 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -72,7 +72,7 @@ v3dv_job_add_extra_bo(struct v3dv_job *job, struct v3dv_bo *bo) } static void -subpass_start(struct v3dv_cmd_buffer *cmd_buffer); +subpass_start(struct v3dv_cmd_buffer *cmd_buffer, uint32_t subpass_idx); static void subpass_finish(struct v3dv_cmd_buffer *cmd_buffer); @@ -397,13 +397,13 @@ v3dv_cmd_buffer_finish_job(struct v3dv_cmd_buffer *cmd_buffer) struct v3dv_job * v3dv_cmd_buffer_start_job(struct v3dv_cmd_buffer *cmd_buffer, - bool is_subpass_start) + int32_t subpass_idx) { /* Don't create a new job if we can merge the current subpass into * the current job. */ if (cmd_buffer->state.pass && - is_subpass_start && + subpass_idx != -1 && cmd_buffer_can_merge_subpass(cmd_buffer)) { cmd_buffer->state.job->is_subpass_finish = false; return cmd_buffer->state.job; @@ -442,9 +442,10 @@ v3dv_cmd_buffer_start_job(struct v3dv_cmd_buffer *cmd_buffer, * and stores. */ if (cmd_buffer->state.pass) - job->first_subpass = cmd_buffer->state.subpass_idx; + job->first_subpass = subpass_idx; cmd_buffer->state.job = job; + return job; } @@ -759,8 +760,7 @@ v3dv_CmdBeginRenderPass(VkCommandBuffer commandBuffer, state->render_area = pRenderPassBegin->renderArea; /* Setup for first subpass */ - state->subpass_idx = 0; - subpass_start(cmd_buffer); + subpass_start(cmd_buffer, 0); } void @@ -775,8 +775,7 @@ v3dv_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) subpass_finish(cmd_buffer); /* Start the next subpass */ - state->subpass_idx++; - subpass_start(cmd_buffer); + subpass_start(cmd_buffer, state->subpass_idx + 1); } void @@ -1390,13 +1389,19 @@ cmd_buffer_emit_render_pass_rcl(struct v3dv_cmd_buffer *cmd_buffer) } static void -subpass_start(struct v3dv_cmd_buffer *cmd_buffer) +subpass_start(struct v3dv_cmd_buffer *cmd_buffer, uint32_t subpass_idx) { - const struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; + struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; + assert(subpass_idx < state->pass->subpass_count); - assert(state->subpass_idx < state->pass->subpass_count); + /* Starting a new job can trigger a finish of the current one, so don't + * change the command buffer state for the new job until we are done creating + * the new job. + */ + struct v3dv_job *job = + v3dv_cmd_buffer_start_job(cmd_buffer, subpass_idx); - struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, true); + state->subpass_idx = subpass_idx; /* If we are starting a new job we need to setup binning. */ if (job->first_subpass == state->subpass_idx) diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c index 6c18b17e37a..17dd57675bd 100644 --- a/src/broadcom/vulkan/v3dv_meta_copy.c +++ b/src/broadcom/vulkan/v3dv_meta_copy.c @@ -680,7 +680,7 @@ copy_image_to_buffer_tlb(struct v3dv_cmd_buffer *cmd_buffer, framebuffer.max_x_supertile = max_render_x / supertile_w_in_pixels; framebuffer.max_y_supertile = max_render_y / supertile_h_in_pixels; - struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, false); + struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1); v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb); v3dv_job_emit_binning_flush(job); @@ -834,7 +834,7 @@ copy_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, framebuffer.max_x_supertile = max_render_x / supertile_w_in_pixels; framebuffer.max_y_supertile = max_render_y / supertile_h_in_pixels; - struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, false); + struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1); v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb); v3dv_job_emit_binning_flush(job); @@ -966,7 +966,7 @@ clear_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, setup_framebuffer_params(&framebuffer, width, height, 1, internal_bpp, internal_type); - struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, false); + struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1); v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb); v3dv_job_emit_binning_flush(job); @@ -1171,7 +1171,7 @@ copy_buffer(struct v3dv_cmd_buffer *cmd_buffer, setup_framebuffer_for_pixel_count(&framebuffer, num_items, internal_bpp, internal_type); - job = v3dv_cmd_buffer_start_job(cmd_buffer, false); + job = v3dv_cmd_buffer_start_job(cmd_buffer, -1); v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb); v3dv_job_emit_binning_flush(job); @@ -1327,7 +1327,7 @@ fill_buffer(struct v3dv_cmd_buffer *cmd_buffer, setup_framebuffer_for_pixel_count(&framebuffer, num_items, internal_bpp, internal_type); - struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, false); + struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1); v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb); v3dv_job_emit_binning_flush(job); @@ -1531,7 +1531,7 @@ copy_buffer_to_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, framebuffer.max_x_supertile = max_render_x / supertile_w_in_pixels; framebuffer.max_y_supertile = max_render_y / supertile_h_in_pixels; - struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, false); + struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1); v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb); v3dv_job_emit_binning_flush(job); diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index fa55127bfd4..9ceb4b9de1f 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -633,7 +633,7 @@ struct v3dv_cmd_buffer { }; struct v3dv_job *v3dv_cmd_buffer_start_job(struct v3dv_cmd_buffer *cmd_buffer, - bool is_subpass_finish); + int32_t subpass_idx); void v3dv_cmd_buffer_finish_job(struct v3dv_cmd_buffer *cmd_buffer); void v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer, const struct v3dv_framebuffer *framebuffer);