diff options
author | Kenneth Graunke <[email protected]> | 2012-06-04 14:07:13 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2012-06-05 14:41:34 -0700 |
commit | 217b62bf001f6b1da31807b803bbe45d7cabe3ba (patch) | |
tree | af88429058d1de39cb36a193e4ed4617d85c1bbf /src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | |
parent | 7fde071f04afff86d4f8d7895073e22e60970b4e (diff) |
i965/fs: Fix texelFetchOffset() on pre-Gen7.
Commit f41ecade7b458c02d504158b522acb2231585040 fixed texelFetchOffset()
on Ivybridge, but didn't update the Ironlake/Sandybridge code.
+15 piglits on Sandybridge.
NOTE: This and f41ecade7b458 are both candidates for stable branches.
Signed-off-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_fs_visitor.cpp')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 275a1f4ef83..845ab49972c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -884,20 +884,36 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, const int vector_elements = ir->coordinate ? ir->coordinate->type->vector_elements : 0; - if (ir->offset) { - /* The offsets set up by the ir_texture visitor are in the - * m1 header, so we can't go headerless. + if (ir->offset != NULL && 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. */ - header_present = true; - mlen++; - base_mrf--; - } + ir_constant *offset = ir->offset->as_constant(); + for (int i = 0; i < vector_elements; i++) { + emit(BRW_OPCODE_ADD, + fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type), + coordinate, + offset->value.i[i]); + coordinate.reg_offset++; + } + } else { + if (ir->offset) { + /* The offsets set up by the ir_texture visitor are in the + * m1 header, so we can't go headerless. + */ + header_present = true; + mlen++; + base_mrf--; + } - for (int i = 0; i < vector_elements; i++) { - emit(BRW_OPCODE_MOV, - fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type), - coordinate); - coordinate.reg_offset++; + for (int i = 0; i < vector_elements; i++) { + emit(BRW_OPCODE_MOV, + fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type), + coordinate); + coordinate.reg_offset++; + } } mlen += vector_elements * reg_width; |