[Mesa-dev] [PATCH] mesa: faster validation of sampler unit mapping for SSO

Timothy Arceri timothy.arceri at collabora.com
Sat Jun 25 03:54:56 UTC 2016


On Fri, 2016-06-24 at 10:07 +0200, Gregory Hainaut wrote:
> Code was inspired from _mesa_update_shader_textures_used
> 
> However unlike _mesa_update_shader_textures_used that only check for
> a single
> stage, it will check all stages.
> 
> It avoids to loop on all uniforms, only active samplers are checked.

Hi Gregory,

Is there any measurable change as a result of this? Normally
performance changes should come with some results in the commit
message.

Tim 

> 
> Signed-off-by: Gregory Hainaut <gregory.hainaut at gmail.com>
> ---
>  src/mesa/main/uniform_query.cpp | 69 ++++++++++++++++++-------------
> ----------
>  1 file changed, 31 insertions(+), 38 deletions(-)
> 
> diff --git a/src/mesa/main/uniform_query.cpp
> b/src/mesa/main/uniform_query.cpp
> index 127f097..4fa4e6e 100644
> --- a/src/mesa/main/uniform_query.cpp
> +++ b/src/mesa/main/uniform_query.cpp
> @@ -1068,58 +1068,51 @@
> _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object
> *pipeline)
>      *         - The number of active samplers in the program exceeds
> the
>      *           maximum number of texture image units allowed."
>      */
> +
> +   GLbitfield mask;
> +   GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
> +   struct gl_shader *shader;
>     unsigned active_samplers = 0;
>     const struct gl_shader_program **shProg =
>        (const struct gl_shader_program **) pipeline->CurrentProgram;
>  
> -   const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
> -   memset(unit_types, 0, sizeof(unit_types));
> +
> +   memset(TexturesUsed, 0, sizeof(TexturesUsed));
>  
>     for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline-
> >CurrentProgram); idx++) {
>        if (!shProg[idx])
>           continue;
>  
> -      for (unsigned i = 0; i < shProg[idx]->NumUniformStorage; i++)
> {
> -         const struct gl_uniform_storage *const storage =
> -            &shProg[idx]->UniformStorage[i];
> +      shader = shProg[idx]->_LinkedShaders[idx];
> +      if (!shader || !shader->Program)
> +         continue;
>  
> -         if (!storage->type->is_sampler())
> +      mask = shader->Program->SamplersUsed;
> +      while (mask) {
> +         const int s = u_bit_scan(&mask);
> +         GLuint unit = shader->SamplerUnits[s];
> +         GLuint tgt = shader->SamplerTargets[s];
> +
> +         /* FIXME: Samplers are initialized to 0 and Mesa doesn't do
> a
> +          * great job of eliminating unused uniforms currently so
> for now
> +          * don't throw an error if two sampler types both point to
> 0.
> +          */
> +         if (unit == 0)
>              continue;
>  
> -         active_samplers++;
> -
> -         const unsigned count = MAX2(1, storage->array_elements);
> -         for (unsigned j = 0; j < count; j++) {
> -            const unsigned unit = storage->storage[j].i;
> -
> -            /* FIXME: Samplers are initialized to 0 and Mesa doesn't
> do a
> -             * great job of eliminating unused uniforms currently so
> for now
> -             * don't throw an error if two sampler types both point
> to 0.
> -             */
> -            if (unit == 0)
> -               continue;
> -
> -            /* The types of the samplers associated with a
> particular texture
> -             * unit must be an exact match.  Page 74 (page 89 of the
> PDF) of
> -             * the OpenGL 3.3 core spec says:
> -             *
> -             *     "It is not allowed to have variables of different
> sampler
> -             *     types pointing to the same texture image unit
> within a
> -             *     program object."
> -             */
> -            if (unit_types[unit] == NULL) {
> -               unit_types[unit] = storage->type;
> -            } else if (unit_types[unit] != storage->type) {
> -               pipeline->InfoLog =
> -                  ralloc_asprintf(pipeline,
> -                                  "Texture unit %d is accessed both
> as %s "
> -                                  "and %s",
> -                                  unit, unit_types[unit]->name,
> -                                  storage->type->name);
> -               return false;
> -            }
> +         if (TexturesUsed[unit] & ~(1 << tgt)) {
> +            pipeline->InfoLog =
> +               ralloc_asprintf(pipeline,
> +                     "Program %d: "
> +                     "Texture unit %d is accessed with 2 different
> types",
> +                     shProg[idx]->Name, unit);
> +            return false;
>           }
> +
> +         TexturesUsed[unit] |= (1 << tgt);
>        }
> +
> +      active_samplers += shader->num_samplers;
>     }
>  
>     if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {


More information about the mesa-dev mailing list