diff options
author | Chris Forbes <chrisf@ijw.co.nz> | 2014-11-18 21:15:06 +1300 |
---|---|---|
committer | Emil Velikov <emil.l.velikov@gmail.com> | 2014-11-26 21:15:08 +0000 |
commit | abccf91e5efeb8173c6a6d0e4e9b36166d2845d8 (patch) | |
tree | 3f25389ee893b5c3ceac0b2ca431781a8265d035 | |
parent | 4aafdf30bafb67c12c470e04cf91ce72bf2459be (diff) |
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 adefccd12a534f0deac7b78db73693fe1dcef2ec)
Conflicts:
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 71 |
1 files changed, 38 insertions, 33 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index 4ed1e8cd0a6..aff2a0c4435 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -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 |