This is a problem when we have IR like this: (array_ref (var_ref temps) (swiz x (expression ivec4 bitcast_f2i (swiz xxxx (array_ref (var_ref temps) (constant int (2)) ) )) )) ) )
where we are indexing an array with the result of an expression that accesses the same array. In this scenario, temps will be moved to scratch space and we will need to add scratch reads/writes for all accesses to temps, however, the current implementation does not consider the case where a reladdr pointer (obtained by indexing into temps trough a expression) points to a register that is also stored in scratch space (as in this case, where the expression used to index temps access temps[2]), and thus, requires a scratch read before it is accessed. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89508 --- src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index 5bf9e1b..b345864 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -3426,6 +3426,19 @@ vec4_visitor::move_grf_array_access_to_scratch() base_ir = inst->ir; current_annotation = inst->annotation; + /* If our reladdr points to scratch space, then we have to load + * it too before we use it + */ + if (inst->dst.reladdr && + inst->dst.reladdr->file == GRF && + inst->dst.reladdr->reg < this->alloc.count && + scratch_loc[inst->dst.reladdr->reg] != -1) { + dst_reg temp = dst_reg(this, glsl_type::vec4_type); + emit_scratch_read(block, inst, temp, *inst->dst.reladdr, + scratch_loc[inst->dst.reladdr->reg]); + memcpy(inst->dst.reladdr, &temp, sizeof(temp)); + } + if (inst->dst.file == GRF && scratch_loc[inst->dst.reg] != -1) { emit_scratch_write(block, inst, scratch_loc[inst->dst.reg]); } @@ -3434,6 +3447,19 @@ vec4_visitor::move_grf_array_access_to_scratch() if (inst->src[i].file != GRF || scratch_loc[inst->src[i].reg] == -1) continue; + /* If our reladdr points to scratch space, then we have to load + * it too before we use it + */ + if (inst->src[i].reladdr && + inst->src[i].reladdr->file == GRF && + inst->src[i].reladdr->reg < this->alloc.count && + scratch_loc[inst->src[i].reladdr->reg] != -1) { + dst_reg temp = dst_reg(this, glsl_type::vec4_type); + emit_scratch_read(block, inst, temp, *inst->src[i].reladdr, + scratch_loc[inst->src[i].reladdr->reg]); + memcpy(inst->src[i].reladdr, &temp, sizeof(temp)); + } + dst_reg temp = dst_reg(this, glsl_type::vec4_type); emit_scratch_read(block, inst, temp, inst->src[i], -- 1.9.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev