diff --git a/src/freedreno/vulkan/tu_cmd_buffer.cc b/src/freedreno/vulkan/tu_cmd_buffer.cc index db8e77255da..6af80d78cac 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.cc +++ b/src/freedreno/vulkan/tu_cmd_buffer.cc @@ -1310,7 +1310,7 @@ use_hw_binning(struct tu_cmd_buffer *cmd) return true; } - return vsc->binning; + return vsc->binning_possible && vsc->binning_useful; } static bool @@ -1373,8 +1373,16 @@ use_sysmem_rendering(struct tu_cmd_buffer *cmd, return true; } - if (TU_DEBUG(GMEM)) + if (TU_DEBUG(GMEM)) { + cmd->state.rp.gmem_disable_reason = "TU_DEBUG(GMEM)"; return false; + } + + /* This is a case where it's better to avoid GMEM, too many tiles but no HW binning possible. */ + if (!vsc->binning_possible && vsc->binning_useful) { + cmd->state.rp.gmem_disable_reason = "Too many tiles and HW binning is not possible"; + return true; + } bool use_sysmem = cmd->device->autotune->get_optimal_mode(cmd, rp_ctx) == tu_autotune::render_mode::SYSMEM; if (use_sysmem) @@ -6413,7 +6421,7 @@ tu_emit_subpass_begin_gmem(struct tu_cmd_buffer *cmd, struct tu_resolve_group *r * (perf queries), then we can't do this optimization since the * start-of-the-CS geometry condition will have been overwritten. */ - bool cond_load_allowed = vsc->binning && + bool cond_load_allowed = vsc->binning_possible && cmd->state.pass->has_cond_load_store && !cmd->state.rp.draw_cs_writes_to_cond_pred; diff --git a/src/freedreno/vulkan/tu_device.h b/src/freedreno/vulkan/tu_device.h index 0ac763ef847..979adfbee68 100644 --- a/src/freedreno/vulkan/tu_device.h +++ b/src/freedreno/vulkan/tu_device.h @@ -564,8 +564,11 @@ struct tu_vsc_config { /* Whether binning could be used for gmem rendering using this framebuffer. */ bool binning_possible; - /* Whether binning should be used for gmem rendering using this framebuffer. */ - bool binning; + /* Whether binning is useful for GMEM rendering performance using this framebuffer. This is independent of whether + * binning is possible, and is determined by the tile count. Not binning when it's useful would be a performance + * hazard, and GMEM rendering should be avoided in the case where it's useful to bin but not possible to do so. + */ + bool binning_useful; /* pipe register values */ uint32_t pipe_config[MAX_VSC_PIPES]; diff --git a/src/freedreno/vulkan/tu_util.cc b/src/freedreno/vulkan/tu_util.cc index e19d43bb8a9..0ebceae8998 100644 --- a/src/freedreno/vulkan/tu_util.cc +++ b/src/freedreno/vulkan/tu_util.cc @@ -460,16 +460,12 @@ tu_tiling_config_update_pipes(struct tu_vsc_config *vsc, static void tu_tiling_config_update_binning(struct tu_vsc_config *vsc, const struct tu_device *device) { - if (vsc->binning_possible) { - vsc->binning = (vsc->tile_count.width * vsc->tile_count.height) > 2; + vsc->binning_useful = (vsc->tile_count.width * vsc->tile_count.height) > 2; - if (TU_DEBUG(FORCEBIN)) - vsc->binning = true; - if (TU_DEBUG(NOBIN)) - vsc->binning = false; - } else { - vsc->binning = false; - } + if (TU_DEBUG(FORCEBIN)) + vsc->binning_useful = true; + if (TU_DEBUG(NOBIN)) + vsc->binning_useful = false; } void