[Mesa-dev] [PATCH 5/6] i965/vs: Add support for ir_tg4

Chris Forbes chrisf at ijw.co.nz
Sun Mar 31 02:10:53 PDT 2013


Pretty much the same as the FS case. Channel select goes in the header,
post-sampling swizzle only does the 0/1 cases.

Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
---
 src/mesa/drivers/dri/i965/brw_vec4.h           |  1 +
 src/mesa/drivers/dri/i965/brw_vec4_emit.cpp    |  2 +-
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 47 ++++++++++++++++++++++++--
 3 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 1f832d1..36c7312 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -443,6 +443,7 @@ public:
    void emit_pack_half_2x16(dst_reg dst, src_reg src0);
    void emit_unpack_half_2x16(dst_reg dst, src_reg src0);
 
+   uint32_t gather_channel(ir_texture *ir, int sampler);
    void swizzle_result(ir_texture *ir, src_reg orig_val, int sampler);
 
    void emit_ndc_computation();
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
index 7938c14..d427469 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
@@ -354,7 +354,7 @@ vec4_generator::generate_tex(vec4_instruction *inst,
       brw_MOV(p,
 	      retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, inst->base_mrf, 2),
 		     BRW_REGISTER_TYPE_UD),
-	      brw_imm_uw(inst->texture_offset));
+	      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. */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 8bd2fd8..95cfc3b 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -2128,6 +2128,7 @@ vec4_visitor::visit(ir_texture *ir)
       break;
    case ir_txb:
    case ir_lod:
+   case ir_tg4:
       break;
    }
 
@@ -2149,15 +2150,21 @@ vec4_visitor::visit(ir_texture *ir)
    case ir_txs:
       inst = new(mem_ctx) vec4_instruction(this, SHADER_OPCODE_TXS);
       break;
+   case ir_tg4:
+      inst = new(mem_ctx) vec4_instruction(this, SHADER_OPCODE_TG4);
+      break;
    case ir_txb:
       assert(!"TXB is not valid for vertex shaders.");
       break;
    case ir_lod:
       assert(!"LOD is not valid for vertex shaders.");
       break;
+   default:
+      assert(!"Unrecognized tex op");
    }
 
-   bool use_texture_offset = ir->offset != NULL && ir->op != ir_txf;
+   bool use_texture_offset = (ir->offset != NULL && ir->op != ir_txf)
+      || ir->op == ir_tg4;
 
    /* Texel offsets go in the message header; Gen4 also requires headers. */
    inst->header_present = use_texture_offset || intel->gen < 5;
@@ -2168,9 +2175,13 @@ vec4_visitor::visit(ir_texture *ir)
    inst->dst.writemask = WRITEMASK_XYZW;
    inst->shadow_compare = ir->shadow_comparitor != NULL;
 
-   if (use_texture_offset)
+   if (use_texture_offset && ir->offset)
       inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
 
+   /* Stuff the channel select bits in the top of the texture offset */
+   if (ir->op == ir_tg4)
+      inst->texture_offset |= gather_channel(ir, sampler)<<16;
+
    /* MRF for the first parameter */
    int param_base = inst->base_mrf + inst->header_present;
 
@@ -2290,6 +2301,24 @@ vec4_visitor::visit(ir_texture *ir)
    swizzle_result(ir, src_reg(inst->dst), sampler);
 }
 
+/**
+ * Set up the gather channel based on the swizzle, for gather4.
+ */
+uint32_t
+vec4_visitor::gather_channel(ir_texture *ir, int sampler)
+{
+   int swiz = GET_SWZ(c->key.tex.swizzles[sampler], 0 /* red */);
+   switch (swiz) {
+      case SWIZZLE_X: return 0;
+      case SWIZZLE_Y: return 1;
+      case SWIZZLE_Z: return 2;
+      case SWIZZLE_W: return 3;
+      default:
+         /* zero, one swizzles */
+         return 0;
+   }
+}
+
 void
 vec4_visitor::swizzle_result(ir_texture *ir, src_reg orig_val, int sampler)
 {
@@ -2304,6 +2333,20 @@ vec4_visitor::swizzle_result(ir_texture *ir, src_reg orig_val, int sampler)
       return;
    }
 
+   /* ir_tg4 does its swizzling in hardware, except for ZERO/ONE degenerate
+    * cases, which we'll do here
+    */
+   if (ir->op == ir_tg4) {
+      int swiz = GET_SWZ(s,0);
+      if (swiz != SWIZZLE_ZERO && swiz != SWIZZLE_ONE) {
+         emit(MOV(swizzled_result, orig_val));
+         return;
+      }
+
+      emit(MOV(swizzled_result, src_reg(swiz == SWIZZLE_ONE ? 1.0f : 0.0f)));
+      return;
+   }
+
    int zero_mask = 0, one_mask = 0, copy_mask = 0;
    int swizzle[4];
 
-- 
1.8.2



More information about the mesa-dev mailing list