diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 5fd8c16ce7c..17ae859f621 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -556,41 +556,23 @@ tu_cs_emit_draw_state(struct tu_cs *cs, uint32_t id, struct tu_draw_state state) tu_cs_emit_qw(cs, state.iova); } -static bool -is_hw_binning_possible(const struct tu_framebuffer *fb) -{ - /* Similar to older gens, # of tiles per pipe cannot be more than 32. - * But there are no hangs with 16 or more tiles per pipe in either - * X or Y direction, so that limit does not seem to apply. - */ - uint32_t tiles_per_pipe = fb->pipe0.width * fb->pipe0.height; - return tiles_per_pipe <= 32; -} - static bool use_hw_binning(struct tu_cmd_buffer *cmd) { const struct tu_framebuffer *fb = cmd->state.framebuffer; - /* XFB commands are emitted for BINNING || SYSMEM, which makes it incompatible - * with non-hw binning GMEM rendering. this is required because some of the - * XFB commands need to only be executed once + /* XFB commands are emitted for BINNING || SYSMEM, which makes it + * incompatible with non-hw binning GMEM rendering. this is required because + * some of the XFB commands need to only be executed once. + * use_sysmem_rendering() should have made sure we only ended up here if no + * XFB was used. */ if (cmd->state.xfb_used) { - assert(is_hw_binning_possible(fb)); + assert(fb->binning_possible); return true; } - if (!is_hw_binning_possible(fb)) - return false; - - if (unlikely(cmd->device->physical_device->instance->debug_flags & TU_DEBUG_NOBIN)) - return false; - - if (unlikely(cmd->device->physical_device->instance->debug_flags & TU_DEBUG_FORCEBIN)) - return true; - - return (fb->tile_count.width * fb->tile_count.height) > 2; + return fb->binning; } static bool @@ -619,7 +601,7 @@ use_sysmem_rendering(struct tu_cmd_buffer *cmd, return true; /* XFB is incompatible with non-hw binning GMEM rendering, see use_hw_binning */ - if (cmd->state.xfb_used && !is_hw_binning_possible(cmd->state.framebuffer)) + if (cmd->state.xfb_used && !cmd->state.framebuffer->binning_possible) return true; if (unlikely(cmd->device->physical_device->instance->debug_flags & TU_DEBUG_GMEM)) diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index 2c9f66b71e5..2e8110c93b2 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -1816,6 +1816,12 @@ struct tu_framebuffer /* number of VSC pipes */ VkExtent2D pipe_count; + /* Whether binning should be used for gmem rendering using this framebuffer. */ + bool binning; + + /* Whether binning could be used for gmem rendering using this framebuffer. */ + bool binning_possible; + /* pipe register values */ uint32_t pipe_config[MAX_VSC_PIPES]; uint32_t pipe_sizes[MAX_VSC_PIPES]; diff --git a/src/freedreno/vulkan/tu_util.c b/src/freedreno/vulkan/tu_util.c index 2d54af74e61..5be9100702b 100644 --- a/src/freedreno/vulkan/tu_util.c +++ b/src/freedreno/vulkan/tu_util.c @@ -208,6 +208,35 @@ tu_tiling_config_update_pipes(struct tu_framebuffer *fb, sizeof(uint32_t) * (max_pipe_count - used_pipe_count)); } +static bool +is_hw_binning_possible(const struct tu_framebuffer *fb) +{ + /* Similar to older gens, # of tiles per pipe cannot be more than 32. + * But there are no hangs with 16 or more tiles per pipe in either + * X or Y direction, so that limit does not seem to apply. + */ + uint32_t tiles_per_pipe = fb->pipe0.width * fb->pipe0.height; + return tiles_per_pipe <= 32; +} + +static void +tu_tiling_config_update_binning(struct tu_framebuffer *fb, const struct tu_device *device) +{ + fb->binning_possible = is_hw_binning_possible(fb); + + if (fb->binning_possible) { + fb->binning = (fb->tile_count.width * fb->tile_count.height) > 2; + + if (unlikely(device->physical_device->instance->debug_flags & TU_DEBUG_FORCEBIN)) + fb->binning = true; + if (unlikely(device->physical_device->instance->debug_flags & + TU_DEBUG_NOBIN)) + fb->binning = false; + } else { + fb->binning = false; + } +} + void tu_framebuffer_tiling_config(struct tu_framebuffer *fb, const struct tu_device *device, @@ -216,6 +245,7 @@ tu_framebuffer_tiling_config(struct tu_framebuffer *fb, tu_tiling_config_update_tile_layout(fb, device, pass); tu_tiling_config_update_pipe_layout(fb, device); tu_tiling_config_update_pipes(fb, device); + tu_tiling_config_update_binning(fb, device); } void @@ -268,4 +298,4 @@ tu_dbg_log_gmem_load_store_skips(struct tu_device *device) last_total_stores = current_total_stores; pthread_mutex_unlock(&device->submit_mutex); -} \ No newline at end of file +}