diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 9983879f3a9..6e60204148e 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -471,6 +471,7 @@ v3dv_job_start_frame(struct v3dv_job *job, uint32_t height, uint32_t layers, bool allocate_tile_state_for_all_layers, + bool allocate_tile_state_now, uint32_t render_target_count, uint8_t max_internal_bpp, bool msaa) @@ -487,8 +488,14 @@ v3dv_job_start_frame(struct v3dv_job *job, v3dv_return_if_oom(NULL, job); job->allocate_tile_state_for_all_layers = allocate_tile_state_for_all_layers; - if (!v3dv_job_allocate_tile_state(job)) - return; + + /* For subpass jobs we postpone tile state allocation until we are finishing + * the job and have made a decision about double-buffer. + */ + if (allocate_tile_state_now) { + if (!v3dv_job_allocate_tile_state(job)) + return; + } v3dv_X(job->device, job_emit_binning_prolog)(job, tiling, allocate_tile_state_for_all_layers ? tiling->layers : 1); @@ -500,7 +507,8 @@ v3dv_job_start_frame(struct v3dv_job *job, static void cmd_buffer_end_render_pass_frame(struct v3dv_cmd_buffer *cmd_buffer) { - assert(cmd_buffer->state.job); + struct v3dv_job *job = cmd_buffer->state.job; + assert(job); /* Typically, we have a single job for each subpass and we emit the job's RCL * here when we are ending the frame for the subpass. However, some commands @@ -510,10 +518,17 @@ cmd_buffer_end_render_pass_frame(struct v3dv_cmd_buffer *cmd_buffer) * those jobs, so we only emit the subpass RCL if the job has not recorded * any RCL commands of its own. */ - if (v3dv_cl_offset(&cmd_buffer->state.job->rcl) == 0) - v3dv_X(cmd_buffer->device, cmd_buffer_emit_render_pass_rcl)(cmd_buffer); + if (v3dv_cl_offset(&job->rcl) == 0) { + /* At this point we have decided whether we want to use double-buffer or + * not and the job's frame tiling represents that decision so we can + * allocate the tile state, which we need to do before we emit the RCL. + */ + v3dv_job_allocate_tile_state(job); - v3dv_X(cmd_buffer->device, job_emit_binning_flush)(cmd_buffer->state.job); + v3dv_X(cmd_buffer->device, cmd_buffer_emit_render_pass_rcl)(cmd_buffer); + } + + v3dv_X(cmd_buffer->device, job_emit_binning_flush)(job); } struct v3dv_job * @@ -1629,7 +1644,7 @@ cmd_buffer_subpass_create_job(struct v3dv_cmd_buffer *cmd_buffer, framebuffer->width, framebuffer->height, layers, - true, + true, false, subpass->color_count, internal_bpp, msaa); @@ -2593,7 +2608,7 @@ cmd_buffer_restart_job_for_msaa_if_needed(struct v3dv_cmd_buffer *cmd_buffer) old_job->frame_tiling.width, old_job->frame_tiling.height, old_job->frame_tiling.layers, - true, + true, false, old_job->frame_tiling.render_target_count, old_job->frame_tiling.internal_bpp, true /* msaa */); diff --git a/src/broadcom/vulkan/v3dv_meta_clear.c b/src/broadcom/vulkan/v3dv_meta_clear.c index 5521bdc9803..889555fb5cd 100644 --- a/src/broadcom/vulkan/v3dv_meta_clear.c +++ b/src/broadcom/vulkan/v3dv_meta_clear.c @@ -119,8 +119,8 @@ clear_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, if (!job) return true; - v3dv_job_start_frame(job, width, height, max_layer, false, - 1, internal_bpp, + v3dv_job_start_frame(job, width, height, max_layer, + false, true, 1, internal_bpp, image->vk.samples > VK_SAMPLE_COUNT_1_BIT); struct v3dv_meta_framebuffer framebuffer; diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c index 67184aa8142..437a86d85d3 100644 --- a/src/broadcom/vulkan/v3dv_meta_copy.c +++ b/src/broadcom/vulkan/v3dv_meta_copy.c @@ -407,7 +407,7 @@ copy_image_to_buffer_tlb(struct v3dv_cmd_buffer *cmd_buffer, const uint32_t width = DIV_ROUND_UP(region->imageExtent.width, block_w); const uint32_t height = DIV_ROUND_UP(region->imageExtent.height, block_h); - v3dv_job_start_frame(job, width, height, num_layers, false, + v3dv_job_start_frame(job, width, height, num_layers, false, true, 1, internal_bpp, false); struct v3dv_meta_framebuffer framebuffer; @@ -948,7 +948,8 @@ copy_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, const uint32_t width = DIV_ROUND_UP(region->extent.width, block_w); const uint32_t height = DIV_ROUND_UP(region->extent.height, block_h); - v3dv_job_start_frame(job, width, height, num_layers, false, 1, internal_bpp, + v3dv_job_start_frame(job, width, height, num_layers, + false, true, 1, internal_bpp, src->vk.samples > VK_SAMPLE_COUNT_1_BIT); struct v3dv_meta_framebuffer framebuffer; @@ -1448,7 +1449,7 @@ copy_buffer_to_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, const uint32_t width = DIV_ROUND_UP(region->imageExtent.width, block_w); const uint32_t height = DIV_ROUND_UP(region->imageExtent.height, block_h); - v3dv_job_start_frame(job, width, height, num_layers, false, + v3dv_job_start_frame(job, width, height, num_layers, false, true, 1, internal_bpp, false); struct v3dv_meta_framebuffer framebuffer; @@ -4288,7 +4289,7 @@ resolve_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, (fb_format, region->srcSubresource.aspectMask, &internal_type, &internal_bpp); - v3dv_job_start_frame(job, width, height, num_layers, false, + v3dv_job_start_frame(job, width, height, num_layers, false, true, 1, internal_bpp, true); struct v3dv_meta_framebuffer framebuffer; diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index efb4e57fbcd..8e1fe34c0b7 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -1203,6 +1203,7 @@ void v3dv_job_start_frame(struct v3dv_job *job, uint32_t height, uint32_t layers, bool allocate_tile_state_for_all_layers, + bool allocate_tile_state_now, uint32_t render_target_count, uint8_t max_internal_bpp, bool msaa); diff --git a/src/broadcom/vulkan/v3dvx_meta_common.c b/src/broadcom/vulkan/v3dvx_meta_common.c index 4e685635ed0..52a1dea4d62 100644 --- a/src/broadcom/vulkan/v3dvx_meta_common.c +++ b/src/broadcom/vulkan/v3dvx_meta_common.c @@ -1274,7 +1274,8 @@ v3dX(meta_copy_buffer)(struct v3dv_cmd_buffer *cmd_buffer, uint32_t width, height; framebuffer_size_for_pixel_count(num_items, &width, &height); - v3dv_job_start_frame(job, width, height, 1, true, 1, internal_bpp, false); + v3dv_job_start_frame(job, width, height, 1, true, true, + 1, internal_bpp, false); struct v3dv_meta_framebuffer framebuffer; v3dX(meta_framebuffer_init)(&framebuffer, vk_format, internal_type, @@ -1320,7 +1321,8 @@ v3dX(meta_fill_buffer)(struct v3dv_cmd_buffer *cmd_buffer, uint32_t width, height; framebuffer_size_for_pixel_count(num_items, &width, &height); - v3dv_job_start_frame(job, width, height, 1, true, 1, internal_bpp, false); + v3dv_job_start_frame(job, width, height, 1, true, true, + 1, internal_bpp, false); struct v3dv_meta_framebuffer framebuffer; v3dX(meta_framebuffer_init)(&framebuffer, VK_FORMAT_R8G8B8A8_UINT, diff --git a/src/broadcom/vulkan/v3dvx_queue.c b/src/broadcom/vulkan/v3dvx_queue.c index 54b0b1ca5db..efe63de425c 100644 --- a/src/broadcom/vulkan/v3dvx_queue.c +++ b/src/broadcom/vulkan/v3dvx_queue.c @@ -29,7 +29,7 @@ void v3dX(job_emit_noop)(struct v3dv_job *job) { - v3dv_job_start_frame(job, 1, 1, 1, true, 1, V3D_INTERNAL_BPP_32, false); + v3dv_job_start_frame(job, 1, 1, 1, true, true, 1, V3D_INTERNAL_BPP_32, false); v3dX(job_emit_binning_flush)(job); struct v3dv_cl *rcl = &job->rcl;