summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2012-04-17 11:56:26 -0700
committerIan Romanick <ian.d.romanick@intel.com>2012-07-06 09:57:07 -0700
commit9b38691927b9f26503ac70e1731182a6a09950ab (patch)
tree1966c3afef9cd2aa4d9c67dda96b3adf50d20226
parent6f1218385a2882574484104f4e135068e584d3dd (diff)
downloadmesa-9b38691927b9f26503ac70e1731182a6a09950ab.tar.gz
i965/vs: Fix texelFetchOffset()
It appears that when using 'ld' with the offset bits, address bounds checking happens before the offset is applied, so parts of the drawing in piglit texelFetchOffset() with a negative texcoord go black. (cherry picked from commit 4650aea7a536ddce120576fadb91845076e8e37a)
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 4eee22543cc..b4775377178 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -1820,7 +1820,7 @@ vec4_visitor::visit(ir_texture *ir)
inst->dst = dst_reg(this, ir->type);
inst->shadow_compare = ir->shadow_comparitor != NULL;
- if (ir->offset != NULL)
+ if (ir->offset != NULL && !(intel->gen >= 7 && ir->op == ir_txf))
inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
/* MRF for the first parameter */
@@ -1841,8 +1841,28 @@ vec4_visitor::visit(ir_texture *ir)
zero_mask |= (1 << i);
ir->coordinate->accept(this);
- emit(MOV(dst_reg(MRF, param_base, ir->coordinate->type, coord_mask),
- this->result));
+ if (ir->offset && intel->gen >= 7 && ir->op == ir_txf) {
+ /* It appears that the ld instruction used for txf does its
+ * address bounds check before adding in the offset. To work
+ * around this, just add the integer offset to the integer
+ * texel coordinate, and don't put the offset in the header.
+ */
+ ir_constant *offset = ir->offset->as_constant();
+ assert(offset);
+
+ for (int j = 0; j < ir->coordinate->type->vector_elements; j++) {
+ src_reg src = this->result;
+ src.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(src.swizzle, j),
+ BRW_GET_SWZ(src.swizzle, j),
+ BRW_GET_SWZ(src.swizzle, j),
+ BRW_GET_SWZ(src.swizzle, j));
+ emit(ADD(dst_reg(MRF, param_base, ir->coordinate->type, 1 << j),
+ src, offset->value.i[j]));
+ }
+ } else {
+ emit(MOV(dst_reg(MRF, param_base, ir->coordinate->type, coord_mask),
+ this->result));
+ }
emit(MOV(dst_reg(MRF, param_base, ir->coordinate->type, zero_mask),
src_reg(0)));
/* Load the shadow comparitor */