[Mesa-dev] [PATCH 5/6] i965/vs: Add support for ir_tg4
Kenneth Graunke
kenneth at whitecape.org
Tue Apr 2 22:27:26 PDT 2013
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 <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;
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];
More information about the mesa-dev
mailing list