[Mesa-dev] [PATCH V2] mesa: validate sampler type across the whole program

Nicolai Hähnle nhaehnle at gmail.com
Fri Apr 21 08:03:32 UTC 2017


On 21.04.2017 09:08, Timothy Arceri wrote:
> Currently we were only making sure types were the same within a
> single stage. This looks to have regressed with 953a0af8e3f73.
>
> V2: move the SamplersValidated reset into the common linker
>     code.
>
> https://bugs.freedesktop.org/show_bug.cgi?id=97524
> Cc: Tapani Pälli <tapani.palli at intel.com>
> ---
>  src/mesa/main/uniform_query.cpp |  2 ++
>  src/mesa/main/uniforms.c        | 26 +++++++++++++++++++++-----
>  src/mesa/program/ir_to_mesa.cpp |  5 +++++
>  3 files changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
> index c648832..e400d0e 100644
> --- a/src/mesa/main/uniform_query.cpp
> +++ b/src/mesa/main/uniform_query.cpp
> @@ -965,20 +965,22 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
>        }
>     }
>
>     _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
>
>     /* If the uniform is a sampler, do the extra magic necessary to propagate
>      * the changes through.
>      */
>     if (uni->type->is_sampler()) {
>        bool flushed = false;
> +      shProg->SamplersValidated = GL_TRUE;
> +
>        for (int i = 0; i < MESA_SHADER_STAGES; i++) {
>  	 struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
>
>  	 /* If the shader stage doesn't use the sampler uniform, skip this. */
>  	 if (!uni->opaque[i].active)
>  	    continue;
>
>           bool changed = false;
>           for (int j = 0; j < count; j++) {
>              unsigned unit = uni->opaque[i].index + offset + j;
> diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
> index 59ae4c5..8869b6e 100644
> --- a/src/mesa/main/uniforms.c
> +++ b/src/mesa/main/uniforms.c
> @@ -60,42 +60,58 @@
>   * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
>   * information to update the prog->TexturesUsed[] values.
>   * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
>   * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
>   * We'll use that info for state validation before rendering.
>   */
>  void
>  _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
>                                    struct gl_program *prog)
>  {
> -   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
> +   GLbitfield mask = prog->SamplersUsed;
> +   gl_shader_stage prog_stage =
> +      _mesa_program_enum_to_shader_stage(prog->Target);
> +   struct gl_linked_shader *shader = shProg->_LinkedShaders[prog_stage];
>
> -   shProg->SamplersValidated = GL_TRUE;
> +   assert(shader);
> +
> +   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
>
> -   GLbitfield mask = prog->SamplersUsed;
>     while (mask) {
>        const int s = u_bit_scan(&mask);
>        GLuint unit = prog->SamplerUnits[s];
>        GLuint tgt = prog->sh.SamplerTargets[s];
>        assert(unit < ARRAY_SIZE(prog->TexturesUsed));
>        assert(tgt < NUM_TEXTURE_TARGETS);
>
>        /* 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 (prog->TexturesUsed[unit] & ~(1 << tgt))
> -         shProg->SamplersValidated = GL_FALSE;
> +      unsigned stages_mask = shProg->data->linked_stages;
> +      while (stages_mask) {
> +         const int stage = u_bit_scan(&stages_mask);
> +
> +         /* Skip validation if we are yet to update textures used in this
> +          * stage.
> +          */
> +         if (prog_stage < stage)
> +            break;
> +
> +         struct gl_program *glprog = shProg->_LinkedShaders[stage]->Program;
> +         if (glprog->TexturesUsed[unit] & ~(1 << tgt))
> +            shProg->SamplersValidated = GL_FALSE;
> +      }
>
>        prog->TexturesUsed[unit] |= (1 << tgt);
>     }
>  }
>
>  /**
>   * Connect a piece of driver storage with a part of a uniform
>   *
>   * \param uni            The uniform with which the storage will be associated
>   * \param element_stride Byte-stride between array elements.
> diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
> index 6b33266..27507e8 100644
> --- a/src/mesa/program/ir_to_mesa.cpp
> +++ b/src/mesa/program/ir_to_mesa.cpp
> @@ -3110,20 +3110,25 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
>        if (!prog->Shaders[i]->CompileStatus) {
>  	 linker_error(prog, "linking with uncompiled shader");
>        }
>     }
>
>     if (prog->data->LinkStatus) {
>        link_shaders(ctx, prog);
>     }
>
>     if (prog->data->LinkStatus) {
> +      /* Reset sampler validated to true, validation happends via the

Typo: happends

With the update you mentioned, this is

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

> +       * LinkShader call below.
> +       */
> +      shProg->SamplersValidated = GL_TRUE;
> +
>        if (!ctx->Driver.LinkShader(ctx, prog)) {
>           prog->data->LinkStatus = linking_failure;
>        }
>     }
>
>     /* Return early if we are loading the shader from on-disk cache */
>     if (prog->data->LinkStatus == linking_skipped)
>        return;
>
>     if (ctx->_Shader->Flags & GLSL_DUMP) {
>


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list