diff options
-rw-r--r-- | src/compiler/glsl/ir_optimization.h | 2 | ||||
-rw-r--r-- | src/compiler/glsl/linker.cpp | 4 | ||||
-rw-r--r-- | src/compiler/glsl/lower_const_arrays_to_uniforms.cpp | 39 |
3 files changed, 40 insertions, 5 deletions
diff --git a/src/compiler/glsl/ir_optimization.h b/src/compiler/glsl/ir_optimization.h index e027654d3a0..cd0be38e56f 100644 --- a/src/compiler/glsl/ir_optimization.h +++ b/src/compiler/glsl/ir_optimization.h @@ -140,7 +140,7 @@ bool lower_variable_index_to_cond_assign(gl_shader_stage stage, exec_list *instructions, bool lower_input, bool lower_output, bool lower_temp, bool lower_uniform); bool lower_quadop_vector(exec_list *instructions, bool dont_lower_swz); -bool lower_const_arrays_to_uniforms(exec_list *instructions, unsigned stage); +bool lower_const_arrays_to_uniforms(exec_list *instructions, unsigned stage, unsigned max_uniform_components); bool lower_clip_cull_distance(struct gl_shader_program *prog, gl_linked_shader *shader); void lower_output_reads(unsigned stage, exec_list *instructions); diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 977d91f5118..912d15c825e 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -5196,8 +5196,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) /* Call opts after lowering const arrays to copy propagate things. */ if (ctx->Const.GLSLLowerConstArrays && - lower_const_arrays_to_uniforms(prog->_LinkedShaders[i]->ir, i)) + lower_const_arrays_to_uniforms(prog->_LinkedShaders[i]->ir, i, + ctx->Const.Program[i].MaxUniformComponents)) linker_optimisation_loop(ctx, prog->_LinkedShaders[i]->ir, i); + } /* Validation for special cases where we allow sampler array indexing diff --git a/src/compiler/glsl/lower_const_arrays_to_uniforms.cpp b/src/compiler/glsl/lower_const_arrays_to_uniforms.cpp index 73b9b542448..dbca6321bea 100644 --- a/src/compiler/glsl/lower_const_arrays_to_uniforms.cpp +++ b/src/compiler/glsl/lower_const_arrays_to_uniforms.cpp @@ -45,11 +45,13 @@ namespace { class lower_const_array_visitor : public ir_rvalue_visitor { public: - lower_const_array_visitor(exec_list *insts, unsigned s) + lower_const_array_visitor(exec_list *insts, unsigned s, + unsigned available_uni_components) { instructions = insts; stage = s; const_count = 0; + free_uni_components = available_uni_components; progress = false; } @@ -66,6 +68,7 @@ private: exec_list *instructions; unsigned stage; unsigned const_count; + unsigned free_uni_components; bool progress; }; @@ -85,6 +88,15 @@ lower_const_array_visitor::handle_rvalue(ir_rvalue **rvalue) if (!con || !con->type->is_array()) return; + /* How many uniform component slots are required? */ + unsigned component_slots = con->type->component_slots(); + + /* We would utilize more than is available, bail out. */ + if (component_slots > free_uni_components) + return; + + free_uni_components -= component_slots; + void *mem_ctx = ralloc_parent(con); /* In the very unlikely event of 4294967295 constant arrays in a single @@ -116,9 +128,30 @@ lower_const_array_visitor::handle_rvalue(ir_rvalue **rvalue) } /* anonymous namespace */ + +static unsigned +count_uniforms(exec_list *instructions) +{ + unsigned total = 0; + + foreach_in_list(ir_instruction, node, instructions) { + ir_variable *const var = node->as_variable(); + + if (!var || var->data.mode != ir_var_uniform) + continue; + + total += var->type->component_slots(); + } + return total; +} + bool -lower_const_arrays_to_uniforms(exec_list *instructions, unsigned stage) +lower_const_arrays_to_uniforms(exec_list *instructions, unsigned stage, + unsigned max_uniform_components) { - lower_const_array_visitor v(instructions, stage); + unsigned uniform_components = count_uniforms(instructions); + unsigned free_uniform_slots = max_uniform_components - uniform_components; + + lower_const_array_visitor v(instructions, stage, free_uniform_slots); return v.run(); } |