freedreno: use tgsi_lowering
authorRob Clark <robclark@freedesktop.org>
Wed, 1 Oct 2014 00:09:11 +0000 (20:09 -0400)
committerRob Clark <robclark@freedesktop.org>
Tue, 14 Oct 2014 16:30:08 +0000 (12:30 -0400)
Now that the freedreno_lowering code is moved to tgsi_lowering, remove
our private copy and switch over to using the common version.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/Makefile.sources
src/gallium/drivers/freedreno/a3xx/fd3_program.c
src/gallium/drivers/freedreno/freedreno_lowering.c [deleted file]
src/gallium/drivers/freedreno/freedreno_lowering.h [deleted file]
src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
src/gallium/drivers/freedreno/ir3/ir3_compiler.c
src/gallium/drivers/freedreno/ir3/ir3_compiler_old.c
src/gallium/drivers/freedreno/ir3/ir3_shader.c

index 9d4cbe381570723f5d2f0f8d3195f6f8bc9afda6..edaaadfb4781ae57fd28efc309c5668da510f2d1 100644 (file)
@@ -10,8 +10,6 @@ C_SOURCES := \
        freedreno_fence.h \
        freedreno_gmem.c \
        freedreno_gmem.h \
-       freedreno_lowering.c \
-       freedreno_lowering.h \
        freedreno_program.c \
        freedreno_program.h \
        freedreno_query.c \
index 64c9668129bfb49513e70c5617459075cf31677c..46a9398a7b46d6e175e04ab4efd9a8b927b8b0f2 100644 (file)
@@ -34,7 +34,6 @@
 #include "tgsi/tgsi_dump.h"
 #include "tgsi/tgsi_parse.h"
 
-#include "freedreno_lowering.h"
 #include "freedreno_program.h"
 
 #include "fd3_program.h"
diff --git a/src/gallium/drivers/freedreno/freedreno_lowering.c b/src/gallium/drivers/freedreno/freedreno_lowering.c
deleted file mode 100644 (file)
index 795b537..0000000
+++ /dev/null
@@ -1,1573 +0,0 @@
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Rob Clark <robclark@freedesktop.org>
- */
-
-#include "tgsi/tgsi_transform.h"
-#include "tgsi/tgsi_scan.h"
-#include "tgsi/tgsi_dump.h"
-
-#include "util/u_debug.h"
-#include "util/u_math.h"
-
-#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];
-#define A 0
-#define B 1
-       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;
-}
-
-/*
- * Utility helpers:
- */
-
-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);
-}
-
-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;
-}
-
-static void
-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];
-}
-
-#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
-
-/*
- * if (dst.x aliases src.x) {
- *   MOV tmpA.x, src.x
- *   src = tmpA
- * }
- * COS dst.x, src.x
- * SIN dst.y, src.x
- * MOV dst.zw, imm{0.0, 1.0}
- */
-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;
-}
-
-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)
-{
-       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
- * the worst case, ie. removed instructions don't have ADDR[] or
- * anything which increases the # of tokens per src/dst and the
- * inserted instructions do.
- *
- * OINST() - old instruction
- *    1         : instruction itself
- *    1         : dst
- *    1 * nargs : srcN
- *
- * NINST() - new instruction
- *    1         : instruction itself
- *    2         : dst
- *    2 * nargs : srcN
- */
-
-#define OINST(nargs)  (1 + 1 + 1 * (nargs))
-#define NINST(nargs)  (1 + 2 + 2 * (nargs))
-
-/*
- * Lowering Translators:
- */
-
-/* DST - Distance Vector
- *   dst.x = 1.0
- *   dst.y = src0.y \times src1.y
- *   dst.z = src0.z
- *   dst.w = src1.w
- *
- * ; note: could be more clever and use just a single temp
- * ;       if I was clever enough to re-write the swizzles.
- * ; needs: 2 tmp, imm{1.0}
- * if (dst.y aliases src0.z) {
- *   MOV tmpA.yz, src0.yz
- *   src0 = tmpA
- * }
- * if (dst.yz aliases src1.w) {
- *   MOV tmpB.yw, src1.yw
- *   src1 = tmpB
- * }
- * MUL dst.y, src0.y, src1.y
- * MOV dst.z, src0.z
- * MOV dst.w, src1.w
- * MOV dst.x, imm{1.0}
- */
-#define DST_GROW (NINST(1) + NINST(1) + NINST(2) + NINST(1) + \
-               NINST(1) + NINST(1) - OINST(2))
-#define DST_TMP  2
-static void
-transform_dst(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* XPD - Cross Product
- *   dst.x = src0.y \times src1.z - src1.y \times src0.z
- *   dst.y = src0.z \times src1.x - src1.z \times src0.x
- *   dst.z = src0.x \times src1.y - src1.x \times src0.y
- *   dst.w = 1.0
- *
- * ; needs: 2 tmp, imm{1.0}
- * MUL tmpA.xyz, src0.yzx, src1.zxy
- * MUL tmpB.xyz, src1.yzx, src0.zxy
- * SUB dst.xyz, tmpA.xyz, tmpB.xyz
- * MOV dst.w, imm{1.0}
- */
-#define XPD_GROW (NINST(2) + NINST(2) + NINST(2) + NINST(1) - OINST(2))
-#define XPD_TMP  2
-static void
-transform_xpd(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* SCS - Sine Cosine
- *   dst.x = \cos{src.x}
- *   dst.y = \sin{src.x}
- *   dst.z = 0.0
- *   dst.w = 1.0
- *
- * ; needs: 1 tmp, imm{0.0, 1.0}
- * if (dst.x aliases src.x) {
- *   MOV tmpA.x, src.x
- *   src = tmpA
- * }
- * COS dst.x, src.x
- * SIN dst.y, src.x
- * MOV dst.zw, imm{0.0, 1.0}
- */
-#define SCS_GROW (NINST(1) + NINST(1) + NINST(1) + NINST(1) - OINST(1))
-#define SCS_TMP  1
-static void
-transform_scs(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* LRP - Linear Interpolate
- *  dst.x = src0.x \times src1.x + (1.0 - src0.x) \times src2.x
- *  dst.y = src0.y \times src1.y + (1.0 - src0.y) \times src2.y
- *  dst.z = src0.z \times src1.z + (1.0 - src0.z) \times src2.z
- *  dst.w = src0.w \times src1.w + (1.0 - src0.w) \times src2.w
- *
- * ; needs: 2 tmp, imm{1.0}
- * MUL tmpA, src0, src1
- * SUB tmpB, imm{1.0}, src0
- * MUL tmpB, tmpB, src2
- * ADD dst, tmpA, tmpB
- */
-#define LRP_GROW (NINST(2) + NINST(2) + NINST(2) + NINST(2) - OINST(3))
-#define LRP_TMP  2
-static void
-transform_lrp(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* FRC - Fraction
- *  dst.x = src.x - \lfloor src.x\rfloor
- *  dst.y = src.y - \lfloor src.y\rfloor
- *  dst.z = src.z - \lfloor src.z\rfloor
- *  dst.w = src.w - \lfloor src.w\rfloor
- *
- * ; needs: 1 tmp
- * FLR tmpA, src
- * SUB dst, src, tmpA
- */
-#define FRC_GROW (NINST(1) + NINST(2) - OINST(1))
-#define FRC_TMP  1
-static void
-transform_frc(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* POW - Power
- *  dst.x = src0.x^{src1.x}
- *  dst.y = src0.x^{src1.x}
- *  dst.z = src0.x^{src1.x}
- *  dst.w = src0.x^{src1.x}
- *
- * ; needs: 1 tmp
- * LG2 tmpA.x, src0.x
- * MUL tmpA.x, src1.x, tmpA.x
- * EX2 dst, tmpA.x
- */
-#define POW_GROW (NINST(1) + NINST(2) + NINST(1) - OINST(2))
-#define POW_TMP  1
-static void
-transform_pow(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* LIT - Light Coefficients
- *  dst.x = 1.0
- *  dst.y = max(src.x, 0.0)
- *  dst.z = (src.x > 0.0) ? max(src.y, 0.0)^{clamp(src.w, -128.0, 128.0))} : 0
- *  dst.w = 1.0
- *
- * ; needs: 1 tmp, imm{0.0}, imm{1.0}, imm{128.0}
- * MAX tmpA.xy, src.xy, imm{0.0}
- * CLAMP tmpA.z, src.w, -imm{128.0}, imm{128.0}
- * LG2 tmpA.y, tmpA.y
- * MUL tmpA.y, tmpA.z, tmpA.y
- * EX2 tmpA.y, tmpA.y
- * CMP tmpA.y, -src.x, tmpA.y, imm{0.0}
- * MOV dst.yz, tmpA.xy
- * MOV dst.xw, imm{1.0}
- */
-#define LIT_GROW (NINST(1) + NINST(3) + NINST(1) + NINST(2) + \
-               NINST(1) + NINST(3) + NINST(1) + NINST(1) - OINST(1))
-#define LIT_TMP  1
-static void
-transform_lit(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* EXP - Approximate Exponential Base 2
- *  dst.x = 2^{\lfloor src.x\rfloor}
- *  dst.y = src.x - \lfloor src.x\rfloor
- *  dst.z = 2^{src.x}
- *  dst.w = 1.0
- *
- * ; needs: 1 tmp, imm{1.0}
- * FLR tmpA.x, src.x
- * EX2 tmpA.y, src.x
- * SUB dst.y, src.x, tmpA.x
- * EX2 dst.x, tmpA.x
- * MOV dst.z, tmpA.y
- * MOV dst.w, imm{1.0}
- */
-#define EXP_GROW (NINST(1) + NINST(1) + NINST(2) + NINST(1) + \
-               NINST(1)+ NINST(1) - OINST(1))
-#define EXP_TMP  1
-static void
-transform_exp(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* LOG - Approximate Logarithm Base 2
- *  dst.x = \lfloor\log_2{|src.x|}\rfloor
- *  dst.y = \frac{|src.x|}{2^{\lfloor\log_2{|src.x|}\rfloor}}
- *  dst.z = \log_2{|src.x|}
- *  dst.w = 1.0
- *
- * ; needs: 1 tmp, imm{1.0}
- * LG2 tmpA.x, |src.x|
- * FLR tmpA.y, tmpA.x
- * EX2 tmpA.z, tmpA.y
- * RCP tmpA.z, tmpA.z
- * MUL dst.y, |src.x|, tmpA.z
- * MOV dst.xz, tmpA.yx
- * MOV dst.w, imm{1.0}
- */
-#define LOG_GROW (NINST(1) + NINST(1) + NINST(1) + NINST(1) + \
-               NINST(2) + NINST(1) + NINST(1) - OINST(1))
-#define LOG_TMP  1
-static void
-transform_log(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* DP4 - 4-component Dot Product
- *   dst = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w
- *
- * DP3 - 3-component Dot Product
- *   dst = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z
- *
- * DPH - Homogeneous Dot Product
- *   dst = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w
- *
- * DP2 - 2-component Dot Product
- *   dst = src0.x \times src1.x + src0.y \times src1.y
- *
- * DP2A - 2-component Dot Product And Add
- *   dst = src0.x \times src1.x + src0.y \times src1.y + src2.x
- *
- * NOTE: these are translated into sequence of MUL/MAD(/ADD) scalar
- * operations, which is what you'd prefer for a ISA that is natively
- * scalar.  Probably a native vector ISA would at least already have
- * DP4/DP3 instructions, but perhaps there is room for an alternative
- * translation for DPH/DP2/DP2A using vector instructions.
- *
- * ; needs: 1 tmp
- * MUL tmpA.x, src0.x, src1.x
- * MAD tmpA.x, src0.y, src1.y, tmpA.x
- * if (DPH || DP3 || DP4) {
- *   MAD tmpA.x, src0.z, src1.z, tmpA.x
- *   if (DPH) {
- *     ADD tmpA.x, src1.w, tmpA.x
- *   } else if (DP4) {
- *     MAD tmpA.x, src0.w, src1.w, tmpA.x
- *   }
- * } else if (DP2A) {
- *   ADD tmpA.x, src2.x, tmpA.x
- * }
- * ; fixup last instruction to replicate into dst
- */
-#define DP4_GROW  (NINST(2) + NINST(3) + NINST(3) + NINST(3) - OINST(2))
-#define DP3_GROW  (NINST(2) + NINST(3) + NINST(3) - OINST(2))
-#define DPH_GROW  (NINST(2) + NINST(3) + NINST(3) + NINST(2) - OINST(2))
-#define DP2_GROW  (NINST(2) + NINST(3) - OINST(2))
-#define DP2A_GROW (NINST(2) + NINST(3) + NINST(2) - OINST(3))
-#define DOTP_TMP  1
-static void
-transform_dotp(struct tgsi_transform_context *tctx,
-               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);
-       }
-}
-
-/* Inserts a MOV_SAT for the needed components of tex coord.  Note that
- * in the case of TXP, the clamping must happen *after* projection, so
- * we need to lower TXP to TEX.
- *
- *   MOV tmpA, src0
- *   if (opc == TXP) {
- *     ; do perspective division manually before clamping:
- *     RCP tmpB, tmpA.w
- *     MUL tmpB.<pmask>, tmpA, tmpB.xxxx
- *     opc = TEX;
- *   }
- *   MOV_SAT tmpA.<mask>, tmpA  ; <mask> is the clamped s/t/r coords
- *   <opc> dst, tmpA, ...
- */
-#define SAMP_GROW (NINST(1) + NINST(1) + NINST(2) + NINST(1))
-#define SAMP_TMP  2
-static int
-transform_samp(struct tgsi_transform_context *tctx,
-               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;
-}
-
-/* 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 */   \
-               )
-
-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);
-       }
-}
-
-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);
-}
-
-static void
-rename_color_inputs(struct fd_lowering_context *ctx,
-               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;
-                               }
-                       }
-               }
-       }
-
-}
-
-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;
-       }
-}
-
-/* returns NULL if no lowering required, else returns the new
- * tokens (which caller is required to free()).  In either case
- * returns the current info.
- */
-const struct tgsi_token *
-fd_transform_lowering(const struct fd_lowering_config *config,
-               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;
-
-#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 0  /* debug */
-       _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);
-
-#if 0  /* debug */
-       _debug_printf("AFTER:");
-       tgsi_dump(newtoks, 0);
-#endif
-
-       return newtoks;
-}
diff --git a/src/gallium/drivers/freedreno/freedreno_lowering.h b/src/gallium/drivers/freedreno/freedreno_lowering.h
deleted file mode 100644 (file)
index 1b0daa9..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Rob Clark <robclark@freedesktop.org>
- */
-
-#ifndef FREEDRENO_LOWERING_H_
-#define FREEDRENO_LOWERING_H_
-
-#include "pipe/p_shader_tokens.h"
-#include "tgsi/tgsi_scan.h"
-
-struct fd_lowering_config {
-       /* For fragment shaders, generate a shader that emulates two
-        * sided color by inserting a BGCOLOR input for each COLOR
-        * input, and insert a CMP instruction to select the correct
-        * color to use based on the TGSI_SEMANTIC_FACE input.
-        *
-        * Note that drivers which use this to emulate two sided color
-        * will:
-        *  a) need to generate (on demand) alternate shaders to use
-        *     depending on the rasterizer state (ie. whether two
-        *     sided shading enabled)
-        *  b) expect to see the BGCOLOR semantic name in fragment
-        *     shaders.  During linkage, the driver should simply
-        *     map VS.OUT.BGCOLOR[n] to FS.IN.BGCOLOR[n] (in the
-        *     same was as linking other outs/ins).
-        */
-       unsigned color_two_side : 1;
-
-       /* TODO support for alpha_to_one as well?? */
-
-       /* Individual OPC lowerings, if lower_<opc> is TRUE then
-        * enable lowering of TGSI_OPCODE_<opc>
-        */
-       unsigned lower_DST : 1;
-       unsigned lower_XPD : 1;
-       unsigned lower_SCS : 1;
-       unsigned lower_LRP : 1;
-       unsigned lower_FRC : 1;
-       unsigned lower_POW : 1;
-       unsigned lower_LIT : 1;
-       unsigned lower_EXP : 1;
-       unsigned lower_LOG : 1;
-       unsigned lower_DP4 : 1;
-       unsigned lower_DP3 : 1;
-       unsigned lower_DPH : 1;
-       unsigned lower_DP2 : 1;
-       unsigned lower_DP2A : 1;
-
-       /* To emulate certain texture wrap modes, this can be used
-        * to saturate the specified tex coord to [0.0, 1.0].  The
-        * bits are according to sampler #, ie. if, for example:
-        *
-        *   (conf->saturate_s & (1 << n))
-        *
-        * is true, then the s coord for sampler n is saturated.
-        */
-       unsigned saturate_s, saturate_t, saturate_r;
-};
-
-const struct tgsi_token * fd_transform_lowering(
-               const struct fd_lowering_config *config,
-               const struct tgsi_token *tokens,
-               struct tgsi_shader_info *info);
-
-#endif /* FREEDRENO_LOWERING_H_ */
index 5e1832586e8b6c92357bb4f314a3cf2a0857d22d..86239b45465d83c2cbbf388c6192a501a96b77d2 100644 (file)
@@ -37,7 +37,6 @@
 #include "tgsi/tgsi_dump.h"
 
 #include "freedreno_util.h"
-#include "freedreno_lowering.h"
 
 #include "ir3_compiler.h"
 #include "instr-a3xx.h"
index 80676830dd7f42c0dfdbaabb2f0f2cca90973374..1a5119c074f7f1ceec3e79bc597fabe0d4fa25af 100644 (file)
@@ -32,6 +32,7 @@
 #include "util/u_string.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
+#include "tgsi/tgsi_lowering.h"
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_ureg.h"
 #include "tgsi/tgsi_info.h"
@@ -39,7 +40,6 @@
 #include "tgsi/tgsi_dump.h"
 #include "tgsi/tgsi_scan.h"
 
-#include "freedreno_lowering.h"
 #include "freedreno_util.h"
 
 #include "ir3_compiler.h"
@@ -135,7 +135,7 @@ compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
 {
        unsigned ret;
        struct tgsi_shader_info *info = &ctx->info;
-       struct fd_lowering_config lconfig = {
+       struct tgsi_lowering_config lconfig = {
                        .color_two_side = so->key.color_two_side,
                        .lower_DST  = true,
                        .lower_XPD  = true,
@@ -167,7 +167,7 @@ compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
                break;
        }
 
-       ctx->tokens = fd_transform_lowering(&lconfig, tokens, &ctx->info);
+       ctx->tokens = tgsi_transform_lowering(&lconfig, tokens, &ctx->info);
        ctx->free_tokens = !!ctx->tokens;
        if (!ctx->tokens) {
                /* no lowering */
index 4267feb351fe76679e872abb279cfe92d9b8444a..335315685088abde6f8adbfa138d83aa147db8a9 100644 (file)
@@ -32,6 +32,7 @@
 #include "util/u_string.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
+#include "tgsi/tgsi_lowering.h"
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_ureg.h"
 #include "tgsi/tgsi_info.h"
@@ -39,7 +40,6 @@
 #include "tgsi/tgsi_dump.h"
 #include "tgsi/tgsi_scan.h"
 
-#include "freedreno_lowering.h"
 #include "freedreno_util.h"
 
 #include "ir3_compiler.h"
@@ -125,7 +125,7 @@ compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
 {
        unsigned ret, base = 0;
        struct tgsi_shader_info *info = &ctx->info;
-       struct fd_lowering_config lconfig = {
+       struct tgsi_lowering_config lconfig = {
                        .color_two_side = so->key.color_two_side,
                        .lower_DST  = true,
                        .lower_XPD  = true,
@@ -157,7 +157,7 @@ compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
                break;
        }
 
-       ctx->tokens = fd_transform_lowering(&lconfig, tokens, &ctx->info);
+       ctx->tokens = tgsi_transform_lowering(&lconfig, tokens, &ctx->info);
        ctx->free_tokens = !!ctx->tokens;
        if (!ctx->tokens) {
                /* no lowering */
index 31e302b92c2b377da5b424ac03531e3d059dd634..c77cec10cc7f7d19b60a983fef68d053a562c587 100644 (file)
@@ -35,7 +35,6 @@
 #include "tgsi/tgsi_parse.h"
 
 #include "freedreno_context.h"
-#include "freedreno_lowering.h"
 #include "freedreno_util.h"
 
 #include "ir3_shader.h"