summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2012-06-04 14:07:13 -0700
committerKenneth Graunke <kenneth@whitecape.org>2012-06-05 14:41:34 -0700
commit217b62bf001f6b1da31807b803bbe45d7cabe3ba (patch)
treeaf88429058d1de39cb36a193e4ed4617d85c1bbf
parent7fde071f04afff86d4f8d7895073e22e60970b4e (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 <kenneth@whitecape.org>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp40
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 275a1f4ef8..845ab49972 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;