On Fri, Oct 21, 2011 at 11:49:43AM -0700, Ian Romanick wrote:
> From: Ian Romanick <ian.d.roman...@intel.com>
> 
> Setting this flag prevents declarations of uniforms from being removed
> from the IR.  Since the IR is directly used by several API functions
> that query uniforms in shaders, uniform declarations cannot be removed
> after the locations have been set.  However, it should still be safe
> to reorder the declarations (this is not tested).

I was debugging this issue(uniform var removed) yesterday. One thing I didn't
understand is why it would fail the test:

72      if ((entry->referenced_count > entry->assigned_count)
73           || !entry->declaration) 
74         continue; 

I found the entry->referenced_count and entry->assigned_count both with
value of 0.

Here is the test shader:

#version 120
varying vec4 Color_out;
uniform vec4 expVal;
uniform sampler2D samp;
void main() {
        vec4 v = texture2D(samp, gl_TexCoord[0].xy);
        if ((expVal.r - v.r) != 0 &&
            (expVal.g - v.g) != 0 &&
            (expVal.b - v.b) != 0 &&
            (expVal.a - v.a) != 0) {
                Color_out = vec4(1.0, 0.0, 0.0, 1.0);
        } else {
                Color_out = v;
        }
        gl_Position = gl_Vertex;
}

#version 120
uniform vec4 expVal;
uniform sampler2D samp;
void main() {
        vec4 v = texture2D(samp, gl_TexCoord[0].xy);
        if ((expVal.r - v.r) != 0 &&
            (expVal.g - v.g) != 0 &&
            (expVal.b - v.b) != 0 &&
            (expVal.a - v.a) != 0) {
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        } else {
                gl_FragColor = v;
        }
}

I found that both samp and expVal are removed. This patch fix this
issue, though I still didn't get it why the refereneced_count would
be 0.  So,

Reviewed-by: Yuanhan Liu <yuanhan....@linux.intel.com>


> 
> Signed-off-by: Ian Romanick <ian.d.roman...@intel.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=41980
> Cc: Brian Paul <bri...@vmware.com>
> Cc: Bryan Cain <bryanca...@gmail.com>
> Cc: Vinson Lee <v...@vmware.com>
> Cc: José Fonseca <jfons...@vmware.com>
> Cc: Kenneth Graunke <kenn...@whitecape.org>
> ---
>  src/glsl/glsl_parser_extras.cpp            |   23 +++++++++++++++++++++--
>  src/glsl/ir_optimization.h                 |    6 ++++--
>  src/glsl/linker.cpp                        |    2 +-
>  src/glsl/main.cpp                          |    2 +-
>  src/glsl/opt_dead_code.cpp                 |   14 ++++++++++----
>  src/glsl/test_optpass.cpp                  |    4 ++--
>  src/mesa/drivers/dri/i965/brw_shader.cpp   |    3 ++-
>  src/mesa/main/ff_fragment_shader.cpp       |    2 +-
>  src/mesa/program/ir_to_mesa.cpp            |    6 ++++--
>  src/mesa/state_tracker/st_glsl_to_tgsi.cpp |    4 +++-
>  10 files changed, 49 insertions(+), 17 deletions(-)
> 
> diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
> index a9075b2..e2112fe 100644
> --- a/src/glsl/glsl_parser_extras.cpp
> +++ b/src/glsl/glsl_parser_extras.cpp
> @@ -883,8 +883,27 @@ ast_struct_specifier::ast_struct_specifier(char 
> *identifier,
>     this->declarations.push_degenerate_list_at_head(&declarator_list->link);
>  }
>  
> +/**
> + * Do the set of common optimizations passes
> + *
> + * \param ir                          List of instructions to be optimized
> + * \param linked                      Is the shader linked?  This enables
> + *                                    optimizations passes that remove code 
> at
> + *                                    global scope and could cause linking to
> + *                                    fail.
> + * \param uniform_locations_assigned  Have locations already been assigned 
> for
> + *                                    uniforms?  This prevents the 
> declarations
> + *                                    of unused uniforms from being removed.
> + *                                    The setting of this flag only matters 
> if
> + *                                    \c linked is \c true.
> + * \param max_unroll_iterations       Maximum number of loop iterations to be
> + *                                    unrolled.  Setting to 0 forces all 
> loops
> + *                                    to be unrolled.
> + */
>  bool
> -do_common_optimization(exec_list *ir, bool linked, unsigned 
> max_unroll_iterations)
> +do_common_optimization(exec_list *ir, bool linked,
> +                    bool uniform_locations_assigned,
> +                    unsigned max_unroll_iterations)
>  {
>     GLboolean progress = GL_FALSE;
>  
> @@ -900,7 +919,7 @@ do_common_optimization(exec_list *ir, bool linked, 
> unsigned max_unroll_iteration
>     progress = do_copy_propagation(ir) || progress;
>     progress = do_copy_propagation_elements(ir) || progress;
>     if (linked)
> -      progress = do_dead_code(ir) || progress;
> +      progress = do_dead_code(ir, uniform_locations_assigned) || progress;
>     else
>        progress = do_dead_code_unlinked(ir) || progress;
>     progress = do_dead_code_local(ir) || progress;
> diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
> index af80e26..7b32e84 100644
> --- a/src/glsl/ir_optimization.h
> +++ b/src/glsl/ir_optimization.h
> @@ -37,7 +37,9 @@
>  #define MOD_TO_FRACT       0x20
>  #define INT_DIV_TO_MUL_RCP 0x40
>  
> -bool do_common_optimization(exec_list *ir, bool linked, unsigned 
> max_unroll_iterations);
> +bool do_common_optimization(exec_list *ir, bool linked,
> +                         bool uniform_locations_assigned,
> +                         unsigned max_unroll_iterations);
>  
>  bool do_algebraic(exec_list *instructions);
>  bool do_constant_folding(exec_list *instructions);
> @@ -46,7 +48,7 @@ bool do_constant_variable_unlinked(exec_list *instructions);
>  bool do_copy_propagation(exec_list *instructions);
>  bool do_copy_propagation_elements(exec_list *instructions);
>  bool do_constant_propagation(exec_list *instructions);
> -bool do_dead_code(exec_list *instructions);
> +bool do_dead_code(exec_list *instructions, bool uniform_locations_assigned);
>  bool do_dead_code_local(exec_list *instructions);
>  bool do_dead_code_unlinked(exec_list *instructions);
>  bool do_dead_functions(exec_list *instructions);
> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
> index a7c38a3..d4d2496 100644
> --- a/src/glsl/linker.cpp
> +++ b/src/glsl/linker.cpp
> @@ -1742,7 +1742,7 @@ link_shaders(struct gl_context *ctx, struct 
> gl_shader_program *prog)
>        if (ctx->ShaderCompilerOptions[i].LowerClipDistance)
>           lower_clip_distance(prog->_LinkedShaders[i]->ir);
>  
> -      while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32))
> +      while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 
> false, 32))
>        ;
>     }
>  
> diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp
> index 0192137..e174224 100644
> --- a/src/glsl/main.cpp
> +++ b/src/glsl/main.cpp
> @@ -166,7 +166,7 @@ compile_shader(struct gl_context *ctx, struct gl_shader 
> *shader)
>     if (!state->error && !shader->ir->is_empty()) {
>        bool progress;
>        do {
> -      progress = do_common_optimization(shader->ir, false, 32);
> +      progress = do_common_optimization(shader->ir, false, false, 32);
>        } while (progress);
>  
>        validate_ir_tree(shader->ir);
> diff --git a/src/glsl/opt_dead_code.cpp b/src/glsl/opt_dead_code.cpp
> index cb500d2..5b9546a 100644
> --- a/src/glsl/opt_dead_code.cpp
> +++ b/src/glsl/opt_dead_code.cpp
> @@ -42,7 +42,7 @@ static bool debug = false;
>   * for usage on an unlinked instruction stream.
>   */
>  bool
> -do_dead_code(exec_list *instructions)
> +do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
>  {
>     ir_variable_refcount_visitor v;
>     bool progress = false;
> @@ -94,10 +94,11 @@ do_dead_code(exec_list *instructions)
>         */
>  
>        /* uniform initializers are precious, and could get used by another
> -       * stage.
> +       * stage.  Also, once uniform locations have been assigned, the
> +       * declaration cannot be deleted.
>         */
>        if (entry->var->mode == ir_var_uniform &&
> -          entry->var->constant_value)
> +          (uniform_locations_assigned || entry->var->constant_value))
>           continue;
>  
>        entry->var->remove();
> @@ -132,7 +133,12 @@ do_dead_code_unlinked(exec_list *instructions)
>        foreach_iter(exec_list_iterator, sigiter, *f) {
>           ir_function_signature *sig =
>              (ir_function_signature *) sigiter.get();
> -         if (do_dead_code(&sig->body))
> +         /* The setting of the uniform_locations_assigned flag here is
> +          * irrelevent.  If there is a uniform declaration encountered
> +          * inside the body of the function, something has already gone
> +          * terribly, terribly wrong.
> +          */
> +         if (do_dead_code(&sig->body, false))
>              progress = true;
>        }
>        }
> diff --git a/src/glsl/test_optpass.cpp b/src/glsl/test_optpass.cpp
> index 89b7f83..6abafb5 100644
> --- a/src/glsl/test_optpass.cpp
> +++ b/src/glsl/test_optpass.cpp
> @@ -64,7 +64,7 @@ do_optimization(struct exec_list *ir, const char 
> *optimization)
>  
>     if (sscanf(optimization, "do_common_optimization ( %d , %d ) ",
>                &int_0, &int_1) == 2) {
> -      return do_common_optimization(ir, int_0 != 0, int_1);
> +      return do_common_optimization(ir, int_0 != 0, false, int_1);
>     } else if (strcmp(optimization, "do_algebraic") == 0) {
>        return do_algebraic(ir);
>     } else if (strcmp(optimization, "do_constant_folding") == 0) {
> @@ -80,7 +80,7 @@ do_optimization(struct exec_list *ir, const char 
> *optimization)
>     } else if (strcmp(optimization, "do_constant_propagation") == 0) {
>        return do_constant_propagation(ir);
>     } else if (strcmp(optimization, "do_dead_code") == 0) {
> -      return do_dead_code(ir);
> +      return do_dead_code(ir, false);
>     } else if (strcmp(optimization, "do_dead_code_local") == 0) {
>        return do_dead_code_local(ir);
>     } else if (strcmp(optimization, "do_dead_code_unlinked") == 0) {
> diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp 
> b/src/mesa/drivers/dri/i965/brw_shader.cpp
> index 0858c40..d9d9414 100644
> --- a/src/mesa/drivers/dri/i965/brw_shader.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
> @@ -138,7 +138,8 @@ brw_link_shader(struct gl_context *ctx, struct 
> gl_shader_program *prog)
>                                  false /* loops */
>                                  ) || progress;
>  
> -      progress = do_common_optimization(shader->ir, true, 32) || progress;
> +      progress = do_common_optimization(shader->ir, true, true, 32)
> +        || progress;
>        } while (progress);
>  
>        validate_ir_tree(shader->ir);
> diff --git a/src/mesa/main/ff_fragment_shader.cpp 
> b/src/mesa/main/ff_fragment_shader.cpp
> index 160a97c..3e449b0 100644
> --- a/src/mesa/main/ff_fragment_shader.cpp
> +++ b/src/mesa/main/ff_fragment_shader.cpp
> @@ -1464,7 +1464,7 @@ create_new_program(struct gl_context *ctx, struct 
> state_key *key)
>  
>     validate_ir_tree(p.shader->ir);
>  
> -   while (do_common_optimization(p.shader->ir, false, 32))
> +   while (do_common_optimization(p.shader->ir, false, false, 32))
>        ;
>     reparent_ir(p.shader->ir, p.shader->ir);
>  
> diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
> index fecab50..635ebdd 100644
> --- a/src/mesa/program/ir_to_mesa.cpp
> +++ b/src/mesa/program/ir_to_mesa.cpp
> @@ -3212,7 +3212,9 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct 
> gl_shader_program *prog)
>  
>        progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, 
> options->EmitNoCont, options->EmitNoLoops) || progress;
>  
> -      progress = do_common_optimization(ir, true, 
> options->MaxUnrollIterations) || progress;
> +      progress = do_common_optimization(ir, true, true,
> +                                        options->MaxUnrollIterations)
> +        || progress;
>  
>        progress = lower_quadop_vector(ir, true) || progress;
>  
> @@ -3321,7 +3323,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, 
> struct gl_shader *shader)
>        /* Do some optimization at compile time to reduce shader IR size
>         * and reduce later work if the same shader is linked multiple times
>         */
> -      while (do_common_optimization(shader->ir, false, 32))
> +      while (do_common_optimization(shader->ir, false, false, 32))
>        ;
>  
>        validate_ir_tree(shader->ir);
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
> b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 35fd1ff..145bd7d 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -5058,7 +5058,9 @@ st_link_shader(struct gl_context *ctx, struct 
> gl_shader_program *prog)
>  
>           progress = do_lower_jumps(ir, true, true, 
> options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || 
> progress;
>  
> -         progress = do_common_optimization(ir, true, 
> options->MaxUnrollIterations) || progress;
> +         progress = do_common_optimization(ir, true, true,
> +                                        options->MaxUnrollIterations)
> +        || progress;
>  
>           progress = lower_quadop_vector(ir, false) || progress;
>  
> -- 
> 1.7.6.4
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to