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>
This commit is contained in:
parent
c88385603a
commit
adefccd12a
|
@ -3353,6 +3353,7 @@ vec4_visitor::move_uniform_array_access_to_pull_constants()
|
||||||
{
|
{
|
||||||
int pull_constant_loc[this->uniforms];
|
int pull_constant_loc[this->uniforms];
|
||||||
memset(pull_constant_loc, -1, sizeof(pull_constant_loc));
|
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
|
/* Walk through and find array access of uniforms. Put a copy of that
|
||||||
* uniform in the pull constant buffer.
|
* uniform in the pull constant buffer.
|
||||||
|
@ -3360,44 +3361,51 @@ vec4_visitor::move_uniform_array_access_to_pull_constants()
|
||||||
* Note that we don't move constant-indexed accesses to arrays. No
|
* Note that we don't move constant-indexed accesses to arrays. No
|
||||||
* testing has been done of the performance impact of this choice.
|
* testing has been done of the performance impact of this choice.
|
||||||
*/
|
*/
|
||||||
foreach_block_and_inst_safe(block, vec4_instruction, inst, cfg) {
|
do {
|
||||||
for (int i = 0 ; i < 3; i++) {
|
nested_reladdr = false;
|
||||||
if (inst->src[i].file != UNIFORM || !inst->src[i].reladdr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int uniform = inst->src[i].reg;
|
foreach_block_and_inst_safe(block, vec4_instruction, inst, cfg) {
|
||||||
|
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,
|
int uniform = inst->src[i].reg;
|
||||||
* add it.
|
|
||||||
*/
|
|
||||||
if (pull_constant_loc[uniform] == -1) {
|
|
||||||
const gl_constant_value **values =
|
|
||||||
&stage_prog_data->param[uniform * 4];
|
|
||||||
|
|
||||||
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);
|
/* If this array isn't already present in the pull constant buffer,
|
||||||
for (int j = 0; j < uniform_size[uniform] * 4; j++) {
|
* add it.
|
||||||
stage_prog_data->pull_param[stage_prog_data->nr_pull_params++]
|
*/
|
||||||
= values[j];
|
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. */
|
pull_constant_loc[uniform] = stage_prog_data->nr_pull_params / 4;
|
||||||
base_ir = inst->ir;
|
|
||||||
current_annotation = inst->annotation;
|
|
||||||
|
|
||||||
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(block, inst, temp, inst->src[i],
|
/* Set up the annotation tracking for new generated instructions. */
|
||||||
pull_constant_loc[uniform]);
|
base_ir = inst->ir;
|
||||||
|
current_annotation = inst->annotation;
|
||||||
|
|
||||||
inst->src[i].file = temp.file;
|
dst_reg temp = dst_reg(this, glsl_type::vec4_type);
|
||||||
inst->src[i].reg = temp.reg;
|
|
||||||
inst->src[i].reg_offset = temp.reg_offset;
|
emit_pull_constant_load(block, inst, temp, inst->src[i],
|
||||||
inst->src[i].reladdr = NULL;
|
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
|
/* 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
|
* no need to track them as larger-than-vec4 objects. This will be
|
||||||
|
|
Loading…
Reference in New Issue