summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Forbes <chrisf@ijw.co.nz>2014-11-18 21:15:06 +1300
committerEmil Velikov <emil.l.velikov@gmail.com>2014-11-26 21:15:08 +0000
commitabccf91e5efeb8173c6a6d0e4e9b36166d2845d8 (patch)
tree3f25389ee893b5c3ceac0b2ca431781a8265d035
parent4aafdf30bafb67c12c470e04cf91ce72bf2459be (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.cpp71
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