From d8a3473cf314f1acbf8d3106df1d0edea74518ec Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 27 Jul 2022 10:06:50 +0200 Subject: [PATCH] v3dv: add a v3dv_job_allocate_tile_state helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we enable double-buffer we are reducing the tile size, and thus, we'll need more tiles and a larger tile state allocation, so we'll need to call to this helper. Reviewed-by: Alejandro PiƱeiro Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 68 ++++++++++++++------------- src/broadcom/vulkan/v3dv_private.h | 11 +++++ 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 93c332a4068..9983879f3a9 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -412,36 +412,12 @@ job_compute_frame_tiling(struct v3dv_job *job, return tiling; } -void -v3dv_job_start_frame(struct v3dv_job *job, - uint32_t width, - uint32_t height, - uint32_t layers, - bool allocate_tile_state_for_all_layers, - uint32_t render_target_count, - uint8_t max_internal_bpp, - bool msaa) +bool +v3dv_job_allocate_tile_state(struct v3dv_job *job) { - assert(job); - - /* Start by computing frame tiling spec for this job */ - const struct v3dv_frame_tiling *tiling = - job_compute_frame_tiling(job, - width, height, layers, - render_target_count, max_internal_bpp, msaa); - - v3dv_cl_ensure_space_with_branch(&job->bcl, 256); - v3dv_return_if_oom(NULL, job); - - /* We only need to allocate tile state for all layers if the binner - * writes primitives to layers other than the first. This can only be - * done using layered rendering (writing gl_Layer from a geometry shader), - * so for other cases of multilayered framebuffers (typically with - * meta copy/clear operations) that won't use layered rendering, we only - * need one layer worth of of tile state for the binner. - */ - if (!allocate_tile_state_for_all_layers) - layers = 1; + struct v3dv_frame_tiling *tiling = &job->frame_tiling; + const uint32_t layers = + job->allocate_tile_state_for_all_layers ? tiling->layers : 1; /* The PTB will request the tile alloc initial size per tile at start * of tile binning. @@ -469,7 +445,7 @@ v3dv_job_start_frame(struct v3dv_job *job, "tile_alloc", true); if (!job->tile_alloc) { v3dv_flag_oom(NULL, job); - return; + return false; } v3dv_job_add_bo_unchecked(job, job->tile_alloc); @@ -482,12 +458,40 @@ v3dv_job_start_frame(struct v3dv_job *job, job->tile_state = v3dv_bo_alloc(job->device, tile_state_size, "TSDA", true); if (!job->tile_state) { v3dv_flag_oom(NULL, job); - return; + return false; } v3dv_job_add_bo_unchecked(job, job->tile_state); + return true; +} - v3dv_X(job->device, job_emit_binning_prolog)(job, tiling, layers); +void +v3dv_job_start_frame(struct v3dv_job *job, + uint32_t width, + uint32_t height, + uint32_t layers, + bool allocate_tile_state_for_all_layers, + uint32_t render_target_count, + uint8_t max_internal_bpp, + bool msaa) +{ + assert(job); + + /* Start by computing frame tiling spec for this job */ + const struct v3dv_frame_tiling *tiling = + job_compute_frame_tiling(job, + width, height, layers, + render_target_count, max_internal_bpp, msaa); + + v3dv_cl_ensure_space_with_branch(&job->bcl, 256); + 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; + + v3dv_X(job->device, job_emit_binning_prolog)(job, tiling, + allocate_tile_state_for_all_layers ? tiling->layers : 1); job->ez_state = V3D_EZ_UNDECIDED; job->first_ez_state = V3D_EZ_UNDECIDED; diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 1ad0731ce71..efb4e57fbcd 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -1086,6 +1086,15 @@ struct v3dv_job { */ bool can_use_double_buffer; + /* We only need to allocate tile state for all layers if the binner + * writes primitives to layers other than the first. This can only be + * done using layered rendering (writing gl_Layer from a geometry shader), + * so for other cases of multilayered framebuffers (typically with + * meta copy/clear operations) that won't use layered rendering, we only + * need one layer worth of of tile state for the binner. + */ + bool allocate_tile_state_for_all_layers; + enum v3dv_job_type type; struct v3dv_device *device; @@ -1219,6 +1228,8 @@ v3dv_cmd_buffer_ensure_array_state(struct v3dv_cmd_buffer *cmd_buffer, void v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer, bool indexed, bool indirect); +bool v3dv_job_allocate_tile_state(struct v3dv_job *job); + /* FIXME: only used on v3dv_cmd_buffer and v3dvx_cmd_buffer, perhaps move to a * cmd_buffer specific header? */