On 03/31/2013 02:10 AM, Chris Forbes wrote:
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 <chr...@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;

I'd prefer to leave this as is, and instead...

     /* Texel offsets go in the message header; Gen4 also requires headers. */
     inst->header_present = use_texture_offset || intel->gen < 5;

inst->header_present =
   use_texture_offset || ir->op == ir_tg4 || 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());

Then you can leave this alone too...

+   /* 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;
+   }

Again, we should probably do this earlier in visit(ir_texture *). Then you can just add || ir->op == ir_tg4 to the above block which short-circuits.

+
     int zero_mask = 0, one_mask = 0, copy_mask = 0;
     int swizzle[4];

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to