[Mesa-dev] [PATCH 1/2] glsl: Add uniform_locations_assigned parameter to do_dead_code opt pass

Yuanhan Liu yuanhan.liu at linux.intel.com
Sun Oct 23 19:18:16 PDT 2011


On Fri, Oct 21, 2011 at 11:49:43AM -0700, Ian Romanick wrote:
> From: Ian Romanick <ian.d.romanick at 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.liu at linux.intel.com>


> 
> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=41980
> Cc: Brian Paul <brianp at vmware.com>
> Cc: Bryan Cain <bryancain3 at gmail.com>
> Cc: Vinson Lee <vlee at vmware.com>
> Cc: José Fonseca <jfonseca at vmware.com>
> Cc: Kenneth Graunke <kenneth at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list