[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