[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