mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-19 06:40:32 +01:00
i965: Handle nested uniform array indexing
When converting a uniform array reference to a pull constant load, the
`reladdr` expression itself may have its own `reladdr`, arbitrarily
deeply. This arises from expressions like:
a[b[x]] where a, b are uniform arrays (or lowered const arrays),
and x is not a constant.
Just iterate the lowering to pull constants until we stop seeing these
nested. For most shaders, there will be only one pass through this loop.
Fixes the piglit test:
tests/spec/glsl-1.20/linker/double-indirect-1.shader_test
Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Cc: "10.3 10.4" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
(cherry picked from commit adefccd12a)
Conflicts:
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
This commit is contained in:
parent
4aafdf30ba
commit
abccf91e5e
1 changed files with 38 additions and 33 deletions
|
|
@ -3427,10 +3427,8 @@ void
|
|||
vec4_visitor::move_uniform_array_access_to_pull_constants()
|
||||
{
|
||||
int pull_constant_loc[this->uniforms];
|
||||
|
||||
for (int i = 0; i < this->uniforms; i++) {
|
||||
pull_constant_loc[i] = -1;
|
||||
}
|
||||
memset(pull_constant_loc, -1, sizeof(pull_constant_loc));
|
||||
bool nested_reladdr;
|
||||
|
||||
/* Walk through and find array access of uniforms. Put a copy of that
|
||||
* uniform in the pull constant buffer.
|
||||
|
|
@ -3438,44 +3436,51 @@ vec4_visitor::move_uniform_array_access_to_pull_constants()
|
|||
* Note that we don't move constant-indexed accesses to arrays. No
|
||||
* testing has been done of the performance impact of this choice.
|
||||
*/
|
||||
foreach_in_list_safe(vec4_instruction, inst, &instructions) {
|
||||
for (int i = 0 ; i < 3; i++) {
|
||||
if (inst->src[i].file != UNIFORM || !inst->src[i].reladdr)
|
||||
continue;
|
||||
do {
|
||||
nested_reladdr = false;
|
||||
|
||||
int uniform = inst->src[i].reg;
|
||||
foreach_in_list_safe(vec4_instruction, inst, &instructions) {
|
||||
for (int i = 0 ; i < 3; i++) {
|
||||
if (inst->src[i].file != UNIFORM || !inst->src[i].reladdr)
|
||||
continue;
|
||||
|
||||
/* If this array isn't already present in the pull constant buffer,
|
||||
* add it.
|
||||
*/
|
||||
if (pull_constant_loc[uniform] == -1) {
|
||||
const gl_constant_value **values =
|
||||
&stage_prog_data->param[uniform * 4];
|
||||
int uniform = inst->src[i].reg;
|
||||
|
||||
pull_constant_loc[uniform] = stage_prog_data->nr_pull_params / 4;
|
||||
if (inst->src[i].reladdr->reladdr)
|
||||
nested_reladdr = true; /* will need another pass */
|
||||
|
||||
assert(uniform < uniform_array_size);
|
||||
for (int j = 0; j < uniform_size[uniform] * 4; j++) {
|
||||
stage_prog_data->pull_param[stage_prog_data->nr_pull_params++]
|
||||
= values[j];
|
||||
}
|
||||
}
|
||||
/* If this array isn't already present in the pull constant buffer,
|
||||
* add it.
|
||||
*/
|
||||
if (pull_constant_loc[uniform] == -1) {
|
||||
const gl_constant_value **values =
|
||||
&stage_prog_data->param[uniform * 4];
|
||||
|
||||
/* Set up the annotation tracking for new generated instructions. */
|
||||
base_ir = inst->ir;
|
||||
current_annotation = inst->annotation;
|
||||
pull_constant_loc[uniform] = stage_prog_data->nr_pull_params / 4;
|
||||
|
||||
dst_reg temp = dst_reg(this, glsl_type::vec4_type);
|
||||
assert(uniform < uniform_array_size);
|
||||
for (int j = 0; j < uniform_size[uniform] * 4; j++) {
|
||||
stage_prog_data->pull_param[stage_prog_data->nr_pull_params++]
|
||||
= values[j];
|
||||
}
|
||||
}
|
||||
|
||||
emit_pull_constant_load(inst, temp, inst->src[i],
|
||||
pull_constant_loc[uniform]);
|
||||
/* Set up the annotation tracking for new generated instructions. */
|
||||
base_ir = inst->ir;
|
||||
current_annotation = inst->annotation;
|
||||
|
||||
inst->src[i].file = temp.file;
|
||||
inst->src[i].reg = temp.reg;
|
||||
inst->src[i].reg_offset = temp.reg_offset;
|
||||
inst->src[i].reladdr = NULL;
|
||||
dst_reg temp = dst_reg(this, glsl_type::vec4_type);
|
||||
|
||||
emit_pull_constant_load(inst, temp, inst->src[i],
|
||||
pull_constant_loc[uniform]);
|
||||
|
||||
inst->src[i].file = temp.file;
|
||||
inst->src[i].reg = temp.reg;
|
||||
inst->src[i].reg_offset = temp.reg_offset;
|
||||
inst->src[i].reladdr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (nested_reladdr);
|
||||
|
||||
/* Now there are no accesses of the UNIFORM file with a reladdr, so
|
||||
* no need to track them as larger-than-vec4 objects. This will be
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue