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; /* 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev