diff options
Diffstat (limited to 'src/gallium/auxiliary/tgsi/tgsi_lowering.c')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_lowering.c | 2306 |
1 files changed, 1152 insertions, 1154 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_lowering.c b/src/gallium/auxiliary/tgsi/tgsi_lowering.c index 795b53729d6..5627bb53ed5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_lowering.c +++ b/src/gallium/auxiliary/tgsi/tgsi_lowering.c @@ -1,5 +1,3 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - /* * Copyright (C) 2014 Rob Clark <[email protected]> * @@ -36,29 +34,29 @@ #include "freedreno_lowering.h" struct fd_lowering_context { - struct tgsi_transform_context base; - const struct fd_lowering_config *config; - struct tgsi_shader_info *info; - unsigned two_side_colors; - unsigned two_side_idx[PIPE_MAX_SHADER_INPUTS]; - unsigned color_base; /* base register for chosen COLOR/BCOLOR's */ - int face_idx; - unsigned numtmp; - struct { - struct tgsi_full_src_register src; - struct tgsi_full_dst_register dst; - } tmp[2]; + struct tgsi_transform_context base; + const struct fd_lowering_config *config; + struct tgsi_shader_info *info; + unsigned two_side_colors; + unsigned two_side_idx[PIPE_MAX_SHADER_INPUTS]; + unsigned color_base; /* base register for chosen COLOR/BCOLOR's */ + int face_idx; + unsigned numtmp; + struct { + struct tgsi_full_src_register src; + struct tgsi_full_dst_register dst; + } tmp[2]; #define A 0 #define B 1 - struct tgsi_full_src_register imm; - int emitted_decls; - unsigned saturate; + struct tgsi_full_src_register imm; + int emitted_decls; + unsigned saturate; }; static inline struct fd_lowering_context * fd_lowering_context(struct tgsi_transform_context *tctx) { - return (struct fd_lowering_context *)tctx; + return (struct fd_lowering_context *)tctx; } /* @@ -69,18 +67,18 @@ static void reg_dst(struct tgsi_full_dst_register *dst, const struct tgsi_full_dst_register *orig_dst, unsigned wrmask) { - *dst = *orig_dst; - dst->Register.WriteMask &= wrmask; - assert(dst->Register.WriteMask); + *dst = *orig_dst; + dst->Register.WriteMask &= wrmask; + assert(dst->Register.WriteMask); } static inline void get_swiz(unsigned *swiz, const struct tgsi_src_register *src) { - swiz[0] = src->SwizzleX; - swiz[1] = src->SwizzleY; - swiz[2] = src->SwizzleZ; - swiz[3] = src->SwizzleW; + swiz[0] = src->SwizzleX; + swiz[1] = src->SwizzleY; + swiz[2] = src->SwizzleZ; + swiz[3] = src->SwizzleW; } static void @@ -88,18 +86,18 @@ reg_src(struct tgsi_full_src_register *src, const struct tgsi_full_src_register *orig_src, unsigned sx, unsigned sy, unsigned sz, unsigned sw) { - unsigned swiz[4]; - get_swiz(swiz, &orig_src->Register); - *src = *orig_src; - src->Register.SwizzleX = swiz[sx]; - src->Register.SwizzleY = swiz[sy]; - src->Register.SwizzleZ = swiz[sz]; - src->Register.SwizzleW = swiz[sw]; + unsigned swiz[4]; + get_swiz(swiz, &orig_src->Register); + *src = *orig_src; + src->Register.SwizzleX = swiz[sx]; + src->Register.SwizzleY = swiz[sy]; + src->Register.SwizzleZ = swiz[sz]; + src->Register.SwizzleW = swiz[sw]; } #define TGSI_SWIZZLE__ TGSI_SWIZZLE_X /* don't-care value! */ -#define SWIZ(x,y,z,w) TGSI_SWIZZLE_ ## x, TGSI_SWIZZLE_ ## y, \ - TGSI_SWIZZLE_ ## z, TGSI_SWIZZLE_ ## w +#define SWIZ(x,y,z,w) TGSI_SWIZZLE_ ## x, TGSI_SWIZZLE_ ## y, \ + TGSI_SWIZZLE_ ## z, TGSI_SWIZZLE_ ## w /* * if (dst.x aliases src.x) { @@ -114,36 +112,36 @@ static bool aliases(const struct tgsi_full_dst_register *dst, unsigned dst_mask, const struct tgsi_full_src_register *src, unsigned src_mask) { - if ((dst->Register.File == src->Register.File) && - (dst->Register.Index == src->Register.Index)) { - unsigned i, actual_mask = 0; - unsigned swiz[4]; - get_swiz(swiz, &src->Register); - for (i = 0; i < 4; i++) - if (src_mask & (1 << i)) - actual_mask |= (1 << swiz[i]); - if (actual_mask & dst_mask) - return true; - } - return false; + if ((dst->Register.File == src->Register.File) && + (dst->Register.Index == src->Register.Index)) { + unsigned i, actual_mask = 0; + unsigned swiz[4]; + get_swiz(swiz, &src->Register); + for (i = 0; i < 4; i++) + if (src_mask & (1 << i)) + actual_mask |= (1 << swiz[i]); + if (actual_mask & dst_mask) + return true; + } + return false; } static void create_mov(struct tgsi_transform_context *tctx, - const struct tgsi_full_dst_register *dst, - const struct tgsi_full_src_register *src, - unsigned mask, unsigned saturate) + const struct tgsi_full_dst_register *dst, + const struct tgsi_full_src_register *src, + unsigned mask, unsigned saturate) { - struct tgsi_full_instruction new_inst; - - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.Saturate = saturate; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, mask); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src, SWIZ(X,Y,Z,W)); - tctx->emit_instruction(tctx, &new_inst); + struct tgsi_full_instruction new_inst; + + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.Saturate = saturate; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, mask); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src, SWIZ(X, Y, Z, W)); + tctx->emit_instruction(tctx, &new_inst); } /* to help calculate # of tgsi tokens for a lowering.. we assume @@ -196,68 +194,68 @@ create_mov(struct tgsi_transform_context *tctx, #define DST_TMP 2 static void transform_dst(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src0 = &inst->Src[0]; - struct tgsi_full_src_register *src1 = &inst->Src[1]; - struct tgsi_full_instruction new_inst; - - if (aliases(dst, TGSI_WRITEMASK_Y, src0, TGSI_WRITEMASK_Z)) { - create_mov(tctx, &ctx->tmp[A].dst, src0, TGSI_WRITEMASK_YZ, 0); - src0 = &ctx->tmp[A].src; - } - - if (aliases(dst, TGSI_WRITEMASK_YZ, src1, TGSI_WRITEMASK_W)) { - create_mov(tctx, &ctx->tmp[B].dst, src1, TGSI_WRITEMASK_YW, 0); - src1 = &ctx->tmp[B].src; - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { - /* MUL dst.y, src0.y, src1.y */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src0, SWIZ(_,Y,_,_)); - reg_src(&new_inst.Src[1], src1, SWIZ(_,Y,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_Z) { - /* MOV dst.z, src0.z */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Z); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src0, SWIZ(_,_,Z,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { - /* MOV dst.w, src1.w */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src1, SWIZ(_,_,_,W)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_X) { - /* MOV dst.x, imm{1.0} */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(Y,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src0 = &inst->Src[0]; + struct tgsi_full_src_register *src1 = &inst->Src[1]; + struct tgsi_full_instruction new_inst; + + if (aliases(dst, TGSI_WRITEMASK_Y, src0, TGSI_WRITEMASK_Z)) { + create_mov(tctx, &ctx->tmp[A].dst, src0, TGSI_WRITEMASK_YZ, 0); + src0 = &ctx->tmp[A].src; + } + + if (aliases(dst, TGSI_WRITEMASK_YZ, src1, TGSI_WRITEMASK_W)) { + create_mov(tctx, &ctx->tmp[B].dst, src1, TGSI_WRITEMASK_YW, 0); + src1 = &ctx->tmp[B].src; + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { + /* MUL dst.y, src0.y, src1.y */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src0, SWIZ(_, Y, _, _)); + reg_src(&new_inst.Src[1], src1, SWIZ(_, Y, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_Z) { + /* MOV dst.z, src0.z */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Z); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src0, SWIZ(_, _, Z, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { + /* MOV dst.w, src1.w */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src1, SWIZ(_, _, _, W)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_X) { + /* MOV dst.x, imm{1.0} */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(Y, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } } /* XPD - Cross Product @@ -276,56 +274,56 @@ transform_dst(struct tgsi_transform_context *tctx, #define XPD_TMP 2 static void transform_xpd(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src0 = &inst->Src[0]; - struct tgsi_full_src_register *src1 = &inst->Src[1]; - struct tgsi_full_instruction new_inst; - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZ) { - /* MUL tmpA.xyz, src0.yzx, src1.zxy */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZ); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src0, SWIZ(Y,Z,X,_)); - reg_src(&new_inst.Src[1], src1, SWIZ(Z,X,Y,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* MUL tmpB.xyz, src1.yzx, src0.zxy */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_XYZ); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src1, SWIZ(Y,Z,X,_)); - reg_src(&new_inst.Src[1], src0, SWIZ(Z,X,Y,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* SUB dst.xyz, tmpA.xyz, tmpB.xyz */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_SUB; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZ); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X,Y,Z,_)); - reg_src(&new_inst.Src[1], &ctx->tmp[B].src, SWIZ(X,Y,Z,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { - /* MOV dst.w, imm{1.0} */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_,_,_,Y)); - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src0 = &inst->Src[0]; + struct tgsi_full_src_register *src1 = &inst->Src[1]; + struct tgsi_full_instruction new_inst; + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZ) { + /* MUL tmpA.xyz, src0.yzx, src1.zxy */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZ); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src0, SWIZ(Y, Z, X, _)); + reg_src(&new_inst.Src[1], src1, SWIZ(Z, X, Y, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* MUL tmpB.xyz, src1.yzx, src0.zxy */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_XYZ); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src1, SWIZ(Y, Z, X, _)); + reg_src(&new_inst.Src[1], src0, SWIZ(Z, X, Y, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* SUB dst.xyz, tmpA.xyz, tmpB.xyz */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_SUB; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZ); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X, Y, Z, _)); + reg_src(&new_inst.Src[1], &ctx->tmp[B].src, SWIZ(X, Y, Z, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { + /* MOV dst.w, imm{1.0} */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_, _, _, Y)); + tctx->emit_instruction(tctx, &new_inst); + } } /* SCS - Sine Cosine @@ -347,50 +345,50 @@ transform_xpd(struct tgsi_transform_context *tctx, #define SCS_TMP 1 static void transform_scs(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src = &inst->Src[0]; - struct tgsi_full_instruction new_inst; - - if (aliases(dst, TGSI_WRITEMASK_X, src, TGSI_WRITEMASK_X)) { - create_mov(tctx, &ctx->tmp[A].dst, src, TGSI_WRITEMASK_X, 0); - src = &ctx->tmp[A].src; - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_X) { - /* COS dst.x, src.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_COS; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src, SWIZ(X,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { - /* SIN dst.y, src.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_SIN; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src, SWIZ(X,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_ZW) { - /* MOV dst.zw, imm{0.0, 1.0} */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_ZW); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_,_,X,Y)); - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src = &inst->Src[0]; + struct tgsi_full_instruction new_inst; + + if (aliases(dst, TGSI_WRITEMASK_X, src, TGSI_WRITEMASK_X)) { + create_mov(tctx, &ctx->tmp[A].dst, src, TGSI_WRITEMASK_X, 0); + src = &ctx->tmp[A].src; + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_X) { + /* COS dst.x, src.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_COS; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { + /* SIN dst.y, src.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_SIN; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_ZW) { + /* MOV dst.zw, imm{0.0, 1.0} */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_ZW); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_, _, X, Y)); + tctx->emit_instruction(tctx, &new_inst); + } } /* LRP - Linear Interpolate @@ -409,56 +407,56 @@ transform_scs(struct tgsi_transform_context *tctx, #define LRP_TMP 2 static void transform_lrp(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src0 = &inst->Src[0]; - struct tgsi_full_src_register *src1 = &inst->Src[1]; - struct tgsi_full_src_register *src2 = &inst->Src[2]; - struct tgsi_full_instruction new_inst; - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { - /* MUL tmpA, src0, src1 */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src0, SWIZ(X,Y,Z,W)); - reg_src(&new_inst.Src[1], src1, SWIZ(X,Y,Z,W)); - tctx->emit_instruction(tctx, &new_inst); - - /* SUB tmpB, imm{1.0}, src0 */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_SUB; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_XYZW); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(Y,Y,Y,Y)); - reg_src(&new_inst.Src[1], src0, SWIZ(X,Y,Z,W)); - tctx->emit_instruction(tctx, &new_inst); - - /* MUL tmpB, tmpB, src2 */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_XYZW); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], &ctx->tmp[B].src, SWIZ(X,Y,Z,W)); - reg_src(&new_inst.Src[1], src2, SWIZ(X,Y,Z,W)); - tctx->emit_instruction(tctx, &new_inst); - - /* ADD dst, tmpA, tmpB */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X,Y,Z,W)); - reg_src(&new_inst.Src[1], &ctx->tmp[B].src, SWIZ(X,Y,Z,W)); - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src0 = &inst->Src[0]; + struct tgsi_full_src_register *src1 = &inst->Src[1]; + struct tgsi_full_src_register *src2 = &inst->Src[2]; + struct tgsi_full_instruction new_inst; + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { + /* MUL tmpA, src0, src1 */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src0, SWIZ(X, Y, Z, W)); + reg_src(&new_inst.Src[1], src1, SWIZ(X, Y, Z, W)); + tctx->emit_instruction(tctx, &new_inst); + + /* SUB tmpB, imm{1.0}, src0 */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_SUB; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_XYZW); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(Y, Y, Y, Y)); + reg_src(&new_inst.Src[1], src0, SWIZ(X, Y, Z, W)); + tctx->emit_instruction(tctx, &new_inst); + + /* MUL tmpB, tmpB, src2 */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_XYZW); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], &ctx->tmp[B].src, SWIZ(X, Y, Z, W)); + reg_src(&new_inst.Src[1], src2, SWIZ(X, Y, Z, W)); + tctx->emit_instruction(tctx, &new_inst); + + /* ADD dst, tmpA, tmpB */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); + reg_src(&new_inst.Src[1], &ctx->tmp[B].src, SWIZ(X, Y, Z, W)); + tctx->emit_instruction(tctx, &new_inst); + } } /* FRC - Fraction @@ -475,33 +473,33 @@ transform_lrp(struct tgsi_transform_context *tctx, #define FRC_TMP 1 static void transform_frc(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src = &inst->Src[0]; - struct tgsi_full_instruction new_inst; - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { - /* FLR tmpA, src */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src, SWIZ(X,Y,Z,W)); - tctx->emit_instruction(tctx, &new_inst); - - /* SUB dst, src, tmpA */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_SUB; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src, SWIZ(X,Y,Z,W)); - reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X,Y,Z,W)); - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src = &inst->Src[0]; + struct tgsi_full_instruction new_inst; + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { + /* FLR tmpA, src */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src, SWIZ(X, Y, Z, W)); + tctx->emit_instruction(tctx, &new_inst); + + /* SUB dst, src, tmpA */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_SUB; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src, SWIZ(X, Y, Z, W)); + reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); + tctx->emit_instruction(tctx, &new_inst); + } } /* POW - Power @@ -519,43 +517,43 @@ transform_frc(struct tgsi_transform_context *tctx, #define POW_TMP 1 static void transform_pow(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src0 = &inst->Src[0]; - struct tgsi_full_src_register *src1 = &inst->Src[1]; - struct tgsi_full_instruction new_inst; - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { - /* LG2 tmpA.x, src0.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_LG2; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src0, SWIZ(X,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* MUL tmpA.x, src1.x, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src1, SWIZ(X,_,_,_)); - reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* EX2 dst, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src0 = &inst->Src[0]; + struct tgsi_full_src_register *src1 = &inst->Src[1]; + struct tgsi_full_instruction new_inst; + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { + /* LG2 tmpA.x, src0.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_LG2; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src0, SWIZ(X, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* MUL tmpA.x, src1.x, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src1, SWIZ(X, _, _, _)); + reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* EX2 dst, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } } /* LIT - Light Coefficients @@ -579,96 +577,96 @@ transform_pow(struct tgsi_transform_context *tctx, #define LIT_TMP 1 static void transform_lit(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src = &inst->Src[0]; - struct tgsi_full_instruction new_inst; - - if (dst->Register.WriteMask & TGSI_WRITEMASK_YZ) { - /* MAX tmpA.xy, src.xy, imm{0.0} */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MAX; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XY); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src, SWIZ(X,Y,_,_)); - reg_src(&new_inst.Src[1], &ctx->imm, SWIZ(X,X,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* CLAMP tmpA.z, src.w, -imm{128.0}, imm{128.0} */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_CLAMP; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Z); - new_inst.Instruction.NumSrcRegs = 3; - reg_src(&new_inst.Src[0], src, SWIZ(_,_,W,_)); - reg_src(&new_inst.Src[1], &ctx->imm, SWIZ(_,_,Z,_)); - new_inst.Src[1].Register.Negate = true; - reg_src(&new_inst.Src[2], &ctx->imm, SWIZ(_,_,Z,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* LG2 tmpA.y, tmpA.y */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_LG2; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* MUL tmpA.y, tmpA.z, tmpA.y */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_,Z,_,_)); - reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_,Y,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* EX2 tmpA.y, tmpA.y */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* CMP tmpA.y, -src.x, tmpA.y, imm{0.0} */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_CMP; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 3; - reg_src(&new_inst.Src[0], src, SWIZ(_,X,_,_)); - new_inst.Src[0].Register.Negate = true; - reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_,Y,_,_)); - reg_src(&new_inst.Src[2], &ctx->imm, SWIZ(_,X,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* MOV dst.yz, tmpA.xy */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_YZ); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_,X,Y,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XW) { - /* MOV dst.xw, imm{1.0} */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XW); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(Y,_,_,Y)); - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src = &inst->Src[0]; + struct tgsi_full_instruction new_inst; + + if (dst->Register.WriteMask & TGSI_WRITEMASK_YZ) { + /* MAX tmpA.xy, src.xy, imm{0.0} */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MAX; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XY); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src, SWIZ(X, Y, _, _)); + reg_src(&new_inst.Src[1], &ctx->imm, SWIZ(X, X, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* CLAMP tmpA.z, src.w, -imm{128.0}, imm{128.0} */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_CLAMP; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Z); + new_inst.Instruction.NumSrcRegs = 3; + reg_src(&new_inst.Src[0], src, SWIZ(_, _, W, _)); + reg_src(&new_inst.Src[1], &ctx->imm, SWIZ(_, _, Z, _)); + new_inst.Src[1].Register.Negate = true; + reg_src(&new_inst.Src[2], &ctx->imm, SWIZ(_, _, Z, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* LG2 tmpA.y, tmpA.y */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_LG2; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* MUL tmpA.y, tmpA.z, tmpA.y */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, Z, _, _)); + reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_, Y, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* EX2 tmpA.y, tmpA.y */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* CMP tmpA.y, -src.x, tmpA.y, imm{0.0} */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_CMP; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 3; + reg_src(&new_inst.Src[0], src, SWIZ(_, X, _, _)); + new_inst.Src[0].Register.Negate = true; + reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_, Y, _, _)); + reg_src(&new_inst.Src[2], &ctx->imm, SWIZ(_, X, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* MOV dst.yz, tmpA.xy */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_YZ); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, X, Y, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XW) { + /* MOV dst.xw, imm{1.0} */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XW); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(Y, _, _, Y)); + tctx->emit_instruction(tctx, &new_inst); + } } /* EXP - Approximate Exponential Base 2 @@ -690,79 +688,79 @@ transform_lit(struct tgsi_transform_context *tctx, #define EXP_TMP 1 static void transform_exp(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src = &inst->Src[0]; - struct tgsi_full_instruction new_inst; - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XY) { - /* FLR tmpA.x, src.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src, SWIZ(X,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_Z) { - /* EX2 tmpA.y, src.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src, SWIZ(X,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { - /* SUB dst.y, src.x, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_SUB; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src, SWIZ(_,X,_,_)); - reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_,X,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_X) { - /* EX2 dst.x, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_Z) { - /* MOV dst.z, tmpA.y */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Z); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_,_,Y,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { - /* MOV dst.w, imm{1.0} */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_,_,_,Y)); - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src = &inst->Src[0]; + struct tgsi_full_instruction new_inst; + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XY) { + /* FLR tmpA.x, src.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_Z) { + /* EX2 tmpA.y, src.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { + /* SUB dst.y, src.x, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_SUB; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src, SWIZ(_, X, _, _)); + reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_, X, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_X) { + /* EX2 dst.x, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_Z) { + /* MOV dst.z, tmpA.y */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Z); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, _, Y, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { + /* MOV dst.w, imm{1.0} */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_, _, _, Y)); + tctx->emit_instruction(tctx, &new_inst); + } } /* LOG - Approximate Logarithm Base 2 @@ -785,88 +783,88 @@ transform_exp(struct tgsi_transform_context *tctx, #define LOG_TMP 1 static void transform_log(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src = &inst->Src[0]; - struct tgsi_full_instruction new_inst; - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZ) { - /* LG2 tmpA.x, |src.x| */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_LG2; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], src, SWIZ(X,_,_,_)); - new_inst.Src[0].Register.Absolute = true; - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XY) { - /* FLR tmpA.y, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_,X,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { - /* EX2 tmpA.z, tmpA.y */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Z); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* RCP tmpA.z, tmpA.z */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_RCP; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Z); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Z,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* MUL dst.y, |src.x|, tmpA.z */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src, SWIZ(_,X,_,_)); - new_inst.Src[0].Register.Absolute = true; - reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_,Z,_,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XZ) { - /* MOV dst.xz, tmpA.yx */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XZ); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y,_,X,_)); - tctx->emit_instruction(tctx, &new_inst); - } - - if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { - /* MOV dst.w, imm{1.0} */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_,_,_,Y)); - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src = &inst->Src[0]; + struct tgsi_full_instruction new_inst; + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZ) { + /* LG2 tmpA.x, |src.x| */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_LG2; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); + new_inst.Src[0].Register.Absolute = true; + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XY) { + /* FLR tmpA.y, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, X, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { + /* EX2 tmpA.z, tmpA.y */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Z); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* RCP tmpA.z, tmpA.z */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_RCP; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Z); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Z, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* MUL dst.y, |src.x|, tmpA.z */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src, SWIZ(_, X, _, _)); + new_inst.Src[0].Register.Absolute = true; + reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_, Z, _, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XZ) { + /* MOV dst.xz, tmpA.yx */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XZ); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y, _, X, _)); + tctx->emit_instruction(tctx, &new_inst); + } + + if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { + /* MOV dst.w, imm{1.0} */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_, _, _, Y)); + tctx->emit_instruction(tctx, &new_inst); + } } /* DP4 - 4-component Dot Product @@ -913,98 +911,98 @@ transform_log(struct tgsi_transform_context *tctx, #define DOTP_TMP 1 static void transform_dotp(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_dst_register *dst = &inst->Dst[0]; - struct tgsi_full_src_register *src0 = &inst->Src[0]; - struct tgsi_full_src_register *src1 = &inst->Src[1]; - struct tgsi_full_src_register *src2 = &inst->Src[2]; /* only DP2A */ - struct tgsi_full_instruction new_inst; - unsigned opcode = inst->Instruction.Opcode; - - /* NOTE: any potential last instruction must replicate src on all - * components (since it could be re-written to write to final dst) - */ - - if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { - /* MUL tmpA.x, src0.x, src1.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src0, SWIZ(X,_,_,_)); - reg_src(&new_inst.Src[1], src1, SWIZ(X,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* MAD tmpA.x, src0.y, src1.y, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 3; - reg_src(&new_inst.Src[0], src0, SWIZ(Y,Y,Y,Y)); - reg_src(&new_inst.Src[1], src1, SWIZ(Y,Y,Y,Y)); - reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X,X,X,X)); - - if ((opcode == TGSI_OPCODE_DPH) || - (opcode == TGSI_OPCODE_DP3) || - (opcode == TGSI_OPCODE_DP4)) { - tctx->emit_instruction(tctx, &new_inst); - - /* MAD tmpA.x, src0.z, src1.z, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 3; - reg_src(&new_inst.Src[0], src0, SWIZ(Z,Z,Z,Z)); - reg_src(&new_inst.Src[1], src1, SWIZ(Z,Z,Z,Z)); - reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X,X,X,X)); - - if (opcode == TGSI_OPCODE_DPH) { - tctx->emit_instruction(tctx, &new_inst); - - /* ADD tmpA.x, src1.w, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src1, SWIZ(W,W,W,W)); - reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X,X,X,X)); - } else if (opcode == TGSI_OPCODE_DP4) { - tctx->emit_instruction(tctx, &new_inst); - - /* MAD tmpA.x, src0.w, src1.w, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 3; - reg_src(&new_inst.Src[0], src0, SWIZ(W,W,W,W)); - reg_src(&new_inst.Src[1], src1, SWIZ(W,W,W,W)); - reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X,X,X,X)); - } - } else if (opcode == TGSI_OPCODE_DP2A) { - tctx->emit_instruction(tctx, &new_inst); - - /* ADD tmpA.x, src2.x, tmpA.x */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], src2, SWIZ(X,X,X,X)); - reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X,X,X,X)); - } - - /* fixup last instruction to write to dst: */ - reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); - - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_dst_register *dst = &inst->Dst[0]; + struct tgsi_full_src_register *src0 = &inst->Src[0]; + struct tgsi_full_src_register *src1 = &inst->Src[1]; + struct tgsi_full_src_register *src2 = &inst->Src[2]; /* only DP2A */ + struct tgsi_full_instruction new_inst; + unsigned opcode = inst->Instruction.Opcode; + + /* NOTE: any potential last instruction must replicate src on all + * components (since it could be re-written to write to final dst) + */ + + if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { + /* MUL tmpA.x, src0.x, src1.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src0, SWIZ(X, _, _, _)); + reg_src(&new_inst.Src[1], src1, SWIZ(X, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* MAD tmpA.x, src0.y, src1.y, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 3; + reg_src(&new_inst.Src[0], src0, SWIZ(Y, Y, Y, Y)); + reg_src(&new_inst.Src[1], src1, SWIZ(Y, Y, Y, Y)); + reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X, X, X, X)); + + if ((opcode == TGSI_OPCODE_DPH) || + (opcode == TGSI_OPCODE_DP3) || + (opcode == TGSI_OPCODE_DP4)) { + tctx->emit_instruction(tctx, &new_inst); + + /* MAD tmpA.x, src0.z, src1.z, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 3; + reg_src(&new_inst.Src[0], src0, SWIZ(Z, Z, Z, Z)); + reg_src(&new_inst.Src[1], src1, SWIZ(Z, Z, Z, Z)); + reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X, X, X, X)); + + if (opcode == TGSI_OPCODE_DPH) { + tctx->emit_instruction(tctx, &new_inst); + + /* ADD tmpA.x, src1.w, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src1, SWIZ(W, W, W, W)); + reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, X, X, X)); + } else if (opcode == TGSI_OPCODE_DP4) { + tctx->emit_instruction(tctx, &new_inst); + + /* MAD tmpA.x, src0.w, src1.w, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 3; + reg_src(&new_inst.Src[0], src0, SWIZ(W, W, W, W)); + reg_src(&new_inst.Src[1], src1, SWIZ(W, W, W, W)); + reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X, X, X, X)); + } + } else if (opcode == TGSI_OPCODE_DP2A) { + tctx->emit_instruction(tctx, &new_inst); + + /* ADD tmpA.x, src2.x, tmpA.x */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], src2, SWIZ(X, X, X, X)); + reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, X, X, X)); + } + + /* fixup last instruction to write to dst: */ + reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); + + tctx->emit_instruction(tctx, &new_inst); + } } /* Inserts a MOV_SAT for the needed components of tex coord. Note that @@ -1025,282 +1023,282 @@ transform_dotp(struct tgsi_transform_context *tctx, #define SAMP_TMP 2 static int transform_samp(struct tgsi_transform_context *tctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_full_src_register *coord = &inst->Src[0]; - struct tgsi_full_src_register *samp; - struct tgsi_full_instruction new_inst; - /* mask is clamped coords, pmask is all coords (for projection): */ - unsigned mask = 0, pmask = 0, smask; - unsigned opcode = inst->Instruction.Opcode; - - if (opcode == TGSI_OPCODE_TXB2) { - samp = &inst->Src[2]; - } else { - samp = &inst->Src[1]; - } - - /* convert sampler # to bitmask to test: */ - smask = 1 << samp->Register.Index; - - /* check if we actually need to lower this one: */ - if (!(ctx->saturate & smask)) - return -1; - - /* figure out which coordinates need saturating: - * - RECT textures should not get saturated - * - array index coords should not get saturated - */ - switch (inst->Texture.Texture) { - case TGSI_TEXTURE_3D: - case TGSI_TEXTURE_CUBE: - case TGSI_TEXTURE_CUBE_ARRAY: - case TGSI_TEXTURE_SHADOWCUBE: - case TGSI_TEXTURE_SHADOWCUBE_ARRAY: - if (ctx->config->saturate_r & smask) - mask |= TGSI_WRITEMASK_Z; - pmask |= TGSI_WRITEMASK_Z; - /* fallthrough */ - - case TGSI_TEXTURE_2D: - case TGSI_TEXTURE_2D_ARRAY: - case TGSI_TEXTURE_SHADOW2D: - case TGSI_TEXTURE_SHADOW2D_ARRAY: - case TGSI_TEXTURE_2D_MSAA: - case TGSI_TEXTURE_2D_ARRAY_MSAA: - if (ctx->config->saturate_t & smask) - mask |= TGSI_WRITEMASK_Y; - pmask |= TGSI_WRITEMASK_Y; - /* fallthrough */ - - case TGSI_TEXTURE_1D: - case TGSI_TEXTURE_1D_ARRAY: - case TGSI_TEXTURE_SHADOW1D: - case TGSI_TEXTURE_SHADOW1D_ARRAY: - if (ctx->config->saturate_s & smask) - mask |= TGSI_WRITEMASK_X; - pmask |= TGSI_WRITEMASK_X; - break; - - /* TODO: I think we should ignore these? - case TGSI_TEXTURE_RECT: - case TGSI_TEXTURE_SHADOWRECT: - */ - } - - /* sanity check.. driver could be asking to saturate a non- - * existent coordinate component: - */ - if (!mask) - return -1; - - /* MOV tmpA, src0 */ - create_mov(tctx, &ctx->tmp[A].dst, coord, TGSI_WRITEMASK_XYZW, 0); - - /* This is a bit sad.. we need to clamp *after* the coords - * are projected, which means lowering TXP to TEX and doing - * the projection ourself. But since I haven't figured out - * how to make the lowering code deliver an electric shock - * to anyone using GL_CLAMP, we must do this instead: - */ - if (opcode == TGSI_OPCODE_TXP) { - /* RCP tmpB.x tmpA.w */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_RCP; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_X); - new_inst.Instruction.NumSrcRegs = 1; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(W,_,_,_)); - tctx->emit_instruction(tctx, &new_inst); - - /* MUL tmpA.mask, tmpA, tmpB.xxxx */ - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; - new_inst.Instruction.NumDstRegs = 1; - reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, pmask); - new_inst.Instruction.NumSrcRegs = 2; - reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X,Y,Z,W)); - reg_src(&new_inst.Src[1], &ctx->tmp[B].src, SWIZ(X,X,X,X)); - tctx->emit_instruction(tctx, &new_inst); - - opcode = TGSI_OPCODE_TEX; - } - - /* MOV_SAT tmpA.<mask>, tmpA */ - create_mov(tctx, &ctx->tmp[A].dst, &ctx->tmp[A].src, mask, - TGSI_SAT_ZERO_ONE); - - /* modify the texture samp instruction to take fixed up coord: */ - new_inst = *inst; - new_inst.Instruction.Opcode = opcode; - new_inst.Src[0] = ctx->tmp[A].src; - tctx->emit_instruction(tctx, &new_inst); - - return 0; + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_full_src_register *coord = &inst->Src[0]; + struct tgsi_full_src_register *samp; + struct tgsi_full_instruction new_inst; + /* mask is clamped coords, pmask is all coords (for projection): */ + unsigned mask = 0, pmask = 0, smask; + unsigned opcode = inst->Instruction.Opcode; + + if (opcode == TGSI_OPCODE_TXB2) { + samp = &inst->Src[2]; + } else { + samp = &inst->Src[1]; + } + + /* convert sampler # to bitmask to test: */ + smask = 1 << samp->Register.Index; + + /* check if we actually need to lower this one: */ + if (!(ctx->saturate & smask)) + return -1; + + /* figure out which coordinates need saturating: + * - RECT textures should not get saturated + * - array index coords should not get saturated + */ + switch (inst->Texture.Texture) { + case TGSI_TEXTURE_3D: + case TGSI_TEXTURE_CUBE: + case TGSI_TEXTURE_CUBE_ARRAY: + case TGSI_TEXTURE_SHADOWCUBE: + case TGSI_TEXTURE_SHADOWCUBE_ARRAY: + if (ctx->config->saturate_r & smask) + mask |= TGSI_WRITEMASK_Z; + pmask |= TGSI_WRITEMASK_Z; + /* fallthrough */ + + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_2D_ARRAY: + case TGSI_TEXTURE_SHADOW2D: + case TGSI_TEXTURE_SHADOW2D_ARRAY: + case TGSI_TEXTURE_2D_MSAA: + case TGSI_TEXTURE_2D_ARRAY_MSAA: + if (ctx->config->saturate_t & smask) + mask |= TGSI_WRITEMASK_Y; + pmask |= TGSI_WRITEMASK_Y; + /* fallthrough */ + + case TGSI_TEXTURE_1D: + case TGSI_TEXTURE_1D_ARRAY: + case TGSI_TEXTURE_SHADOW1D: + case TGSI_TEXTURE_SHADOW1D_ARRAY: + if (ctx->config->saturate_s & smask) + mask |= TGSI_WRITEMASK_X; + pmask |= TGSI_WRITEMASK_X; + break; + + /* TODO: I think we should ignore these? + case TGSI_TEXTURE_RECT: + case TGSI_TEXTURE_SHADOWRECT: + */ + } + + /* sanity check.. driver could be asking to saturate a non- + * existent coordinate component: + */ + if (!mask) + return -1; + + /* MOV tmpA, src0 */ + create_mov(tctx, &ctx->tmp[A].dst, coord, TGSI_WRITEMASK_XYZW, 0); + + /* This is a bit sad.. we need to clamp *after* the coords + * are projected, which means lowering TXP to TEX and doing + * the projection ourself. But since I haven't figured out + * how to make the lowering code deliver an electric shock + * to anyone using GL_CLAMP, we must do this instead: + */ + if (opcode == TGSI_OPCODE_TXP) { + /* RCP tmpB.x tmpA.w */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_RCP; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_X); + new_inst.Instruction.NumSrcRegs = 1; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(W, _, _, _)); + tctx->emit_instruction(tctx, &new_inst); + + /* MUL tmpA.mask, tmpA, tmpB.xxxx */ + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; + new_inst.Instruction.NumDstRegs = 1; + reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, pmask); + new_inst.Instruction.NumSrcRegs = 2; + reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); + reg_src(&new_inst.Src[1], &ctx->tmp[B].src, SWIZ(X, X, X, X)); + tctx->emit_instruction(tctx, &new_inst); + + opcode = TGSI_OPCODE_TEX; + } + + /* MOV_SAT tmpA.<mask>, tmpA */ + create_mov(tctx, &ctx->tmp[A].dst, &ctx->tmp[A].src, mask, + TGSI_SAT_ZERO_ONE); + + /* modify the texture samp instruction to take fixed up coord: */ + new_inst = *inst; + new_inst.Instruction.Opcode = opcode; + new_inst.Src[0] = ctx->tmp[A].src; + tctx->emit_instruction(tctx, &new_inst); + + return 0; } /* Two-sided color emulation: * For each COLOR input, create a corresponding BCOLOR input, plus * CMP instruction to select front or back color based on FACE */ -#define TWOSIDE_GROW(n) ( \ - 2 + /* FACE */ \ - ((n) * 2) + /* IN[] BCOLOR[n] */ \ - ((n) * 1) + /* TEMP[] */ \ - ((n) * NINST(3)) /* CMP instr */ \ - ) +#define TWOSIDE_GROW(n) ( \ + 2 + /* FACE */ \ + ((n) * 2) + /* IN[] BCOLOR[n] */ \ + ((n) * 1) + /* TEMP[] */ \ + ((n) * NINST(3)) /* CMP instr */ \ + ) static void emit_twoside(struct tgsi_transform_context *tctx) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_shader_info *info = ctx->info; - struct tgsi_full_declaration decl; - struct tgsi_full_instruction new_inst; - unsigned inbase, tmpbase; - int i; - - inbase = info->file_max[TGSI_FILE_INPUT] + 1; - tmpbase = info->file_max[TGSI_FILE_TEMPORARY] + 1; - - /* additional inputs for BCOLOR's */ - for (i = 0; i < ctx->two_side_colors; i++) { - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = true; - decl.Range.First = decl.Range.Last = inbase + i; - decl.Semantic.Name = TGSI_SEMANTIC_BCOLOR; - decl.Semantic.Index = - info->input_semantic_index[ctx->two_side_idx[i]]; - tctx->emit_declaration(tctx, &decl); - } - - /* additional input for FACE */ - if (ctx->two_side_colors && (ctx->face_idx == -1)) { - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = true; - decl.Range.First = decl.Range.Last = inbase + ctx->two_side_colors; - decl.Semantic.Name = TGSI_SEMANTIC_FACE; - decl.Semantic.Index = 0; - tctx->emit_declaration(tctx, &decl); - - ctx->face_idx = decl.Range.First; - } - - /* additional temps for COLOR/BCOLOR selection: */ - for (i = 0; i < ctx->two_side_colors; i++) { - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.Range.First = decl.Range.Last = tmpbase + ctx->numtmp + i; - tctx->emit_declaration(tctx, &decl); - } - - /* and finally additional instructions to select COLOR/BCOLOR: */ - for (i = 0; i < ctx->two_side_colors; i++) { - new_inst = tgsi_default_full_instruction(); - new_inst.Instruction.Opcode = TGSI_OPCODE_CMP; - - new_inst.Instruction.NumDstRegs = 1; - new_inst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; - new_inst.Dst[0].Register.Index = tmpbase + ctx->numtmp + i; - new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW; - - new_inst.Instruction.NumSrcRegs = 3; - new_inst.Src[0].Register.File = TGSI_FILE_INPUT; - new_inst.Src[0].Register.Index = ctx->face_idx; - new_inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X; - new_inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X; - new_inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X; - new_inst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_X; - new_inst.Src[1].Register.File = TGSI_FILE_INPUT; - new_inst.Src[1].Register.Index = inbase + i; - new_inst.Src[1].Register.SwizzleX = TGSI_SWIZZLE_X; - new_inst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_Y; - new_inst.Src[1].Register.SwizzleZ = TGSI_SWIZZLE_Z; - new_inst.Src[1].Register.SwizzleW = TGSI_SWIZZLE_W; - new_inst.Src[2].Register.File = TGSI_FILE_INPUT; - new_inst.Src[2].Register.Index = ctx->two_side_idx[i]; - new_inst.Src[2].Register.SwizzleX = TGSI_SWIZZLE_X; - new_inst.Src[2].Register.SwizzleY = TGSI_SWIZZLE_Y; - new_inst.Src[2].Register.SwizzleZ = TGSI_SWIZZLE_Z; - new_inst.Src[2].Register.SwizzleW = TGSI_SWIZZLE_W; - - tctx->emit_instruction(tctx, &new_inst); - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_shader_info *info = ctx->info; + struct tgsi_full_declaration decl; + struct tgsi_full_instruction new_inst; + unsigned inbase, tmpbase; + int i; + + inbase = info->file_max[TGSI_FILE_INPUT] + 1; + tmpbase = info->file_max[TGSI_FILE_TEMPORARY] + 1; + + /* additional inputs for BCOLOR's */ + for (i = 0; i < ctx->two_side_colors; i++) { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = true; + decl.Range.First = decl.Range.Last = inbase + i; + decl.Semantic.Name = TGSI_SEMANTIC_BCOLOR; + decl.Semantic.Index = + info->input_semantic_index[ctx->two_side_idx[i]]; + tctx->emit_declaration(tctx, &decl); + } + + /* additional input for FACE */ + if (ctx->two_side_colors && (ctx->face_idx == -1)) { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = true; + decl.Range.First = decl.Range.Last = inbase + ctx->two_side_colors; + decl.Semantic.Name = TGSI_SEMANTIC_FACE; + decl.Semantic.Index = 0; + tctx->emit_declaration(tctx, &decl); + + ctx->face_idx = decl.Range.First; + } + + /* additional temps for COLOR/BCOLOR selection: */ + for (i = 0; i < ctx->two_side_colors; i++) { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.Range.First = decl.Range.Last = tmpbase + ctx->numtmp + i; + tctx->emit_declaration(tctx, &decl); + } + + /* and finally additional instructions to select COLOR/BCOLOR: */ + for (i = 0; i < ctx->two_side_colors; i++) { + new_inst = tgsi_default_full_instruction(); + new_inst.Instruction.Opcode = TGSI_OPCODE_CMP; + + new_inst.Instruction.NumDstRegs = 1; + new_inst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; + new_inst.Dst[0].Register.Index = tmpbase + ctx->numtmp + i; + new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW; + + new_inst.Instruction.NumSrcRegs = 3; + new_inst.Src[0].Register.File = TGSI_FILE_INPUT; + new_inst.Src[0].Register.Index = ctx->face_idx; + new_inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X; + new_inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X; + new_inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X; + new_inst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_X; + new_inst.Src[1].Register.File = TGSI_FILE_INPUT; + new_inst.Src[1].Register.Index = inbase + i; + new_inst.Src[1].Register.SwizzleX = TGSI_SWIZZLE_X; + new_inst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_Y; + new_inst.Src[1].Register.SwizzleZ = TGSI_SWIZZLE_Z; + new_inst.Src[1].Register.SwizzleW = TGSI_SWIZZLE_W; + new_inst.Src[2].Register.File = TGSI_FILE_INPUT; + new_inst.Src[2].Register.Index = ctx->two_side_idx[i]; + new_inst.Src[2].Register.SwizzleX = TGSI_SWIZZLE_X; + new_inst.Src[2].Register.SwizzleY = TGSI_SWIZZLE_Y; + new_inst.Src[2].Register.SwizzleZ = TGSI_SWIZZLE_Z; + new_inst.Src[2].Register.SwizzleW = TGSI_SWIZZLE_W; + + tctx->emit_instruction(tctx, &new_inst); + } } static void emit_decls(struct tgsi_transform_context *tctx) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - struct tgsi_shader_info *info = ctx->info; - struct tgsi_full_declaration decl; - struct tgsi_full_immediate immed; - unsigned tmpbase; - int i; - - tmpbase = info->file_max[TGSI_FILE_TEMPORARY] + 1; - - ctx->color_base = tmpbase + ctx->numtmp; - - /* declare immediate: */ - immed = tgsi_default_full_immediate(); - immed.Immediate.NrTokens = 1 + 4; /* one for the token itself */ - immed.u[0].Float = 0.0; - immed.u[1].Float = 1.0; - immed.u[2].Float = 128.0; - immed.u[3].Float = 0.0; - tctx->emit_immediate(tctx, &immed); - - ctx->imm.Register.File = TGSI_FILE_IMMEDIATE; - ctx->imm.Register.Index = info->immediate_count; - ctx->imm.Register.SwizzleX = TGSI_SWIZZLE_X; - ctx->imm.Register.SwizzleY = TGSI_SWIZZLE_Y; - ctx->imm.Register.SwizzleZ = TGSI_SWIZZLE_Z; - ctx->imm.Register.SwizzleW = TGSI_SWIZZLE_W; - - /* declare temp regs: */ - for (i = 0; i < ctx->numtmp; i++) { - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.Range.First = decl.Range.Last = tmpbase + i; - tctx->emit_declaration(tctx, &decl); - - ctx->tmp[i].src.Register.File = TGSI_FILE_TEMPORARY; - ctx->tmp[i].src.Register.Index = tmpbase + i; - ctx->tmp[i].src.Register.SwizzleX = TGSI_SWIZZLE_X; - ctx->tmp[i].src.Register.SwizzleY = TGSI_SWIZZLE_Y; - ctx->tmp[i].src.Register.SwizzleZ = TGSI_SWIZZLE_Z; - ctx->tmp[i].src.Register.SwizzleW = TGSI_SWIZZLE_W; - - ctx->tmp[i].dst.Register.File = TGSI_FILE_TEMPORARY; - ctx->tmp[i].dst.Register.Index = tmpbase + i; - ctx->tmp[i].dst.Register.WriteMask = TGSI_WRITEMASK_XYZW; - } - - if (ctx->two_side_colors) - emit_twoside(tctx); + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + struct tgsi_shader_info *info = ctx->info; + struct tgsi_full_declaration decl; + struct tgsi_full_immediate immed; + unsigned tmpbase; + int i; + + tmpbase = info->file_max[TGSI_FILE_TEMPORARY] + 1; + + ctx->color_base = tmpbase + ctx->numtmp; + + /* declare immediate: */ + immed = tgsi_default_full_immediate(); + immed.Immediate.NrTokens = 1 + 4; /* one for the token itself */ + immed.u[0].Float = 0.0; + immed.u[1].Float = 1.0; + immed.u[2].Float = 128.0; + immed.u[3].Float = 0.0; + tctx->emit_immediate(tctx, &immed); + + ctx->imm.Register.File = TGSI_FILE_IMMEDIATE; + ctx->imm.Register.Index = info->immediate_count; + ctx->imm.Register.SwizzleX = TGSI_SWIZZLE_X; + ctx->imm.Register.SwizzleY = TGSI_SWIZZLE_Y; + ctx->imm.Register.SwizzleZ = TGSI_SWIZZLE_Z; + ctx->imm.Register.SwizzleW = TGSI_SWIZZLE_W; + + /* declare temp regs: */ + for (i = 0; i < ctx->numtmp; i++) { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.Range.First = decl.Range.Last = tmpbase + i; + tctx->emit_declaration(tctx, &decl); + + ctx->tmp[i].src.Register.File = TGSI_FILE_TEMPORARY; + ctx->tmp[i].src.Register.Index = tmpbase + i; + ctx->tmp[i].src.Register.SwizzleX = TGSI_SWIZZLE_X; + ctx->tmp[i].src.Register.SwizzleY = TGSI_SWIZZLE_Y; + ctx->tmp[i].src.Register.SwizzleZ = TGSI_SWIZZLE_Z; + ctx->tmp[i].src.Register.SwizzleW = TGSI_SWIZZLE_W; + + ctx->tmp[i].dst.Register.File = TGSI_FILE_TEMPORARY; + ctx->tmp[i].dst.Register.Index = tmpbase + i; + ctx->tmp[i].dst.Register.WriteMask = TGSI_WRITEMASK_XYZW; + } + + if (ctx->two_side_colors) + emit_twoside(tctx); } static void rename_color_inputs(struct fd_lowering_context *ctx, - struct tgsi_full_instruction *inst) + struct tgsi_full_instruction *inst) { - unsigned i, j; - for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { - struct tgsi_src_register *src = &inst->Src[i].Register; - if (src->File == TGSI_FILE_INPUT) { - for (j = 0; j < ctx->two_side_colors; j++) { - if (src->Index == ctx->two_side_idx[j]) { - src->File = TGSI_FILE_TEMPORARY; - src->Index = ctx->color_base + j; - break; - } - } - } - } + unsigned i, j; + for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { + struct tgsi_src_register *src = &inst->Src[i].Register; + if (src->File == TGSI_FILE_INPUT) { + for (j = 0; j < ctx->two_side_colors; j++) { + if (src->Index == ctx->two_side_idx[j]) { + src->File = TGSI_FILE_TEMPORARY; + src->Index = ctx->color_base + j; + break; + } + } + } + } } @@ -1308,103 +1306,103 @@ static void transform_instr(struct tgsi_transform_context *tctx, struct tgsi_full_instruction *inst) { - struct fd_lowering_context *ctx = fd_lowering_context(tctx); - - if (!ctx->emitted_decls) { - emit_decls(tctx); - ctx->emitted_decls = 1; - } - - /* if emulating two-sided-color, we need to re-write some - * src registers: - */ - if (ctx->two_side_colors) - rename_color_inputs(ctx, inst); - - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_DST: - if (!ctx->config->lower_DST) - goto skip; - transform_dst(tctx, inst); - break; - case TGSI_OPCODE_XPD: - if (!ctx->config->lower_XPD) - goto skip; - transform_xpd(tctx, inst); - break; - case TGSI_OPCODE_SCS: - if (!ctx->config->lower_SCS) - goto skip; - transform_scs(tctx, inst); - break; - case TGSI_OPCODE_LRP: - if (!ctx->config->lower_LRP) - goto skip; - transform_lrp(tctx, inst); - break; - case TGSI_OPCODE_FRC: - if (!ctx->config->lower_FRC) - goto skip; - transform_frc(tctx, inst); - break; - case TGSI_OPCODE_POW: - if (!ctx->config->lower_POW) - goto skip; - transform_pow(tctx, inst); - break; - case TGSI_OPCODE_LIT: - if (!ctx->config->lower_LIT) - goto skip; - transform_lit(tctx, inst); - break; - case TGSI_OPCODE_EXP: - if (!ctx->config->lower_EXP) - goto skip; - transform_exp(tctx, inst); - break; - case TGSI_OPCODE_LOG: - if (!ctx->config->lower_LOG) - goto skip; - transform_log(tctx, inst); - break; - case TGSI_OPCODE_DP4: - if (!ctx->config->lower_DP4) - goto skip; - transform_dotp(tctx, inst); - break; - case TGSI_OPCODE_DP3: - if (!ctx->config->lower_DP3) - goto skip; - transform_dotp(tctx, inst); - break; - case TGSI_OPCODE_DPH: - if (!ctx->config->lower_DPH) - goto skip; - transform_dotp(tctx, inst); - break; - case TGSI_OPCODE_DP2: - if (!ctx->config->lower_DP2) - goto skip; - transform_dotp(tctx, inst); - break; - case TGSI_OPCODE_DP2A: - if (!ctx->config->lower_DP2A) - goto skip; - transform_dotp(tctx, inst); - break; - case TGSI_OPCODE_TEX: - case TGSI_OPCODE_TXP: - case TGSI_OPCODE_TXB: - case TGSI_OPCODE_TXB2: - case TGSI_OPCODE_TXL: - if (transform_samp(tctx, inst)) - goto skip; - break; - default: - skip: - tctx->emit_instruction(tctx, inst); - break; - } + struct fd_lowering_context *ctx = fd_lowering_context(tctx); + + if (!ctx->emitted_decls) { + emit_decls(tctx); + ctx->emitted_decls = 1; + } + + /* if emulating two-sided-color, we need to re-write some + * src registers: + */ + if (ctx->two_side_colors) + rename_color_inputs(ctx, inst); + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_DST: + if (!ctx->config->lower_DST) + goto skip; + transform_dst(tctx, inst); + break; + case TGSI_OPCODE_XPD: + if (!ctx->config->lower_XPD) + goto skip; + transform_xpd(tctx, inst); + break; + case TGSI_OPCODE_SCS: + if (!ctx->config->lower_SCS) + goto skip; + transform_scs(tctx, inst); + break; + case TGSI_OPCODE_LRP: + if (!ctx->config->lower_LRP) + goto skip; + transform_lrp(tctx, inst); + break; + case TGSI_OPCODE_FRC: + if (!ctx->config->lower_FRC) + goto skip; + transform_frc(tctx, inst); + break; + case TGSI_OPCODE_POW: + if (!ctx->config->lower_POW) + goto skip; + transform_pow(tctx, inst); + break; + case TGSI_OPCODE_LIT: + if (!ctx->config->lower_LIT) + goto skip; + transform_lit(tctx, inst); + break; + case TGSI_OPCODE_EXP: + if (!ctx->config->lower_EXP) + goto skip; + transform_exp(tctx, inst); + break; + case TGSI_OPCODE_LOG: + if (!ctx->config->lower_LOG) + goto skip; + transform_log(tctx, inst); + break; + case TGSI_OPCODE_DP4: + if (!ctx->config->lower_DP4) + goto skip; + transform_dotp(tctx, inst); + break; + case TGSI_OPCODE_DP3: + if (!ctx->config->lower_DP3) + goto skip; + transform_dotp(tctx, inst); + break; + case TGSI_OPCODE_DPH: + if (!ctx->config->lower_DPH) + goto skip; + transform_dotp(tctx, inst); + break; + case TGSI_OPCODE_DP2: + if (!ctx->config->lower_DP2) + goto skip; + transform_dotp(tctx, inst); + break; + case TGSI_OPCODE_DP2A: + if (!ctx->config->lower_DP2A) + goto skip; + transform_dotp(tctx, inst); + break; + case TGSI_OPCODE_TEX: + case TGSI_OPCODE_TXP: + case TGSI_OPCODE_TXB: + case TGSI_OPCODE_TXB2: + case TGSI_OPCODE_TXL: + if (transform_samp(tctx, inst)) + goto skip; + break; + default: + skip: + tctx->emit_instruction(tctx, inst); + break; + } } /* returns NULL if no lowering required, else returns the new @@ -1413,161 +1411,161 @@ transform_instr(struct tgsi_transform_context *tctx, */ const struct tgsi_token * fd_transform_lowering(const struct fd_lowering_config *config, - const struct tgsi_token *tokens, - struct tgsi_shader_info *info) + const struct tgsi_token *tokens, + struct tgsi_shader_info *info) { - struct fd_lowering_context ctx; - struct tgsi_token *newtoks; - int newlen, numtmp; - - /* sanity check in case limit is ever increased: */ - assert((sizeof(config->saturate_s) * 8) >= PIPE_MAX_SAMPLERS); - - memset(&ctx, 0, sizeof(ctx)); - ctx.base.transform_instruction = transform_instr; - ctx.info = info; - ctx.config = config; - - tgsi_scan_shader(tokens, info); - - /* if we are adding fragment shader support to emulate two-sided - * color, then figure out the number of additional inputs we need - * to create for BCOLOR's.. - */ - if ((info->processor == TGSI_PROCESSOR_FRAGMENT) && - config->color_two_side) { - int i; - ctx.face_idx = -1; - for (i = 0; i <= info->file_max[TGSI_FILE_INPUT]; i++) { - if (info->input_semantic_name[i] == TGSI_SEMANTIC_COLOR) - ctx.two_side_idx[ctx.two_side_colors++] = i; - if (info->input_semantic_name[i] == TGSI_SEMANTIC_FACE) - ctx.face_idx = i; - } - } - - ctx.saturate = config->saturate_r | config->saturate_s | config->saturate_t; + struct fd_lowering_context ctx; + struct tgsi_token *newtoks; + int newlen, numtmp; + + /* sanity check in case limit is ever increased: */ + assert((sizeof(config->saturate_s) * 8) >= PIPE_MAX_SAMPLERS); + + memset(&ctx, 0, sizeof(ctx)); + ctx.base.transform_instruction = transform_instr; + ctx.info = info; + ctx.config = config; + + tgsi_scan_shader(tokens, info); + + /* if we are adding fragment shader support to emulate two-sided + * color, then figure out the number of additional inputs we need + * to create for BCOLOR's.. + */ + if ((info->processor == TGSI_PROCESSOR_FRAGMENT) && + config->color_two_side) { + int i; + ctx.face_idx = -1; + for (i = 0; i <= info->file_max[TGSI_FILE_INPUT]; i++) { + if (info->input_semantic_name[i] == TGSI_SEMANTIC_COLOR) + ctx.two_side_idx[ctx.two_side_colors++] = i; + if (info->input_semantic_name[i] == TGSI_SEMANTIC_FACE) + ctx.face_idx = i; + } + } + + ctx.saturate = config->saturate_r | config->saturate_s | config->saturate_t; #define OPCS(x) ((config->lower_ ## x) ? info->opcode_count[TGSI_OPCODE_ ## x] : 0) - /* if there are no instructions to lower, then we are done: */ - if (!(OPCS(DST) || - OPCS(XPD) || - OPCS(SCS) || - OPCS(LRP) || - OPCS(FRC) || - OPCS(POW) || - OPCS(LIT) || - OPCS(EXP) || - OPCS(LOG) || - OPCS(DP4) || - OPCS(DP3) || - OPCS(DPH) || - OPCS(DP2) || - OPCS(DP2A) || - ctx.two_side_colors || - ctx.saturate)) - return NULL; + /* if there are no instructions to lower, then we are done: */ + if (!(OPCS(DST) || + OPCS(XPD) || + OPCS(SCS) || + OPCS(LRP) || + OPCS(FRC) || + OPCS(POW) || + OPCS(LIT) || + OPCS(EXP) || + OPCS(LOG) || + OPCS(DP4) || + OPCS(DP3) || + OPCS(DPH) || + OPCS(DP2) || + OPCS(DP2A) || + ctx.two_side_colors || + ctx.saturate)) + return NULL; #if 0 /* debug */ - _debug_printf("BEFORE:"); - tgsi_dump(tokens, 0); + _debug_printf("BEFORE:"); + tgsi_dump(tokens, 0); #endif - numtmp = 0; - newlen = tgsi_num_tokens(tokens); - if (OPCS(DST)) { - newlen += DST_GROW * OPCS(DST); - numtmp = MAX2(numtmp, DST_TMP); - } - if (OPCS(XPD)) { - newlen += XPD_GROW * OPCS(XPD); - numtmp = MAX2(numtmp, XPD_TMP); - } - if (OPCS(SCS)) { - newlen += SCS_GROW * OPCS(SCS); - numtmp = MAX2(numtmp, SCS_TMP); - } - if (OPCS(LRP)) { - newlen += LRP_GROW * OPCS(LRP); - numtmp = MAX2(numtmp, LRP_TMP); - } - if (OPCS(FRC)) { - newlen += FRC_GROW * OPCS(FRC); - numtmp = MAX2(numtmp, FRC_TMP); - } - if (OPCS(POW)) { - newlen += POW_GROW * OPCS(POW); - numtmp = MAX2(numtmp, POW_TMP); - } - if (OPCS(LIT)) { - newlen += LIT_GROW * OPCS(LIT); - numtmp = MAX2(numtmp, LIT_TMP); - } - if (OPCS(EXP)) { - newlen += EXP_GROW * OPCS(EXP); - numtmp = MAX2(numtmp, EXP_TMP); - } - if (OPCS(LOG)) { - newlen += LOG_GROW * OPCS(LOG); - numtmp = MAX2(numtmp, LOG_TMP); - } - if (OPCS(DP4)) { - newlen += DP4_GROW * OPCS(DP4); - numtmp = MAX2(numtmp, DOTP_TMP); - } - if (OPCS(DP3)) { - newlen += DP3_GROW * OPCS(DP3); - numtmp = MAX2(numtmp, DOTP_TMP); - } - if (OPCS(DPH)) { - newlen += DPH_GROW * OPCS(DPH); - numtmp = MAX2(numtmp, DOTP_TMP); - } - if (OPCS(DP2)) { - newlen += DP2_GROW * OPCS(DP2); - numtmp = MAX2(numtmp, DOTP_TMP); - } - if (OPCS(DP2A)) { - newlen += DP2A_GROW * OPCS(DP2A); - numtmp = MAX2(numtmp, DOTP_TMP); - } - if (ctx.saturate) { - int n = info->opcode_count[TGSI_OPCODE_TEX] + - info->opcode_count[TGSI_OPCODE_TXP] + - info->opcode_count[TGSI_OPCODE_TXB] + - info->opcode_count[TGSI_OPCODE_TXB2] + - info->opcode_count[TGSI_OPCODE_TXL]; - newlen += SAMP_GROW * n; - numtmp = MAX2(numtmp, SAMP_TMP); - } - - /* specifically don't include two_side_colors temps in the count: */ - ctx.numtmp = numtmp; - - if (ctx.two_side_colors) { - newlen += TWOSIDE_GROW(ctx.two_side_colors); - /* note: we permanently consume temp regs, re-writing references - * to IN.COLOR[n] to TEMP[m] (holding the output of of the CMP - * instruction that selects which varying to use): - */ - numtmp += ctx.two_side_colors; - } - - newlen += 2 * numtmp; - newlen += 5; /* immediate */ - - newtoks = tgsi_alloc_tokens(newlen); - if (!newtoks) - return NULL; - - tgsi_transform_shader(tokens, newtoks, newlen, &ctx.base); - - tgsi_scan_shader(newtoks, info); + numtmp = 0; + newlen = tgsi_num_tokens(tokens); + if (OPCS(DST)) { + newlen += DST_GROW * OPCS(DST); + numtmp = MAX2(numtmp, DST_TMP); + } + if (OPCS(XPD)) { + newlen += XPD_GROW * OPCS(XPD); + numtmp = MAX2(numtmp, XPD_TMP); + } + if (OPCS(SCS)) { + newlen += SCS_GROW * OPCS(SCS); + numtmp = MAX2(numtmp, SCS_TMP); + } + if (OPCS(LRP)) { + newlen += LRP_GROW * OPCS(LRP); + numtmp = MAX2(numtmp, LRP_TMP); + } + if (OPCS(FRC)) { + newlen += FRC_GROW * OPCS(FRC); + numtmp = MAX2(numtmp, FRC_TMP); + } + if (OPCS(POW)) { + newlen += POW_GROW * OPCS(POW); + numtmp = MAX2(numtmp, POW_TMP); + } + if (OPCS(LIT)) { + newlen += LIT_GROW * OPCS(LIT); + numtmp = MAX2(numtmp, LIT_TMP); + } + if (OPCS(EXP)) { + newlen += EXP_GROW * OPCS(EXP); + numtmp = MAX2(numtmp, EXP_TMP); + } + if (OPCS(LOG)) { + newlen += LOG_GROW * OPCS(LOG); + numtmp = MAX2(numtmp, LOG_TMP); + } + if (OPCS(DP4)) { + newlen += DP4_GROW * OPCS(DP4); + numtmp = MAX2(numtmp, DOTP_TMP); + } + if (OPCS(DP3)) { + newlen += DP3_GROW * OPCS(DP3); + numtmp = MAX2(numtmp, DOTP_TMP); + } + if (OPCS(DPH)) { + newlen += DPH_GROW * OPCS(DPH); + numtmp = MAX2(numtmp, DOTP_TMP); + } + if (OPCS(DP2)) { + newlen += DP2_GROW * OPCS(DP2); + numtmp = MAX2(numtmp, DOTP_TMP); + } + if (OPCS(DP2A)) { + newlen += DP2A_GROW * OPCS(DP2A); + numtmp = MAX2(numtmp, DOTP_TMP); + } + if (ctx.saturate) { + int n = info->opcode_count[TGSI_OPCODE_TEX] + + info->opcode_count[TGSI_OPCODE_TXP] + + info->opcode_count[TGSI_OPCODE_TXB] + + info->opcode_count[TGSI_OPCODE_TXB2] + + info->opcode_count[TGSI_OPCODE_TXL]; + newlen += SAMP_GROW * n; + numtmp = MAX2(numtmp, SAMP_TMP); + } + + /* specifically don't include two_side_colors temps in the count: */ + ctx.numtmp = numtmp; + + if (ctx.two_side_colors) { + newlen += TWOSIDE_GROW(ctx.two_side_colors); + /* note: we permanently consume temp regs, re-writing references + * to IN.COLOR[n] to TEMP[m] (holding the output of of the CMP + * instruction that selects which varying to use): + */ + numtmp += ctx.two_side_colors; + } + + newlen += 2 * numtmp; + newlen += 5; /* immediate */ + + newtoks = tgsi_alloc_tokens(newlen); + if (!newtoks) + return NULL; + + tgsi_transform_shader(tokens, newtoks, newlen, &ctx.base); + + tgsi_scan_shader(newtoks, info); #if 0 /* debug */ - _debug_printf("AFTER:"); - tgsi_dump(newtoks, 0); + _debug_printf("AFTER:"); + tgsi_dump(newtoks, 0); #endif - return newtoks; + return newtoks; } |