[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