Mesa (master): i965: Emit texel offsets in sampler messages.

Kenneth Graunke kwg at kemper.freedesktop.org
Mon Jan 31 19:53:20 UTC 2011


Module: Mesa
Branch: master
Commit: 0f7325b89038937bd428f7c89ed9859189a0ab0b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0f7325b89038937bd428f7c89ed9859189a0ab0b

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Mon Dec 27 03:21:23 2010 -0800

i965: Emit texel offsets in sampler messages.

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   45 +++++++++++++++++++++++++++++++--
 src/mesa/drivers/dri/i965/brw_fs.h   |    2 +-
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index c64a4c0..8fd120c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1337,6 +1337,37 @@ fs_visitor::visit(ir_texture *ir)
    ir->coordinate->accept(this);
    fs_reg coordinate = this->result;
 
+   if (ir->offset != NULL) {
+      ir_constant *offset = ir->offset->as_constant();
+      assert(offset != NULL);
+
+      signed char offsets[3];
+      for (unsigned i = 0; i < ir->offset->type->vector_elements; i++)
+	 offsets[i] = (signed char) offset->value.i[i];
+
+      /* Combine all three offsets into a single unsigned dword:
+       *
+       *    bits 11:8 - U Offset (X component)
+       *    bits  7:4 - V Offset (Y component)
+       *    bits  3:0 - R Offset (Z component)
+       */
+      unsigned offset_bits = 0;
+      for (unsigned i = 0; i < ir->offset->type->vector_elements; i++) {
+	 const unsigned shift = 4 * (2 - i);
+	 offset_bits |= (offsets[i] << shift) & (0xF << shift);
+      }
+
+      /* Explicitly set up the message header by copying g0 to msg reg m1. */
+      emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, 1, BRW_REGISTER_TYPE_UD),
+				   fs_reg(GRF, 0, BRW_REGISTER_TYPE_UD)));
+
+      /* Then set the offset bits in DWord 2 of the message header. */
+      emit(fs_inst(BRW_OPCODE_MOV,
+		   fs_reg(retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, 1, 2),
+				 BRW_REGISTER_TYPE_UD)),
+		   fs_reg(brw_imm_uw(offset_bits))));
+   }
+
    /* Should be lowered by do_lower_texture_projection */
    assert(!ir->projector);
 
@@ -1397,6 +1428,14 @@ fs_visitor::visit(ir_texture *ir)
       inst = emit_texture_gen5(ir, dst, coordinate);
    }
 
+   /* If there's an offset, we already set up m1.  To avoid the implied move,
+    * use the null register.  Otherwise, we want an implied move from g0.
+    */
+   if (ir->offset != NULL)
+      inst->src[0] = fs_reg(brw_null_reg());
+   else
+      inst->src[0] = fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
+
    inst->sampler = sampler;
 
    this->result = dst;
@@ -2243,7 +2282,7 @@ fs_visitor::generate_math(fs_inst *inst,
 }
 
 void
-fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst)
+fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
 {
    int msg_type = -1;
    int rlen = 4;
@@ -2301,7 +2340,7 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst)
    brw_SAMPLE(p,
 	      retype(dst, BRW_REGISTER_TYPE_UW),
 	      inst->base_mrf,
-	      retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
+	      src,
               SURF_INDEX_TEXTURE(inst->sampler),
 	      inst->sampler,
 	      WRITEMASK_XYZW,
@@ -3539,7 +3578,7 @@ fs_visitor::generate_code()
       case FS_OPCODE_TEX:
       case FS_OPCODE_TXB:
       case FS_OPCODE_TXL:
-	 generate_tex(inst, dst);
+	 generate_tex(inst, dst, src[0]);
 	 break;
       case FS_OPCODE_DISCARD_NOT:
 	 generate_discard_not(inst, dst);
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 59a17f7..8352760 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -453,7 +453,7 @@ public:
    void generate_fb_write(fs_inst *inst);
    void generate_linterp(fs_inst *inst, struct brw_reg dst,
 			 struct brw_reg *src);
-   void generate_tex(fs_inst *inst, struct brw_reg dst);
+   void generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
    void generate_math(fs_inst *inst, struct brw_reg dst, struct brw_reg *src);
    void generate_discard_not(fs_inst *inst, struct brw_reg temp);
    void generate_discard_and(fs_inst *inst, struct brw_reg temp);




More information about the mesa-commit mailing list