mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-03 22:58:31 +02:00
radeonsi: move si_nir_mark_divergent_texture_non_uniform to its own file
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34492>
This commit is contained in:
parent
deda05e2b7
commit
2e8cac328a
4 changed files with 63 additions and 55 deletions
|
|
@ -55,6 +55,7 @@ files_libradeonsi = files(
|
|||
'si_nir_lower_ps_color_inputs.c',
|
||||
'si_nir_lower_resource.c',
|
||||
'si_nir_lower_vs_inputs.c',
|
||||
'si_nir_mark_divergent_texture_non_uniform.c',
|
||||
'si_nir_optim.c',
|
||||
'si_sdma_copy_image.c',
|
||||
'si_shader.c',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
/* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "si_shader_internal.h"
|
||||
#include "nir.h"
|
||||
|
||||
bool si_nir_mark_divergent_texture_non_uniform(struct nir_shader *nir)
|
||||
{
|
||||
/* 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, mark them as non-uniform,
|
||||
* so that we can apply waterfall loop on these index later (either llvm
|
||||
* backend or nir_lower_non_uniform_access).
|
||||
*
|
||||
* See https://gitlab.freedesktop.org/mesa/mesa/-/issues/2253
|
||||
*/
|
||||
|
||||
bool divergence_changed = false;
|
||||
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
|
||||
nir_metadata_require(impl, nir_metadata_divergence);
|
||||
|
||||
nir_foreach_block_safe(block, impl) {
|
||||
nir_foreach_instr_safe(instr, block) {
|
||||
if (instr->type != nir_instr_type_tex)
|
||||
continue;
|
||||
|
||||
nir_tex_instr *tex = nir_instr_as_tex(instr);
|
||||
for (int i = 0; i < tex->num_srcs; i++) {
|
||||
bool divergent = nir_src_is_divergent(&tex->src[i].src);
|
||||
|
||||
switch (tex->src[i].src_type) {
|
||||
case nir_tex_src_texture_deref:
|
||||
case nir_tex_src_texture_handle:
|
||||
tex->texture_non_uniform |= divergent;
|
||||
break;
|
||||
case nir_tex_src_sampler_deref:
|
||||
case nir_tex_src_sampler_handle:
|
||||
tex->sampler_non_uniform |= divergent;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If dest is already divergent, divergence won't change. */
|
||||
divergence_changed |= !tex->def.divergent &&
|
||||
(tex->texture_non_uniform || tex->sampler_non_uniform);
|
||||
}
|
||||
}
|
||||
return nir_progress(divergence_changed, impl,
|
||||
nir_metadata_all & ~nir_metadata_divergence);
|
||||
}
|
||||
|
|
@ -156,6 +156,7 @@ bool si_nir_lower_resource(nir_shader *nir, struct si_shader *shader,
|
|||
struct si_shader_args *args);
|
||||
bool si_nir_lower_vs_inputs(nir_shader *nir, struct si_shader *shader,
|
||||
struct si_shader_args *args);
|
||||
bool si_nir_mark_divergent_texture_non_uniform(struct nir_shader *nir);
|
||||
|
||||
/* si_shader_llvm.c */
|
||||
bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compiler,
|
||||
|
|
|
|||
|
|
@ -346,60 +346,6 @@ static void si_lower_nir(struct si_screen *sscreen, struct nir_shader *nir)
|
|||
NIR_PASS_V(nir, nir_lower_fp16_casts, nir_lower_fp16_split_fp64);
|
||||
}
|
||||
|
||||
static bool si_mark_divergent_texture_non_uniform(struct nir_shader *nir)
|
||||
{
|
||||
/* 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, mark them as non-uniform,
|
||||
* so that we can apply waterfall loop on these index later (either llvm
|
||||
* backend or nir_lower_non_uniform_access).
|
||||
*
|
||||
* See https://gitlab.freedesktop.org/mesa/mesa/-/issues/2253
|
||||
*/
|
||||
|
||||
bool divergence_changed = false;
|
||||
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
|
||||
nir_metadata_require(impl, nir_metadata_divergence);
|
||||
|
||||
nir_foreach_block_safe(block, impl) {
|
||||
nir_foreach_instr_safe(instr, block) {
|
||||
if (instr->type != nir_instr_type_tex)
|
||||
continue;
|
||||
|
||||
nir_tex_instr *tex = nir_instr_as_tex(instr);
|
||||
for (int i = 0; i < tex->num_srcs; i++) {
|
||||
bool divergent = nir_src_is_divergent(&tex->src[i].src);
|
||||
|
||||
switch (tex->src[i].src_type) {
|
||||
case nir_tex_src_texture_deref:
|
||||
case nir_tex_src_texture_handle:
|
||||
tex->texture_non_uniform |= divergent;
|
||||
break;
|
||||
case nir_tex_src_sampler_deref:
|
||||
case nir_tex_src_sampler_handle:
|
||||
tex->sampler_non_uniform |= divergent;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If dest is already divergent, divergence won't change. */
|
||||
divergence_changed |= !tex->def.divergent &&
|
||||
(tex->texture_non_uniform || tex->sampler_non_uniform);
|
||||
}
|
||||
}
|
||||
return nir_progress(divergence_changed, impl,
|
||||
nir_metadata_all & ~nir_metadata_divergence);
|
||||
}
|
||||
|
||||
char *si_finalize_nir(struct pipe_screen *screen, struct nir_shader *nir)
|
||||
{
|
||||
struct si_screen *sscreen = (struct si_screen *)screen;
|
||||
|
|
@ -454,7 +400,7 @@ char *si_finalize_nir(struct pipe_screen *screen, struct nir_shader *nir)
|
|||
if (progress)
|
||||
si_nir_opts(sscreen, nir, false);
|
||||
|
||||
NIR_PASS(_, nir, si_mark_divergent_texture_non_uniform);
|
||||
NIR_PASS(_, nir, si_nir_mark_divergent_texture_non_uniform);
|
||||
|
||||
/* Require divergence analysis to identify divergent loops. */
|
||||
nir_metadata_require(nir_shader_get_entrypoint(nir), nir_metadata_divergence);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue