[Mesa-dev] [PATCH] nir/lower_samplers: don't assume a deref for both texture and sampler srcs

Jason Ekstrand jason at jlekstrand.net
Sat Aug 11 13:03:47 UTC 2018


On August 11, 2018 06:13:17 Alejandro PiƱeiro <apinheiro at igalia.com> wrote:

> After commit "nir: Use derefs in nir_lower_samplers"
> (75286c2d083cdbdfb202a93349e567df0441d5f7) assumes one deref for both
> the texture and the sampler. However there are cases (on OpenGL, using
> ARB_gl_spirv) where SPIR-V is not providing a sampler, like for
> texture query levels ops. Although we could make spirv_to_nir to
> provide a sampler deref for those cases, it is not really needed, and
> wrong from the Vulkan point of view.
>
> This patch fixes the following (borrowed) tests run on SPIR-V mode:
>  arb_compute_shader/execution/basic-texelFetch.shader_test
>  arb_gpu_shader5/execution/sampler_array_indexing/fs-simple-texture-size.shader_test
>  arb_texture_query_levels/execution/fs-baselevel.shader_test
>  arb_texture_query_levels/execution/fs-maxlevel.shader_test
>  arb_texture_query_levels/execution/fs-miptree.shader_test
>  arb_texture_query_levels/execution/fs-nomips.shader_test
>  arb_texture_query_levels/execution/vs-baselevel.shader_test
>  arb_texture_query_levels/execution/vs-maxlevel.shader_test
>  arb_texture_query_levels/execution/vs-miptree.shader_test
>  arb_texture_query_levels/execution/vs-nomips.shader_test
>  glsl-1.30/execution/fs-textureSize-compare.shader_test
>
> v2: merge lower_tex_src_to_offset and calc_sampler_offsets together,
>    update texture/sampler index and texture_array_size directly on
>    lower_tex_src_to_offset (Jason)
> ---
> src/compiler/glsl/gl_nir_lower_samplers.c | 111 ++++++++++++++++--------------
> 1 file changed, 58 insertions(+), 53 deletions(-)
>
> diff --git a/src/compiler/glsl/gl_nir_lower_samplers.c 
> b/src/compiler/glsl/gl_nir_lower_samplers.c
> index 43fe318a835..e001792d689 100644
> --- a/src/compiler/glsl/gl_nir_lower_samplers.c
> +++ b/src/compiler/glsl/gl_nir_lower_samplers.c
> @@ -31,21 +31,20 @@
> #include "main/compiler.h"
> #include "main/mtypes.h"
>
> -/* Calculate the sampler index based on array indicies and also
> - * calculate the base uniform location for struct members.
> - */
> static void
> -calc_sampler_offsets(nir_builder *b, nir_ssa_def *ptr,
> -                     const struct gl_shader_program *shader_program,
> -                     unsigned *base_index, nir_ssa_def **index,
> -                     unsigned *array_elements)
> +lower_tex_src_to_offset(nir_builder *b,
> +                        nir_tex_instr *instr, unsigned src_idx,
> +                        const struct gl_shader_program *shader_program)
> {
> -   *base_index = 0;
> -   *index = NULL;
> -   *array_elements = 1;
> +   nir_ssa_def *index = NULL;
> +   unsigned base_index = 0;
> +   unsigned array_elements = 1;
> +   nir_tex_src *src = &instr->src[src_idx];
> +   bool is_sampler = src->src_type == nir_tex_src_sampler_deref;
>    unsigned location = 0;
>
> -   nir_deref_instr *deref = nir_instr_as_deref(ptr->parent_instr);
> +   /* We compute first the offsets */
> +   nir_deref_instr *deref = nir_instr_as_deref(src->src.ssa->parent_instr);
>    while (deref->deref_type != nir_deref_type_var) {
>       assert(deref->parent.is_ssa);
>       nir_deref_instr *parent =
> @@ -61,22 +60,22 @@ calc_sampler_offsets(nir_builder *b, nir_ssa_def *ptr,
>          nir_const_value *const_deref_index =
>             nir_src_as_const_value(deref->arr.index);
>
> -         if (const_deref_index && *index == NULL) {
> +         if (const_deref_index && index == NULL) {
>             /* We're still building a direct index */
> -            *base_index += const_deref_index->u32[0] * *array_elements;
> +            base_index += const_deref_index->u32[0] * array_elements;
>          } else {
> -            if (*index == NULL) {
> +            if (index == NULL) {
>                /* We used to be direct but not anymore */
> -               *index = nir_imm_int(b, *base_index);
> -               *base_index = 0;
> +               index = nir_imm_int(b, base_index);
> +               base_index = 0;
>             }
>
> -            *index = nir_iadd(b, *index,
> -                     nir_imul(b, nir_imm_int(b, *array_elements),
> -                              nir_ssa_for_src(b, deref->arr.index, 1)));
> +            index = nir_iadd(b, index,
> +                             nir_imul(b, nir_imm_int(b, array_elements),
> +                                      nir_ssa_for_src(b, deref->arr.index, 
> 1)));
>          }
>
> -         *array_elements *= glsl_get_length(parent->type);
> +         array_elements *= glsl_get_length(parent->type);
>          break;
>       }
>
> @@ -87,8 +86,8 @@ calc_sampler_offsets(nir_builder *b, nir_ssa_def *ptr,
>       deref = parent;
>    }
>
> -   if (*index)
> -      *index = nir_umin(b, *index, nir_imm_int(b, *array_elements - 1));
> +   if (index)
> +      index = nir_umin(b, index, nir_imm_int(b, array_elements - 1));
>
>    /* We hit the deref_var.  This is the end of the line */
>    assert(deref->deref_type == nir_deref_type_var);
> @@ -99,8 +98,31 @@ calc_sampler_offsets(nir_builder *b, nir_ssa_def *ptr,
>    assert(location < shader_program->data->NumUniformStorage &&
>           shader_program->data->UniformStorage[location].opaque[stage].active);
>
> -   *base_index +=
> +   base_index +=
>       shader_program->data->UniformStorage[location].opaque[stage].index;
> +
> +   /* We have the offsets, we apply them, rewriting/removing instr if
> +    * needed
> +    */

We're removing it rewriting the source, not the instruction.  With that fixed,

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>

> +   if (index) {
> +      nir_instr_rewrite_src(&instr->instr, &src->src,
> +                            nir_src_for_ssa(index));
> +
> +      src->src_type = is_sampler ?
> +         nir_tex_src_sampler_offset :
> +         nir_tex_src_texture_offset;
> +
> +      instr->texture_array_size = array_elements;
> +   } else {
> +      nir_tex_instr_remove_src(instr, src_idx);
> +   }
> +
> +   if (is_sampler) {
> +      instr->sampler_index = base_index;
> +   } else {
> +      instr->texture_index = base_index;
> +      instr->texture_array_size = array_elements;
> +   }
> }
>
> static bool
> @@ -109,42 +131,25 @@ lower_sampler(nir_builder *b, nir_tex_instr *instr,
> {
>    int texture_idx =
>       nir_tex_instr_src_index(instr, nir_tex_src_texture_deref);
> -   int sampler_idx =
> -      nir_tex_instr_src_index(instr, nir_tex_src_sampler_deref);
> -
> -   if (texture_idx < 0)
> -      return false;
>
> -   assert(texture_idx >= 0 && sampler_idx >= 0);
> -   assert(instr->src[texture_idx].src.is_ssa);
> -   assert(instr->src[sampler_idx].src.is_ssa);
> -   assert(instr->src[texture_idx].src.ssa == instr->src[sampler_idx].src.ssa);
> +   if (texture_idx >= 0) {
> +      b->cursor = nir_before_instr(&instr->instr);
>
> -   b->cursor = nir_before_instr(&instr->instr);
> -
> -   unsigned base_offset, array_elements;
> -   nir_ssa_def *indirect;
> -   calc_sampler_offsets(b, instr->src[texture_idx].src.ssa, shader_program,
> -                        &base_offset, &indirect, &array_elements);
> +      lower_tex_src_to_offset(b, instr, texture_idx,
> +                              shader_program);
> +   }
>
> -   instr->texture_index = base_offset;
> -   instr->sampler_index = base_offset;
> -   if (indirect) {
> -      nir_instr_rewrite_src(&instr->instr, &instr->src[texture_idx].src,
> -                            nir_src_for_ssa(indirect));
> -      instr->src[texture_idx].src_type = nir_tex_src_texture_offset;
> -      nir_instr_rewrite_src(&instr->instr, &instr->src[sampler_idx].src,
> -                            nir_src_for_ssa(indirect));
> -      instr->src[sampler_idx].src_type = nir_tex_src_sampler_offset;
> +   int sampler_idx =
> +      nir_tex_instr_src_index(instr, nir_tex_src_sampler_deref);
>
> -      instr->texture_array_size = array_elements;
> -   } else {
> -      nir_tex_instr_remove_src(instr, texture_idx);
> -      /* The sampler index may have changed */
> -      sampler_idx = nir_tex_instr_src_index(instr, nir_tex_src_sampler_deref);
> -      nir_tex_instr_remove_src(instr, sampler_idx);
> +   if (sampler_idx >= 0) {
> +      lower_tex_src_to_offset(b, instr, sampler_idx,
> +                              shader_program);
>    }
>
> +   if (texture_idx < 0 && sampler_idx < 0)
> +      return false;
> +
>    return true;
> }
>
> --
> 2.14.1





More information about the mesa-dev mailing list