glsl: handle max uniform limits with lower_const_arrays_to_uniforms

Fixes arb_tessellation_shader-large-uniforms Piglit test.

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Tapani Pälli
2019-11-08 08:17:17 +02:00
parent 4cde0e04e3
commit d61a21f439
3 changed files with 41 additions and 6 deletions

View File

@@ -140,7 +140,7 @@ bool lower_variable_index_to_cond_assign(gl_shader_stage stage,
exec_list *instructions, bool lower_input, bool lower_output, exec_list *instructions, bool lower_input, bool lower_output,
bool lower_temp, bool lower_uniform); bool lower_temp, bool lower_uniform);
bool lower_quadop_vector(exec_list *instructions, bool dont_lower_swz); 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, bool lower_clip_cull_distance(struct gl_shader_program *prog,
gl_linked_shader *shader); gl_linked_shader *shader);
void lower_output_reads(unsigned stage, exec_list *instructions); void lower_output_reads(unsigned stage, exec_list *instructions);

View File

@@ -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. */ /* Call opts after lowering const arrays to copy propagate things. */
if (ctx->Const.GLSLLowerConstArrays && 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); linker_optimisation_loop(ctx, prog->_LinkedShaders[i]->ir, i);
} }
/* Validation for special cases where we allow sampler array indexing /* Validation for special cases where we allow sampler array indexing

View File

@@ -45,11 +45,13 @@
namespace { namespace {
class lower_const_array_visitor : public ir_rvalue_visitor { class lower_const_array_visitor : public ir_rvalue_visitor {
public: 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; instructions = insts;
stage = s; stage = s;
const_count = 0; const_count = 0;
free_uni_components = available_uni_components;
progress = false; progress = false;
} }
@@ -66,6 +68,7 @@ private:
exec_list *instructions; exec_list *instructions;
unsigned stage; unsigned stage;
unsigned const_count; unsigned const_count;
unsigned free_uni_components;
bool progress; bool progress;
}; };
@@ -85,6 +88,15 @@ lower_const_array_visitor::handle_rvalue(ir_rvalue **rvalue)
if (!con || !con->type->is_array()) if (!con || !con->type->is_array())
return; 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); void *mem_ctx = ralloc_parent(con);
/* In the very unlikely event of 4294967295 constant arrays in a single /* 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 */ } /* anonymous namespace */
bool
lower_const_arrays_to_uniforms(exec_list *instructions, unsigned stage) static unsigned
count_uniforms(exec_list *instructions)
{ {
lower_const_array_visitor v(instructions, stage); 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,
unsigned max_uniform_components)
{
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(); return v.run();
} }