diff options
-rw-r--r-- | src/glsl/glsl_parser_extras.cpp | 23 | ||||
-rw-r--r-- | src/glsl/ir_optimization.h | 6 | ||||
-rw-r--r-- | src/glsl/linker.cpp | 2 | ||||
-rw-r--r-- | src/glsl/main.cpp | 2 | ||||
-rw-r--r-- | src/glsl/opt_dead_code.cpp | 14 | ||||
-rw-r--r-- | src/glsl/test_optpass.cpp | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_shader.cpp | 3 | ||||
-rw-r--r-- | src/mesa/main/ff_fragment_shader.cpp | 2 | ||||
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 6 | ||||
-rw-r--r-- | 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 a9075b2b1be..e2112fe6dd0 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 af80e26b9ff..7b32e84f0d8 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 a7c38a3426a..d4d2496fedd 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 01921375070..e174224712b 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 cb500d2d105..5b9546ad409 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 89b7f8338dc..6abafb5d311 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 0858c4032bb..d9d9414543d 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 160a97c0cae..3e449b03e9c 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 fecab50f753..635ebdd53f4 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 35fd1ffc13a..145bd7dcd0c 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; |