[Mesa-dev] [PATCH 2/2] mesa: fix GLSL program objects with more than 16 samplers combined

Marek Olšák maraeo at gmail.com
Sat May 18 11:20:41 PDT 2013


Ping. This patch allows more than 16 samplers in all shaders combined
(MAX_COMBINED_TEXTURE_IMAGE_UNITS), which has never been possible with
current Mesa git. GL 3.1 requires 32 combined texture image units and
GL 3.2 requires 48, so I think this patch deserves a review.

Marek

On Mon, May 13, 2013 at 6:42 PM, Marek Olšák <maraeo at gmail.com> wrote:
> The problem is the sampler units are allocated from the same pool for all
> shader stages, so if a vertex shader uses 12 samplers (0..11), the fragment
> shader samplers start at index 12, leaving only 4 sampler units
> for the fragment shader. The main cause is probably the fact that samplers
> (texture unit -> sampler unit mapping, etc.) are tracked globally
> for an entire program object.
>
> This commit adapts the GLSL linker and core Mesa such that the sampler units
> are assigned to sampler uniforms for each shader stage separately
> (if a sampler uniform is used in all shader stages, it may occupy a different
> sampler unit in each, and vice versa, an i-th sampler unit may refer to
> a different sampler uniform in each shader stage), and the sampler-specific
> variables are moved from gl_shader_program to gl_shader.
>
> This doesn't require any driver changes, and it fixes piglit/max-samplers
> for gallium and classic swrast. It also works with any number of shader
> stages.
> ---
>  src/glsl/ir_uniform.h                            |   27 +++--
>  src/glsl/link_uniform_initializers.cpp           |   25 ++++-
>  src/glsl/link_uniforms.cpp                       |  127 +++++++++++-----------
>  src/glsl/tests/set_uniform_initializer_tests.cpp |   10 +-
>  src/mesa/main/mtypes.h                           |   22 ++--
>  src/mesa/main/uniform_query.cpp                  |   24 ++--
>  src/mesa/main/uniforms.c                         |   11 +-
>  src/mesa/program/ir_to_mesa.cpp                  |   15 ++-
>  src/mesa/program/sampler.cpp                     |   19 +++-
>  9 files changed, 167 insertions(+), 113 deletions(-)
>
> diff --git a/src/glsl/ir_uniform.h b/src/glsl/ir_uniform.h
> index 30e6f26..8198c48 100644
> --- a/src/glsl/ir_uniform.h
> +++ b/src/glsl/ir_uniform.h
> @@ -99,15 +99,24 @@ struct gl_uniform_storage {
>      */
>     bool initialized;
>
> -   /**
> -    * Base sampler index
> -    *
> -    * If \c ::base_type is \c GLSL_TYPE_SAMPLER, this represents the index of
> -    * this sampler.  If \c ::array_elements is not zero, the array will use
> -    * sampler indexes \c ::sampler through \c ::sampler + \c ::array_elements
> -    * - 1, inclusive.
> -    */
> -   uint8_t sampler;
> +   struct {
> +      /**
> +       * Base sampler index
> +       *
> +       * If \c ::base_type is \c GLSL_TYPE_SAMPLER, this represents the index
> +       * of this sampler.  If \c ::array_elements is not zero, the array will
> +       * use sampler indices \c ::sampler through \c ::sampler +
> +       * \c ::array_elements - 1, inclusive.
> +       *
> +       * Note that the index may be different in each shader stage.
> +       */
> +      uint8_t index;
> +
> +      /**
> +       * Whether this sampler is used in this shader stage.
> +       */
> +      bool active;
> +   } sampler[MESA_SHADER_TYPES];
>
>     /**
>      * Storage used by the driver for the uniform
> diff --git a/src/glsl/link_uniform_initializers.cpp b/src/glsl/link_uniform_initializers.cpp
> index 836a360..54d9bf1 100644
> --- a/src/glsl/link_uniform_initializers.cpp
> +++ b/src/glsl/link_uniform_initializers.cpp
> @@ -138,8 +138,16 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
>        }
>
>        if (base_type == GLSL_TYPE_SAMPLER) {
> -        for (unsigned int i = 0; i < storage->array_elements; i++) {
> -           prog->SamplerUnits[storage->sampler + i] = storage->storage[i].i;
> +         for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
> +            gl_shader *shader = prog->_LinkedShaders[sh];
> +
> +            if (shader && storage->sampler[sh].active) {
> +               for (unsigned i = 0; i < storage->array_elements; i++) {
> +                  unsigned index = storage->sampler[sh].index + i;
> +
> +                  shader->SamplerUnits[index] = storage->storage[i].i;
> +               }
> +            }
>          }
>        }
>     } else {
> @@ -148,8 +156,17 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
>                                val->type->base_type,
>                                val->type->components());
>
> -      if (storage->type->is_sampler())
> -        prog->SamplerUnits[storage->sampler] = storage->storage[0].i;
> +      if (storage->type->is_sampler()) {
> +         for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
> +            gl_shader *shader = prog->_LinkedShaders[sh];
> +
> +            if (shader && storage->sampler[sh].active) {
> +               unsigned index = storage->sampler[sh].index;
> +
> +               shader->SamplerUnits[index] = storage->storage[0].i;
> +            }
> +         }
> +      }
>     }
>
>     storage->initialized = true;
> diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
> index d457e4d..3d02fff 100644
> --- a/src/glsl/link_uniforms.cpp
> +++ b/src/glsl/link_uniforms.cpp
> @@ -263,15 +263,19 @@ public:
>     parcel_out_uniform_storage(struct string_to_uint_map *map,
>                               struct gl_uniform_storage *uniforms,
>                               union gl_constant_value *values)
> -      : map(map), uniforms(uniforms), next_sampler(0), values(values)
> +      : map(map), uniforms(uniforms), values(values)
>     {
> -      memset(this->targets, 0, sizeof(this->targets));
>     }
>
> -   void start_shader()
> +   void start_shader(gl_shader_type shader_type)
>     {
> +      assert(shader_type < MESA_SHADER_TYPES);
> +      this->shader_type = shader_type;
> +
>        this->shader_samplers_used = 0;
>        this->shader_shadow_samplers = 0;
> +      this->next_sampler = 0;
> +      memset(this->targets, 0, sizeof(this->targets));
>     }
>
>     void set_and_process(struct gl_shader_program *prog,
> @@ -335,8 +339,38 @@ public:
>     int ubo_block_index;
>     int ubo_byte_offset;
>     bool ubo_row_major;
> +   gl_shader_type shader_type;
>
>  private:
> +   void handle_samplers(const glsl_type *base_type,
> +                        struct gl_uniform_storage *uniform)
> +   {
> +
> +      if (base_type->is_sampler()) {
> +         uniform->sampler[shader_type].index = this->next_sampler;
> +         uniform->sampler[shader_type].active = true;
> +
> +        /* Increment the sampler by 1 for non-arrays and by the number of
> +         * array elements for arrays.
> +         */
> +         this->next_sampler +=
> +               MAX2(1, uniform->array_elements);
> +
> +        const gl_texture_index target = base_type->sampler_index();
> +        const unsigned shadow = base_type->sampler_shadow;
> +         for (unsigned i = uniform->sampler[shader_type].index;
> +              i < MIN2(this->next_sampler, MAX_SAMPLERS);
> +              i++) {
> +           this->targets[i] = target;
> +           this->shader_samplers_used |= 1U << i;
> +           this->shader_shadow_samplers |= shadow << i;
> +        }
> +      } else {
> +         uniform->sampler[shader_type].index = ~0;
> +         uniform->sampler[shader_type].active = false;
> +      }
> +   }
> +
>     virtual void visit_field(const glsl_type *type, const char *name,
>                              bool row_major)
>     {
> @@ -354,31 +388,6 @@ private:
>        if (!found)
>          return;
>
> -      /* If there is already storage associated with this uniform, it means
> -       * that it was set while processing an earlier shader stage.  For
> -       * example, we may be processing the uniform in the fragment shader, but
> -       * the uniform was already processed in the vertex shader.
> -       */
> -      if (this->uniforms[id].storage != NULL) {
> -        /* If the uniform already has storage set from another shader stage,
> -         * mark the samplers used for this shader stage.
> -         */
> -        if (type->contains_sampler()) {
> -           const unsigned count = MAX2(1, this->uniforms[id].array_elements);
> -           const unsigned shadow = (type->is_array())
> -              ? type->fields.array->sampler_shadow : type->sampler_shadow;
> -
> -           for (unsigned i = 0; i < count; i++) {
> -              const unsigned s = this->uniforms[id].sampler + i;
> -
> -              this->shader_samplers_used |= 1U << s;
> -              this->shader_shadow_samplers |= shadow << s;
> -           }
> -        }
> -
> -        return;
> -      }
> -
>        const glsl_type *base_type;
>        if (type->is_array()) {
>          this->uniforms[id].array_elements = type->length;
> @@ -388,26 +397,16 @@ private:
>          base_type = type;
>        }
>
> -      if (base_type->is_sampler()) {
> -        this->uniforms[id].sampler = this->next_sampler;
> +      /* This assigns sampler uniforms to sampler units. */
> +      handle_samplers(base_type, &this->uniforms[id]);
>
> -        /* Increment the sampler by 1 for non-arrays and by the number of
> -         * array elements for arrays.
> -         */
> -        this->next_sampler += MAX2(1, this->uniforms[id].array_elements);
> -
> -        const gl_texture_index target = base_type->sampler_index();
> -        const unsigned shadow = base_type->sampler_shadow;
> -        for (unsigned i = this->uniforms[id].sampler
> -                ; i < MIN2(this->next_sampler, MAX_SAMPLERS)
> -                ; i++) {
> -           this->targets[i] = target;
> -           this->shader_samplers_used |= 1U << i;
> -           this->shader_shadow_samplers |= shadow << i;
> -        }
> -
> -      } else {
> -        this->uniforms[id].sampler = ~0;
> +      /* If there is already storage associated with this uniform, it means
> +       * that it was set while processing an earlier shader stage.  For
> +       * example, we may be processing the uniform in the fragment shader, but
> +       * the uniform was already processed in the vertex shader.
> +       */
> +      if (this->uniforms[id].storage != NULL) {
> +        return;
>        }
>
>        this->uniforms[id].name = ralloc_strdup(this->uniforms, name);
> @@ -633,17 +632,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
>        prog->UniformHash = new string_to_uint_map;
>     }
>
> -   /* Uniforms that lack an initializer in the shader code have an initial
> -    * value of zero.  This includes sampler uniforms.
> -    *
> -    * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says:
> -    *
> -    *     "The link time initial value is either the value of the variable's
> -    *     initializer, if present, or 0 if no initializer is present. Sampler
> -    *     types cannot have initializers."
> -    */
> -   memset(prog->SamplerUnits, 0, sizeof(prog->SamplerUnits));
> -
>     /* First pass: Count the uniform resources used by the user-defined
>      * uniforms.  While this happens, each active uniform will have an index
>      * assigned to it.
> @@ -656,6 +644,18 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
>        if (prog->_LinkedShaders[i] == NULL)
>          continue;
>
> +      /* Uniforms that lack an initializer in the shader code have an initial
> +       * value of zero.  This includes sampler uniforms.
> +       *
> +       * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says:
> +       *
> +       *     "The link time initial value is either the value of the variable's
> +       *     initializer, if present, or 0 if no initializer is present. Sampler
> +       *     types cannot have initializers."
> +       */
> +      memset(prog->_LinkedShaders[i]->SamplerUnits, 0,
> +             sizeof(gl_shader::SamplerUnits));
> +
>        link_update_uniform_buffer_variables(prog->_LinkedShaders[i]);
>
>        /* Reset various per-shader target counts.
> @@ -706,9 +706,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
>        if (prog->_LinkedShaders[i] == NULL)
>          continue;
>
> -      /* Reset various per-shader target counts.
> -       */
> -      parcel.start_shader();
> +      parcel.start_shader((gl_shader_type)i);
>
>        foreach_list(node, prog->_LinkedShaders[i]->ir) {
>          ir_variable *const var = ((ir_instruction *) node)->as_variable();
> @@ -726,10 +724,11 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
>
>        prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used;
>        prog->_LinkedShaders[i]->shadow_samplers = parcel.shader_shadow_samplers;
> -   }
>
> -   assert(sizeof(prog->SamplerTargets) == sizeof(parcel.targets));
> -   memcpy(prog->SamplerTargets, parcel.targets, sizeof(prog->SamplerTargets));
> +      assert(sizeof(gl_shader::SamplerTargets) == sizeof(parcel.targets));
> +      memcpy(prog->_LinkedShaders[i]->SamplerTargets, parcel.targets,
> +             sizeof(gl_shader::SamplerTargets));
> +   }
>
>  #ifndef NDEBUG
>     for (unsigned i = 0; i < num_user_uniforms; i++) {
> diff --git a/src/glsl/tests/set_uniform_initializer_tests.cpp b/src/glsl/tests/set_uniform_initializer_tests.cpp
> index 55831f9..5c6d4a5 100644
> --- a/src/glsl/tests/set_uniform_initializer_tests.cpp
> +++ b/src/glsl/tests/set_uniform_initializer_tests.cpp
> @@ -116,7 +116,10 @@ establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage,
>     prog->UniformStorage[index_to_set].type = type;
>     prog->UniformStorage[index_to_set].array_elements = array_size;
>     prog->UniformStorage[index_to_set].initialized = false;
> -   prog->UniformStorage[index_to_set].sampler = ~0;
> +   for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
> +      prog->UniformStorage[index_to_set].sampler[sh].index = ~0;
> +      prog->UniformStorage[index_to_set].sampler[sh].active = false;
> +   }
>     prog->UniformStorage[index_to_set].num_driver_storage = 0;
>     prog->UniformStorage[index_to_set].driver_storage = NULL;
>     prog->UniformStorage[index_to_set].storage =
> @@ -134,7 +137,10 @@ establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage,
>        prog->UniformStorage[i].type = glsl_type::void_type;
>        prog->UniformStorage[i].array_elements = 0;
>        prog->UniformStorage[i].initialized = false;
> -      prog->UniformStorage[i].sampler = ~0;
> +      for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
> +         prog->UniformStorage[i].sampler[sh].index = ~0;
> +         prog->UniformStorage[i].sampler[sh].active = false;
> +      }
>        prog->UniformStorage[i].num_driver_storage = 0;
>        prog->UniformStorage[i].driver_storage = NULL;
>        prog->UniformStorage[i].storage = NULL;
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index a68862d..bce1e6c 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -2132,6 +2132,17 @@ struct gl_shader
>     /*@}*/
>
>     /**
> +    * Map from sampler unit to texture unit (set by glUniform1i())
> +    *
> +    * A sampler unit is associated with each sampler uniform by the linker.
> +    * The sampler unit associated with each uniform is stored in the
> +    * \c gl_uniform_storage::sampler field.
> +    */
> +   GLubyte SamplerUnits[MAX_SAMPLERS];
> +   /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */
> +   gl_texture_index SamplerTargets[MAX_SAMPLERS];
> +
> +   /**
>      * Number of uniform components used by this shader.
>      *
>      * This field is only set post-linking.
> @@ -2335,17 +2346,6 @@ struct gl_shader_program
>      */
>     struct string_to_uint_map *UniformHash;
>
> -   /**
> -    * Map from sampler unit to texture unit (set by glUniform1i())
> -    *
> -    * A sampler unit is associated with each sampler uniform by the linker.
> -    * The sampler unit associated with each uniform is stored in the
> -    * \c gl_uniform_storage::sampler field.
> -    */
> -   GLubyte SamplerUnits[MAX_SAMPLERS];
> -   /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */
> -   gl_texture_index SamplerTargets[MAX_SAMPLERS];
> -
>     GLboolean LinkStatus;   /**< GL_LINK_STATUS */
>     GLboolean Validated;
>     GLboolean _Used;        /**< Ever used for drawing? */
> diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
> index b7f25e0..ec31049 100644
> --- a/src/mesa/main/uniform_query.cpp
> +++ b/src/mesa/main/uniform_query.cpp
> @@ -778,24 +778,24 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
>     if (uni->type->is_sampler()) {
>        int i;
>
> -      for (i = 0; i < count; i++) {
> -        shProg->SamplerUnits[uni->sampler + offset + i] =
> -           ((unsigned *) values)[i];
> -      }
> -
>        bool flushed = false;
>        for (i = 0; i < MESA_SHADER_TYPES; i++) {
>          struct gl_shader *const sh = shProg->_LinkedShaders[i];
> +         int j;
>
> -        /* If the shader stage doesn't use any samplers, don't bother
> -         * checking if any samplers have changed.
> +        /* If the shader stage doesn't use the sampler uniform, skip this.
>           */
> -        if (sh == NULL || sh->active_samplers == 0)
> +        if (sh == NULL || !uni->sampler[i].active)
>             continue;
>
> +         for (j = 0; j < count; j++) {
> +            sh->SamplerUnits[uni->sampler[i].index + offset + j] =
> +               ((unsigned *) values)[j];
> +         }
> +
>          struct gl_program *const prog = sh->Program;
>
> -        assert(sizeof(prog->SamplerUnits) == sizeof(shProg->SamplerUnits));
> +        assert(sizeof(prog->SamplerUnits) == sizeof(sh->SamplerUnits));
>
>          /* Determine if any of the samplers used by this shader stage have
>           * been modified.
> @@ -803,7 +803,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
>          bool changed = false;
>          for (unsigned j = 0; j < Elements(prog->SamplerUnits); j++) {
>             if ((sh->active_samplers & (1U << j)) != 0
> -               && (prog->SamplerUnits[j] != shProg->SamplerUnits[j])) {
> +               && (prog->SamplerUnits[j] != sh->SamplerUnits[j])) {
>                changed = true;
>                break;
>             }
> @@ -816,8 +816,8 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
>             }
>
>             memcpy(prog->SamplerUnits,
> -                  shProg->SamplerUnits,
> -                  sizeof(shProg->SamplerUnits));
> +                  sh->SamplerUnits,
> +                  sizeof(sh->SamplerUnits));
>
>             _mesa_update_shader_textures_used(shProg, prog);
>              if (ctx->Driver.SamplerUniformChange)
> diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
> index f0d80f0..6d79df6 100644
> --- a/src/mesa/main/uniforms.c
> +++ b/src/mesa/main/uniforms.c
> @@ -45,6 +45,7 @@
>  #include "main/enums.h"
>  #include "ir_uniform.h"
>  #include "glsl_types.h"
> +#include "program/program.h"
>
>  /**
>   * Update the vertex/fragment program's TexturesUsed array.
> @@ -66,14 +67,18 @@ _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
>                                   struct gl_program *prog)
>  {
>     GLuint s;
> +   struct gl_shader *shader =
> +      shProg->_LinkedShaders[_mesa_program_target_to_index(prog->Target)];
>
> -   memcpy(prog->SamplerUnits, shProg->SamplerUnits, sizeof(prog->SamplerUnits));
> +   assert(shader);
> +
> +   memcpy(prog->SamplerUnits, shader->SamplerUnits, sizeof(prog->SamplerUnits));
>     memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
>
>     for (s = 0; s < MAX_SAMPLERS; s++) {
>        if (prog->SamplersUsed & (1 << s)) {
> -         GLuint unit = shProg->SamplerUnits[s];
> -         GLuint tgt = shProg->SamplerTargets[s];
> +         GLuint unit = shader->SamplerUnits[s];
> +         GLuint tgt = shader->SamplerTargets[s];
>           assert(unit < Elements(prog->TexturesUsed));
>           assert(tgt < NUM_TEXTURE_TARGETS);
>           prog->TexturesUsed[unit] |= (1 << tgt);
> diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
> index 258b864..7e64db5 100644
> --- a/src/mesa/program/ir_to_mesa.cpp
> +++ b/src/mesa/program/ir_to_mesa.cpp
> @@ -2402,8 +2402,10 @@ print_program(struct prog_instruction *mesa_instructions,
>  class add_uniform_to_shader : public program_resource_visitor {
>  public:
>     add_uniform_to_shader(struct gl_shader_program *shader_program,
> -                        struct gl_program_parameter_list *params)
> -      : shader_program(shader_program), params(params), idx(-1)
> +                        struct gl_program_parameter_list *params,
> +                         gl_shader_type shader_type)
> +      : shader_program(shader_program), params(params), idx(-1),
> +        shader_type(shader_type)
>     {
>        /* empty */
>     }
> @@ -2423,6 +2425,7 @@ private:
>     struct gl_shader_program *shader_program;
>     struct gl_program_parameter_list *params;
>     int idx;
> +   gl_shader_type shader_type;
>  };
>
>  void
> @@ -2469,8 +2472,11 @@ add_uniform_to_shader::visit_field(const glsl_type *type, const char *name,
>          struct gl_uniform_storage *storage =
>             &this->shader_program->UniformStorage[location];
>
> +         assert(storage->sampler[shader_type].active);
> +
>          for (unsigned int j = 0; j < size / 4; j++)
> -           params->ParameterValues[index + j][0].f = storage->sampler + j;
> +            params->ParameterValues[index + j][0].f =
> +               storage->sampler[shader_type].index + j;
>        }
>     }
>
> @@ -2496,7 +2502,8 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
>                                             struct gl_program_parameter_list
>                                             *params)
>  {
> -   add_uniform_to_shader add(shader_program, params);
> +   add_uniform_to_shader add(shader_program, params,
> +                             _mesa_shader_type_to_index(sh->Type));
>
>     foreach_list(node, sh->ir) {
>        ir_variable *var = ((ir_instruction *) node)->as_variable();
> diff --git a/src/mesa/program/sampler.cpp b/src/mesa/program/sampler.cpp
> index e3641aa..1cf3061 100644
> --- a/src/mesa/program/sampler.cpp
> +++ b/src/mesa/program/sampler.cpp
> @@ -34,6 +34,7 @@ extern "C" {
>  #include "main/compiler.h"
>  #include "main/mtypes.h"
>  #include "program/prog_parameter.h"
> +#include "program/program.h"
>  }
>
>  class get_sampler_name : public ir_hierarchical_visitor
> @@ -102,14 +103,16 @@ public:
>     ir_dereference *last;
>  };
>
> -extern "C" {
> -int
> +
> +extern "C" int
>  _mesa_get_sampler_uniform_value(class ir_dereference *sampler,
>                                 struct gl_shader_program *shader_program,
>                                 const struct gl_program *prog)
>  {
>     get_sampler_name getname(sampler, shader_program);
>
> +   GLuint shader = _mesa_program_target_to_index(prog->Target);
> +
>     sampler->accept(&getname);
>
>     unsigned location;
> @@ -119,6 +122,14 @@ _mesa_get_sampler_uniform_value(class ir_dereference *sampler,
>        return 0;
>     }
>
> -   return shader_program->UniformStorage[location].sampler + getname.offset;
> -}
> +   if (!shader_program->UniformStorage[location].sampler[shader].active) {
> +      linker_error(shader_program,
> +                  "cannot return a sampler named %s, because it is not "
> +                   "used in this shader stage. This is a driver bug.\n",
> +                   getname.name);
> +      return 0;
> +   }
> +
> +   return shader_program->UniformStorage[location].sampler[shader].index +
> +          getname.offset;
>  }
> --
> 1.7.10.4
>


More information about the mesa-dev mailing list