ac/llvm: add use_waterfall_for_divergent_tex_samplers option
GLSL says that indexing in a samplers array should be done with a dynamically uniform value. If the app doesn't obey this constraint, it'll get incorrect results. But there's one case where the app might be correct and yet get incorrect result: if 2 consecutive draws are used, with no state changes in between, the hardware might run them in the same wave and the app will get incorrect result as-if it was using non-dynamically uniform index. To prevent this, this commit takes advantage of the divergence analysis pass - if the index is marked as divergent, then it will have the same effect as using ACCESS_NON_UNIFORM in SPIR-V. Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16709>
This commit is contained in:

committed by
Marge Bot

parent
9ff04985b9
commit
9776c1cff2
@@ -4583,10 +4583,22 @@ static void tex_fetch_ptrs(struct ac_nir_context *ctx, nir_tex_instr *instr,
|
||||
|
||||
LLVMValueRef sampler_dynamic_index =
|
||||
get_sampler_desc_index(ctx, sampler_deref_instr, &instr->instr, false);
|
||||
if (instr->texture_non_uniform)
|
||||
|
||||
/* instr->sampler_non_uniform and texture_non_uniform are always false in GLSL,
|
||||
* but this can lead to unexpected behavior if texture/sampler index come from
|
||||
* a vertex attribute.
|
||||
* For instance, 2 consecutive draws using 2 different index values,
|
||||
* could be squashed together by the hw - producing a single draw with
|
||||
* non-dynamically uniform index.
|
||||
* To avoid this, detect divergent indexing, and use enter_waterfall.
|
||||
* See https://gitlab.freedesktop.org/mesa/mesa/-/issues/2253.
|
||||
*/
|
||||
if (instr->texture_non_uniform ||
|
||||
(ctx->abi->use_waterfall_for_divergent_tex_samplers && texture_deref_instr->dest.ssa.divergent))
|
||||
texture_dynamic_index = enter_waterfall(ctx, wctx + 0, texture_dynamic_index, true);
|
||||
|
||||
if (instr->sampler_non_uniform)
|
||||
if (instr->sampler_non_uniform ||
|
||||
(ctx->abi->use_waterfall_for_divergent_tex_samplers && sampler_deref_instr->dest.ssa.divergent))
|
||||
sampler_dynamic_index = enter_waterfall(ctx, wctx + 1, sampler_dynamic_index, true);
|
||||
|
||||
*res_ptr = get_sampler_desc(ctx, texture_deref_instr, main_descriptor, &instr->instr,
|
||||
|
@@ -129,6 +129,10 @@ struct ac_shader_abi {
|
||||
|
||||
/* Whether to inline the compute dispatch size in user sgprs. */
|
||||
bool load_grid_size_from_user_sgpr;
|
||||
|
||||
/* Whether to detect divergent textures/samplers index and apply
|
||||
* waterfall to avoid incorrect rendering. */
|
||||
bool use_waterfall_for_divergent_tex_samplers;
|
||||
};
|
||||
|
||||
#endif /* AC_SHADER_ABI_H */
|
||||
|
Reference in New Issue
Block a user