i965/fs: Move message header and texture offset setup to generate_tex().
authorKenneth Graunke <kenneth@whitecape.org>
Sun, 5 Aug 2012 03:33:13 +0000 (20:33 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 6 Aug 2012 18:16:00 +0000 (11:16 -0700)
Setting the texture offset bits in the message header involves very
specific hardware register descriptions.  As such, I feel it's better
suited for the lower level "generate" layer that has direct access to
the weird register layouts, rather than at the fs_inst abstraction layer.

This also parallels the approach I took in the VS backend.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_emit.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

index 031d5414ba14f92532fe720ac6cf6bb84de84fd1..246dcf0f4e46b8f5b87624865080b4bcd5690f38 100644 (file)
@@ -164,6 +164,7 @@ public:
 
    int mlen; /**< SEND message length */
    int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */
+   uint32_t texture_offset; /**< Texture offset bitfield */
    int sampler;
    int target; /**< MRT target. */
    bool eot;
index dc5f3e16134c036e8a9ee7bbaab78bc586220f2d..0bd056d5c1a14e7427d89a1270ac7692718c8bfa 100644 (file)
@@ -381,6 +381,27 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
       dst = vec16(dst);
    }
 
+   /* Load the message header if present.  If there's a texture offset,
+    * we need to set it up explicitly and load the offset bitfield.
+    * Otherwise, we can use an implied move from g0 to the first message reg.
+    */
+   if (inst->texture_offset) {
+      brw_push_insn_state(p);
+      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+      /* Explicitly set up the message header by copying g0 to the MRF. */
+      brw_MOV(p, retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD),
+                 retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
+
+      /* Then set the offset bits in DWord 2. */
+      brw_MOV(p, retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE,
+                                     inst->base_mrf, 2), BRW_REGISTER_TYPE_UD),
+                 brw_imm_ud(inst->texture_offset));
+      brw_pop_insn_state(p);
+   } else if (inst->header_present) {
+      /* Set up an implied move from g0 to the MRF. */
+      src = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW);
+   }
+
    brw_SAMPLE(p,
              retype(dst, BRW_REGISTER_TYPE_UW),
              inst->base_mrf,
index fefe2c7d15d330e2a088af8be289caa3f4110e33..08b7fb887aa213733acb38db835b7e56be9e7107 100644 (file)
@@ -1167,20 +1167,6 @@ fs_visitor::visit(ir_texture *ir)
       ir->coordinate->accept(this);
    fs_reg coordinate = this->result;
 
-   if (ir->offset != NULL && !(intel->gen == 7 && ir->op == ir_txf)) {
-      uint32_t offset_bits = brw_texture_offset(ir->offset->as_constant());
-
-      /* Explicitly set up the message header by copying g0 to msg reg m1. */
-      emit(BRW_OPCODE_MOV, fs_reg(MRF, 1, BRW_REGISTER_TYPE_UD),
-          fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)));
-
-      /* Then set the offset bits in DWord 2 of the message header. */
-      emit(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);
 
@@ -1297,13 +1283,11 @@ fs_visitor::visit(ir_texture *ir)
       inst = emit_texture_gen4(ir, dst, coordinate, sampler);
    }
 
-   /* 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->header_present)
-      inst->src[0] = reg_undef;
-   else
-      inst->src[0] = fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
+   /* The header is set up by generate_tex() when necessary. */
+   inst->src[0] = reg_undef;
+
+   if (ir->offset != NULL && ir->op != ir_txf)
+      inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
 
    inst->sampler = sampler;