diff --git a/src/freedreno/common/freedreno_dev_info.h b/src/freedreno/common/freedreno_dev_info.h index 7d9631d9b62..e2170df697c 100644 --- a/src/freedreno/common/freedreno_dev_info.h +++ b/src/freedreno/common/freedreno_dev_info.h @@ -247,6 +247,13 @@ struct fd_dev_info { * fully compatible. */ bool ubwc_unorm_snorm_int_compatible; + + /* Blob doesn't use hw binning with GS on all a6xx and a7xx, however + * in Turnip it worked without issues until a750. On a750 there are CTS + * failures when e.g. dEQP-VK.subgroups.arithmetic.framebuffer.* in + * parallel with "forcebin". It is exacerbated by using "syncdraw". + */ + bool no_gs_hw_binning_quirk; } a7xx; }; diff --git a/src/freedreno/common/freedreno_devices.py b/src/freedreno/common/freedreno_devices.py index 2f6aa02573a..a213cc32b1d 100644 --- a/src/freedreno/common/freedreno_devices.py +++ b/src/freedreno/common/freedreno_devices.py @@ -825,6 +825,7 @@ a7xx_750 = A7XXProps( # example dEQP-VK.image.load_store.with_format.2d.*. Disable this for # now. #supports_ibo_ubwc = True, + no_gs_hw_binning_quirk = True, ) a730_magic_regs = dict( diff --git a/src/freedreno/vulkan/tu_cmd_buffer.cc b/src/freedreno/vulkan/tu_cmd_buffer.cc index 850603a5e7b..1edfec6a383 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.cc +++ b/src/freedreno/vulkan/tu_cmd_buffer.cc @@ -858,6 +858,10 @@ use_hw_binning(struct tu_cmd_buffer *cmd) const struct tu_framebuffer *fb = cmd->state.framebuffer; const struct tu_tiling_config *tiling = &fb->tiling[cmd->state.gmem_layout]; + if (cmd->state.rp.has_gs && + cmd->device->physical_device->info->a7xx.no_gs_hw_binning_quirk) + return false; + /* 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. @@ -908,17 +912,21 @@ use_sysmem_rendering(struct tu_cmd_buffer *cmd, if (cmd->state.rp.disable_gmem) return true; - /* XFB is incompatible with non-hw binning GMEM rendering, see use_hw_binning */ - if (cmd->state.rp.xfb_used && !cmd->state.tiling->binning_possible) - return true; + if (!cmd->state.tiling->binning_possible || + (cmd->state.rp.has_gs && + cmd->device->physical_device->info->a7xx.no_gs_hw_binning_quirk)) { + /* XFB is incompatible with non-hw binning GMEM rendering, see + * use_hw_binning */ + if (cmd->state.rp.xfb_used) + return true; - /* QUERY_TYPE_PRIMITIVES_GENERATED is incompatible with non-hw binning - * GMEM rendering, see use_hw_binning. - */ - if ((cmd->state.rp.has_prim_generated_query_in_rp || - cmd->state.prim_generated_query_running_before_rp) && - !cmd->state.tiling->binning_possible) - return true; + /* QUERY_TYPE_PRIMITIVES_GENERATED is incompatible with non-hw binning + * GMEM rendering, see use_hw_binning. + */ + if (cmd->state.rp.has_prim_generated_query_in_rp || + cmd->state.prim_generated_query_running_before_rp) + return true; + } if (TU_DEBUG(GMEM)) return false; @@ -3183,6 +3191,9 @@ tu_pipeline_update_rp_state(struct tu_cmd_state *cmd_state) if (cmd_state->pipeline_has_tess) { cmd_state->rp.has_tess = true; } + if (cmd_state->pipeline_has_gs) { + cmd_state->rp.has_gs = true; + } } VKAPI_ATTR void VKAPI_CALL @@ -3234,6 +3245,7 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer, cmd->state.prim_order_gmem = pipeline->prim_order.state_gmem; cmd->state.pipeline_sysmem_single_prim_mode = pipeline->prim_order.sysmem_single_prim_mode; cmd->state.pipeline_has_tess = pipeline->active_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + cmd->state.pipeline_has_gs = pipeline->active_stages & VK_SHADER_STAGE_GEOMETRY_BIT; cmd->state.pipeline_disable_gmem = gfx_pipeline->feedback_loop_may_involve_textures; tu_pipeline_update_rp_state(&cmd->state); @@ -3723,6 +3735,7 @@ tu_render_pass_state_merge(struct tu_render_pass_state *dst, { dst->xfb_used |= src->xfb_used; dst->has_tess |= src->has_tess; + dst->has_gs |= src->has_gs; dst->has_prim_generated_query_in_rp |= src->has_prim_generated_query_in_rp; dst->disable_gmem |= src->disable_gmem; dst->sysmem_single_prim_mode |= src->sysmem_single_prim_mode; diff --git a/src/freedreno/vulkan/tu_cmd_buffer.h b/src/freedreno/vulkan/tu_cmd_buffer.h index 0bc3db8b92f..ab171e1ab8c 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.h +++ b/src/freedreno/vulkan/tu_cmd_buffer.h @@ -276,6 +276,7 @@ struct tu_render_pass_state { bool xfb_used; bool has_tess; + bool has_gs; bool has_prim_generated_query_in_rp; bool disable_gmem; bool sysmem_single_prim_mode; @@ -504,6 +505,7 @@ struct tu_cmd_state bool pipeline_feedback_loop_ds; bool pipeline_sysmem_single_prim_mode; bool pipeline_has_tess; + bool pipeline_has_gs; bool pipeline_disable_gmem; bool pipeline_blend_lrz, pipeline_bandwidth;