[Mesa-dev] [PATCH 1/2] i965/fs: Fix texelFetchOffset() on pre-Gen7.

Kenneth Graunke kenneth at whitecape.org
Mon Jun 4 23:15:10 CEST 2012


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 at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp |   45 +++++++++++++++++++-------
 1 file changed, 33 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 275a1f4..8d124a0 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -884,20 +884,41 @@ 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--;
-   }
+      int offsets[3];
+      ir_constant *offset = ir->offset->as_constant();
+      offsets[0] = offset->value.i[0];
+      offsets[1] = offset->value.i[1];
+      offsets[2] = offset->value.i[2];
 
-   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_ADD,
+	      fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type),
+	      coordinate,
+	      offsets[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++;
+      }
    }
    mlen += vector_elements * reg_width;
 
-- 
1.7.10.3



More information about the mesa-dev mailing list