[Mesa-dev] [PATCH 119/133] nir: Rework the way samplers are lowered

Connor Abbott cwabbott0 at gmail.com
Mon Jan 5 22:48:00 PST 2015


I don't really feel qualified to review this, since I didn't write any
of the original code (I just copied-n-pasted it from what i965 was
doing...). I'm not sure who would be able to, maybe Chris Forbes since
he did the indirect sampler work?

On Tue, Dec 16, 2014 at 1:13 AM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> ---
>  src/glsl/nir/nir_lower_samplers.cpp | 149 ++++++++++++++++++------------------
>  1 file changed, 74 insertions(+), 75 deletions(-)
>
> diff --git a/src/glsl/nir/nir_lower_samplers.cpp b/src/glsl/nir/nir_lower_samplers.cpp
> index d94183c..ece4dc3 100644
> --- a/src/glsl/nir/nir_lower_samplers.cpp
> +++ b/src/glsl/nir/nir_lower_samplers.cpp
> @@ -36,67 +36,9 @@ extern "C" {
>  }
>
>  static unsigned
> -get_deref_name_offset(nir_deref_var *deref_var,
> -                      gl_shader_program *shader_program, char **name,
> -                      void *mem_ctx)
> -{
> -   nir_deref *deref = &deref_var->deref;
> -   nir_deref_array *deref_array;
> -   nir_deref_struct *deref_struct;
> -
> -   *name = ralloc_strdup(mem_ctx, deref_var->var->name);
> -
> -   while (deref->child != NULL) {
> -      switch (deref->child->deref_type) {
> -      case nir_deref_type_array:
> -         deref_array = nir_deref_as_array(deref->child);
> -         if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
> -            /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
> -             * while GLSL 1.30 requires that the array indices be
> -             * constant integer expressions.  We don't expect any driver
> -             * to actually work with a really variable array index, so
> -             * all that would work would be an unrolled loop counter that
> -             * ends up being constant.
> -             */
> -            ralloc_strcat(&shader_program->InfoLog,
> -                        "warning: Variable sampler array index unsupported.\n"
> -                        "This feature of the language was removed in GLSL 1.20 "
> -                        "and is unlikely to be supported for 1.10 in Mesa.\n");
> -         }
> -         if (deref_array->deref.child == NULL) {
> -            return deref_array->base_offset;
> -         }
> -         ralloc_asprintf_append(name, "[%u]", deref_array->base_offset);
> -         break;
> -
> -      case nir_deref_type_struct: {
> -         deref_struct = nir_deref_as_struct(deref->child);
> -         const char *field = glsl_get_struct_elem_name(deref->type,
> -                                                       deref_struct->index);
> -         ralloc_asprintf_append(name, ".%s", field);
> -         break;
> -      }
> -
> -      default:
> -         assert(0);
> -         break;
> -      }
> -      deref = deref->child;
> -   }
> -
> -   return 0;
> -}
> -
> -static unsigned
> -get_sampler_index(nir_deref_var *sampler,
> -                  struct gl_shader_program *shader_program,
> +get_sampler_index(struct gl_shader_program *shader_program, const char *name,
>                    const struct gl_program *prog)
>  {
> -   void *mem_ctx = ralloc_context(NULL);
> -   char *name;
> -   unsigned offset = get_deref_name_offset(sampler, shader_program, &name,
> -                                           mem_ctx);
> -
>     GLuint shader = _mesa_program_enum_to_shader_stage(prog->Target);
>
>     unsigned location;
> @@ -115,33 +57,86 @@ get_sampler_index(nir_deref_var *sampler,
>        return 0;
>     }
>
> -   ralloc_free(mem_ctx);
> -
> -   return shader_program->UniformStorage[location].sampler[shader].index +
> -          offset;
> +   return shader_program->UniformStorage[location].sampler[shader].index;
>  }
>
>  static void
>  lower_sampler(nir_tex_instr *instr, struct gl_shader_program *shader_program,
> -              const struct gl_program *prog)
> +              const struct gl_program *prog, void *mem_ctx)
>  {
> -   if (instr->sampler) {
> -      instr->sampler_index = get_sampler_index(instr->sampler, shader_program,
> -                                               prog);
> -      nir_src empty_src;
> -      memset(&empty_src, 0, sizeof empty_src);
> -      for (nir_deref *deref = &instr->sampler->deref; deref; deref = deref->child) {
> -         if (deref->deref_type == nir_deref_type_array) {
> -            nir_deref_array *arr = nir_deref_as_array(deref);
> -            nir_instr_rewrite_src(&instr->instr, &arr->indirect, empty_src);
> +   if (instr->sampler == NULL)
> +      return;
> +
> +   /* Get the name and the offset */
> +   instr->sampler_index = 0;
> +   instr->has_sampler_indirect = false;
> +   char *name = ralloc_strdup(mem_ctx, instr->sampler->var->name);
> +
> +   for (nir_deref *deref = &instr->sampler->deref;
> +        deref->child; deref = deref->child) {
> +      switch (deref->child->deref_type) {
> +      case nir_deref_type_array: {
> +         nir_deref_array *deref_array = nir_deref_as_array(deref->child);
> +
> +         /* XXX: We're assuming here that the indirect is the last array
> +          * thing we have.  This should be ok for now as we don't support
> +          * arrays_of_arrays yet.
> +          */
> +         assert(!instr->has_sampler_indirect);
> +
> +         instr->sampler_index *= glsl_get_length(deref->type);
> +         switch (deref_array->deref_array_type) {
> +         case nir_deref_array_type_direct:
> +            instr->sampler_index += deref_array->base_offset;
> +            if (deref_array->deref.child)
> +               ralloc_asprintf_append(&name, "[%u]", deref_array->base_offset);
> +            break;
> +         case nir_deref_array_type_indirect: {
> +            assert(!instr->has_sampler_indirect);
> +
> +            nir_instr_rewrite_src(&instr->instr, &instr->sampler_indirect,
> +                                  nir_src_copy(deref_array->indirect, mem_ctx));
> +            instr->has_sampler_indirect = true;
> +            instr->sampler_indirect_max = glsl_get_length(deref->type) - 1;
> +
> +            nir_src empty;
> +            memset(&empty, 0, sizeof empty);
> +            nir_instr_rewrite_src(&instr->instr, &deref_array->indirect, empty);
> +
> +            if (deref_array->deref.child)
> +               ralloc_strcat(&name, "[0]");
> +            break;
>           }
> +
> +         case nir_deref_array_type_wildcard:
> +            unreachable("Cannot copy samplers");
> +         default:
> +            unreachable("Invalid deref array type");
> +         }
> +         break;
>        }
>
> -      instr->sampler = NULL;
> +      case nir_deref_type_struct: {
> +         nir_deref_struct *deref_struct = nir_deref_as_struct(deref->child);
> +         const char *field = glsl_get_struct_elem_name(deref->type,
> +                                                       deref_struct->index);
> +         ralloc_asprintf_append(&name, ".%s", field);
> +         break;
> +      }
> +
> +      default:
> +         unreachable("Invalid deref type");
> +         break;
> +      }
>     }
> +
> +   instr->sampler_index += get_sampler_index(shader_program, name, prog);
> +
> +   instr->sampler = NULL;
>  }
>
>  typedef struct {
> +   void *mem_ctx;
>     struct gl_shader_program *shader_program;
>     struct gl_program *prog;
>  } lower_state;
> @@ -154,7 +149,8 @@ lower_block_cb(nir_block *block, void *_state)
>     nir_foreach_instr(block, instr) {
>        if (instr->type == nir_instr_type_tex) {
>           nir_tex_instr *tex_instr = nir_instr_as_tex(instr);
> -         lower_sampler(tex_instr, state->shader_program, state->prog);
> +         lower_sampler(tex_instr, state->shader_program, state->prog,
> +                       state->mem_ctx);
>        }
>     }
>
> @@ -166,8 +162,11 @@ lower_impl(nir_function_impl *impl, struct gl_shader_program *shader_program,
>             struct gl_program *prog)
>  {
>     lower_state state;
> +
> +   state.mem_ctx = ralloc_parent(impl);
>     state.shader_program = shader_program;
>     state.prog = prog;
> +
>     nir_foreach_block(impl, lower_block_cb, &state);
>  }
>
> --
> 2.2.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list