13141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* 23141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org> 33141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 43141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 53141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * copy of this software and associated documentation files (the "Software"), 63141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * to deal in the Software without restriction, including without limitation 73141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 83141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * and/or sell copies of the Software, and to permit persons to whom the 93141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * Software is furnished to do so, subject to the following conditions: 103141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 113141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * The above copyright notice and this permission notice (including the next 123141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * paragraph) shall be included in all copies or substantial portions of the 133141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * Software. 143141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 153141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 163141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 173141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 183141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 193141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 203141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 213141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * SOFTWARE. 223141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 233141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * Authors: 243141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * Rob Clark <robclark@freedesktop.org> 253141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 263141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 273141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#include "tgsi/tgsi_transform.h" 283141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#include "tgsi/tgsi_scan.h" 293141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#include "tgsi/tgsi_dump.h" 303141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 313141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#include "util/u_debug.h" 323141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#include "util/u_math.h" 333141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 34f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt#include "tgsi_lowering.h" 353141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 36f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholtstruct tgsi_lowering_context { 3719df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_transform_context base; 38f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt const struct tgsi_lowering_config *config; 3919df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_shader_info *info; 4019df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned two_side_colors; 4119df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned two_side_idx[PIPE_MAX_SHADER_INPUTS]; 4219df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned color_base; /* base register for chosen COLOR/BCOLOR's */ 4319df602b39ec03f61edec308ad568be118beb3acEric Anholt int face_idx; 4419df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned numtmp; 4519df602b39ec03f61edec308ad568be118beb3acEric Anholt struct { 4619df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register src; 4719df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register dst; 4819df602b39ec03f61edec308ad568be118beb3acEric Anholt } tmp[2]; 493141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define A 0 503141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define B 1 5119df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register imm; 5219df602b39ec03f61edec308ad568be118beb3acEric Anholt int emitted_decls; 5319df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned saturate; 543141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt}; 553141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 56f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholtstatic inline struct tgsi_lowering_context * 57f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholttgsi_lowering_context(struct tgsi_transform_context *tctx) 583141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 59f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt return (struct tgsi_lowering_context *)tctx; 603141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 613141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 623141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* 633141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * Utility helpers: 643141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 653141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 663141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 673141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtreg_dst(struct tgsi_full_dst_register *dst, 683141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt const struct tgsi_full_dst_register *orig_dst, unsigned wrmask) 693141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 7019df602b39ec03f61edec308ad568be118beb3acEric Anholt *dst = *orig_dst; 7119df602b39ec03f61edec308ad568be118beb3acEric Anholt dst->Register.WriteMask &= wrmask; 7219df602b39ec03f61edec308ad568be118beb3acEric Anholt assert(dst->Register.WriteMask); 733141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 743141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 753141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic inline void 763141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtget_swiz(unsigned *swiz, const struct tgsi_src_register *src) 773141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 7819df602b39ec03f61edec308ad568be118beb3acEric Anholt swiz[0] = src->SwizzleX; 7919df602b39ec03f61edec308ad568be118beb3acEric Anholt swiz[1] = src->SwizzleY; 8019df602b39ec03f61edec308ad568be118beb3acEric Anholt swiz[2] = src->SwizzleZ; 8119df602b39ec03f61edec308ad568be118beb3acEric Anholt swiz[3] = src->SwizzleW; 823141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 833141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 843141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 853141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtreg_src(struct tgsi_full_src_register *src, 863141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt const struct tgsi_full_src_register *orig_src, 873141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt unsigned sx, unsigned sy, unsigned sz, unsigned sw) 883141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 8919df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned swiz[4]; 9019df602b39ec03f61edec308ad568be118beb3acEric Anholt get_swiz(swiz, &orig_src->Register); 9119df602b39ec03f61edec308ad568be118beb3acEric Anholt *src = *orig_src; 9219df602b39ec03f61edec308ad568be118beb3acEric Anholt src->Register.SwizzleX = swiz[sx]; 9319df602b39ec03f61edec308ad568be118beb3acEric Anholt src->Register.SwizzleY = swiz[sy]; 9419df602b39ec03f61edec308ad568be118beb3acEric Anholt src->Register.SwizzleZ = swiz[sz]; 9519df602b39ec03f61edec308ad568be118beb3acEric Anholt src->Register.SwizzleW = swiz[sw]; 963141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 973141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 983141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define TGSI_SWIZZLE__ TGSI_SWIZZLE_X /* don't-care value! */ 9919df602b39ec03f61edec308ad568be118beb3acEric Anholt#define SWIZ(x,y,z,w) TGSI_SWIZZLE_ ## x, TGSI_SWIZZLE_ ## y, \ 10019df602b39ec03f61edec308ad568be118beb3acEric Anholt TGSI_SWIZZLE_ ## z, TGSI_SWIZZLE_ ## w 1013141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 1023141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* 1033141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * if (dst.x aliases src.x) { 1043141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV tmpA.x, src.x 1053141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * src = tmpA 1063141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * } 1073141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * COS dst.x, src.x 1083141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * SIN dst.y, src.x 1093141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.zw, imm{0.0, 1.0} 1103141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 1113141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic bool 1123141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtaliases(const struct tgsi_full_dst_register *dst, unsigned dst_mask, 1133141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt const struct tgsi_full_src_register *src, unsigned src_mask) 1143141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 11519df602b39ec03f61edec308ad568be118beb3acEric Anholt if ((dst->Register.File == src->Register.File) && 11619df602b39ec03f61edec308ad568be118beb3acEric Anholt (dst->Register.Index == src->Register.Index)) { 11719df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned i, actual_mask = 0; 11819df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned swiz[4]; 11919df602b39ec03f61edec308ad568be118beb3acEric Anholt get_swiz(swiz, &src->Register); 12019df602b39ec03f61edec308ad568be118beb3acEric Anholt for (i = 0; i < 4; i++) 12119df602b39ec03f61edec308ad568be118beb3acEric Anholt if (src_mask & (1 << i)) 12219df602b39ec03f61edec308ad568be118beb3acEric Anholt actual_mask |= (1 << swiz[i]); 12319df602b39ec03f61edec308ad568be118beb3acEric Anholt if (actual_mask & dst_mask) 12419df602b39ec03f61edec308ad568be118beb3acEric Anholt return true; 12519df602b39ec03f61edec308ad568be118beb3acEric Anholt } 12619df602b39ec03f61edec308ad568be118beb3acEric Anholt return false; 1273141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 1283141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 1293141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 1303141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtcreate_mov(struct tgsi_transform_context *tctx, 13119df602b39ec03f61edec308ad568be118beb3acEric Anholt const struct tgsi_full_dst_register *dst, 13219df602b39ec03f61edec308ad568be118beb3acEric Anholt const struct tgsi_full_src_register *src, 13319df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned mask, unsigned saturate) 1343141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 13519df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 13619df602b39ec03f61edec308ad568be118beb3acEric Anholt 13719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 13819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 13919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Saturate = saturate; 14019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 14119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, mask); 14219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 14319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(X, Y, Z, W)); 14419df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 1453141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 1463141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 1473141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* to help calculate # of tgsi tokens for a lowering.. we assume 1483141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * the worst case, ie. removed instructions don't have ADDR[] or 1493141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * anything which increases the # of tokens per src/dst and the 1503141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * inserted instructions do. 1513141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 1523141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * OINST() - old instruction 1533141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 1 : instruction itself 1543141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 1 : dst 1553141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 1 * nargs : srcN 1563141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 1573141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * NINST() - new instruction 1583141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 1 : instruction itself 1593141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 2 : dst 1603141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 2 * nargs : srcN 1613141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 1623141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 1633141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define OINST(nargs) (1 + 1 + 1 * (nargs)) 1643141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define NINST(nargs) (1 + 2 + 2 * (nargs)) 1653141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 1663141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* 1673141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * Lowering Translators: 1683141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 1693141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 1703141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* DST - Distance Vector 1713141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.x = 1.0 1723141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.y = src0.y \times src1.y 1733141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.z = src0.z 1743141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.w = src1.w 1753141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 1763141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; note: could be more clever and use just a single temp 1773141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; if I was clever enough to re-write the swizzles. 1783141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; needs: 2 tmp, imm{1.0} 1793141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * if (dst.y aliases src0.z) { 1803141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV tmpA.yz, src0.yz 1813141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * src0 = tmpA 1823141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * } 1833141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * if (dst.yz aliases src1.w) { 1843141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV tmpB.yw, src1.yw 1853141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * src1 = tmpB 1863141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * } 1873141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MUL dst.y, src0.y, src1.y 1883141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.z, src0.z 1893141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.w, src1.w 1903141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.x, imm{1.0} 1913141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 1923141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define DST_GROW (NINST(1) + NINST(1) + NINST(2) + NINST(1) + \ 1933141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt NINST(1) + NINST(1) - OINST(2)) 1943141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define DST_TMP 2 1953141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 1963141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_dst(struct tgsi_transform_context *tctx, 19719df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 1983141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 199f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 20019df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 20119df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src0 = &inst->Src[0]; 20219df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src1 = &inst->Src[1]; 20319df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 20419df602b39ec03f61edec308ad568be118beb3acEric Anholt 20519df602b39ec03f61edec308ad568be118beb3acEric Anholt if (aliases(dst, TGSI_WRITEMASK_Y, src0, TGSI_WRITEMASK_Z)) { 20619df602b39ec03f61edec308ad568be118beb3acEric Anholt create_mov(tctx, &ctx->tmp[A].dst, src0, TGSI_WRITEMASK_YZ, 0); 20719df602b39ec03f61edec308ad568be118beb3acEric Anholt src0 = &ctx->tmp[A].src; 20819df602b39ec03f61edec308ad568be118beb3acEric Anholt } 20919df602b39ec03f61edec308ad568be118beb3acEric Anholt 21019df602b39ec03f61edec308ad568be118beb3acEric Anholt if (aliases(dst, TGSI_WRITEMASK_YZ, src1, TGSI_WRITEMASK_W)) { 21119df602b39ec03f61edec308ad568be118beb3acEric Anholt create_mov(tctx, &ctx->tmp[B].dst, src1, TGSI_WRITEMASK_YW, 0); 21219df602b39ec03f61edec308ad568be118beb3acEric Anholt src1 = &ctx->tmp[B].src; 21319df602b39ec03f61edec308ad568be118beb3acEric Anholt } 21419df602b39ec03f61edec308ad568be118beb3acEric Anholt 21519df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { 21619df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MUL dst.y, src0.y, src1.y */ 21719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 21819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; 21919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 22019df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); 22119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 22219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src0, SWIZ(_, Y, _, _)); 22319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], src1, SWIZ(_, Y, _, _)); 22419df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 22519df602b39ec03f61edec308ad568be118beb3acEric Anholt } 22619df602b39ec03f61edec308ad568be118beb3acEric Anholt 22719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_Z) { 22819df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.z, src0.z */ 22919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 23019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 23119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 23219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Z); 23319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 23419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src0, SWIZ(_, _, Z, _)); 23519df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 23619df602b39ec03f61edec308ad568be118beb3acEric Anholt } 23719df602b39ec03f61edec308ad568be118beb3acEric Anholt 23819df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { 23919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.w, src1.w */ 24019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 24119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 24219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 24319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); 24419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 24519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src1, SWIZ(_, _, _, W)); 24619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 24719df602b39ec03f61edec308ad568be118beb3acEric Anholt } 24819df602b39ec03f61edec308ad568be118beb3acEric Anholt 24919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_X) { 25019df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.x, imm{1.0} */ 25119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 25219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 25319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 25419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_X); 25519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 25619df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(Y, _, _, _)); 25719df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 25819df602b39ec03f61edec308ad568be118beb3acEric Anholt } 2593141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 2603141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 2613141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* XPD - Cross Product 2623141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.x = src0.y \times src1.z - src1.y \times src0.z 2633141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.y = src0.z \times src1.x - src1.z \times src0.x 2643141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.z = src0.x \times src1.y - src1.x \times src0.y 2653141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.w = 1.0 2663141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 26767da7dd98a6253143b80a058d7077666408a688eRussell King * ; needs: 1 tmp, imm{1.0} 26867da7dd98a6253143b80a058d7077666408a688eRussell King * MUL tmpA.xyz, src1.yzx, src0.zxy 26967da7dd98a6253143b80a058d7077666408a688eRussell King * MAD dst.xyz, src0.yzx, src1.zxy, -tmpA.xyz 2703141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.w, imm{1.0} 2713141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 27267da7dd98a6253143b80a058d7077666408a688eRussell King#define XPD_GROW (NINST(2) + NINST(3) + NINST(1) - OINST(2)) 27367da7dd98a6253143b80a058d7077666408a688eRussell King#define XPD_TMP 1 2743141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 2753141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_xpd(struct tgsi_transform_context *tctx, 27619df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 2773141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 278f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 27919df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 28019df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src0 = &inst->Src[0]; 28119df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src1 = &inst->Src[1]; 28219df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 28319df602b39ec03f61edec308ad568be118beb3acEric Anholt 28419df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZ) { 28567da7dd98a6253143b80a058d7077666408a688eRussell King /* MUL tmpA.xyz, src1.yzx, src0.zxy */ 28619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 28719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; 28819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 28919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZ); 29019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 29119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src1, SWIZ(Y, Z, X, _)); 29219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], src0, SWIZ(Z, X, Y, _)); 29319df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 29419df602b39ec03f61edec308ad568be118beb3acEric Anholt 29567da7dd98a6253143b80a058d7077666408a688eRussell King /* MAD dst.xyz, src0.yzx, src1.zxy, -tmpA.xyz */ 29619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 29767da7dd98a6253143b80a058d7077666408a688eRussell King new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; 29819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 29919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZ); 30067da7dd98a6253143b80a058d7077666408a688eRussell King new_inst.Instruction.NumSrcRegs = 3; 30167da7dd98a6253143b80a058d7077666408a688eRussell King reg_src(&new_inst.Src[0], src0, SWIZ(Y, Z, X, _)); 30267da7dd98a6253143b80a058d7077666408a688eRussell King reg_src(&new_inst.Src[1], src1, SWIZ(Z, X, Y, _)); 30367da7dd98a6253143b80a058d7077666408a688eRussell King reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X, Y, Z, _)); 30467da7dd98a6253143b80a058d7077666408a688eRussell King new_inst.Src[2].Register.Negate = true; 30519df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 30619df602b39ec03f61edec308ad568be118beb3acEric Anholt } 30719df602b39ec03f61edec308ad568be118beb3acEric Anholt 30819df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { 30919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.w, imm{1.0} */ 31019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 31119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 31219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 31319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); 31419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 31519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_, _, _, Y)); 31619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 31719df602b39ec03f61edec308ad568be118beb3acEric Anholt } 3183141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 3193141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 3203141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* SCS - Sine Cosine 3213141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.x = \cos{src.x} 3223141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.y = \sin{src.x} 3233141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.z = 0.0 3243141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.w = 1.0 3253141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 3263141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; needs: 1 tmp, imm{0.0, 1.0} 3273141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * if (dst.x aliases src.x) { 3283141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV tmpA.x, src.x 3293141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * src = tmpA 3303141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * } 3313141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * COS dst.x, src.x 3323141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * SIN dst.y, src.x 3333141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.zw, imm{0.0, 1.0} 3343141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 3353141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define SCS_GROW (NINST(1) + NINST(1) + NINST(1) + NINST(1) - OINST(1)) 3363141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define SCS_TMP 1 3373141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 3383141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_scs(struct tgsi_transform_context *tctx, 33919df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 3403141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 341f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 34219df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 34319df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src = &inst->Src[0]; 34419df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 34519df602b39ec03f61edec308ad568be118beb3acEric Anholt 34619df602b39ec03f61edec308ad568be118beb3acEric Anholt if (aliases(dst, TGSI_WRITEMASK_X, src, TGSI_WRITEMASK_X)) { 34719df602b39ec03f61edec308ad568be118beb3acEric Anholt create_mov(tctx, &ctx->tmp[A].dst, src, TGSI_WRITEMASK_X, 0); 34819df602b39ec03f61edec308ad568be118beb3acEric Anholt src = &ctx->tmp[A].src; 34919df602b39ec03f61edec308ad568be118beb3acEric Anholt } 35019df602b39ec03f61edec308ad568be118beb3acEric Anholt 35119df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_X) { 35219df602b39ec03f61edec308ad568be118beb3acEric Anholt /* COS dst.x, src.x */ 35319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 35419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_COS; 35519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 35619df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_X); 35719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 35819df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); 35919df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 36019df602b39ec03f61edec308ad568be118beb3acEric Anholt } 36119df602b39ec03f61edec308ad568be118beb3acEric Anholt 36219df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { 36319df602b39ec03f61edec308ad568be118beb3acEric Anholt /* SIN dst.y, src.x */ 36419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 36519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_SIN; 36619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 36719df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); 36819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 36919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); 37019df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 37119df602b39ec03f61edec308ad568be118beb3acEric Anholt } 37219df602b39ec03f61edec308ad568be118beb3acEric Anholt 37319df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_ZW) { 37419df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.zw, imm{0.0, 1.0} */ 37519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 37619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 37719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 37819df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_ZW); 37919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 38019df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_, _, X, Y)); 38119df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 38219df602b39ec03f61edec308ad568be118beb3acEric Anholt } 3833141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 3843141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 3853141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* LRP - Linear Interpolate 3863141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.x = src0.x \times src1.x + (1.0 - src0.x) \times src2.x 3873141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.y = src0.y \times src1.y + (1.0 - src0.y) \times src2.y 3883141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.z = src0.z \times src1.z + (1.0 - src0.z) \times src2.z 3893141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.w = src0.w \times src1.w + (1.0 - src0.w) \times src2.w 3903141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 391fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King * This becomes: src0 \times src1 + src2 - src0 \times src2, which 392fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King * can then become: src0 \times src1 - (src0 \times src2 - src2) 393fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King * 394fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King * ; needs: 1 tmp 395fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King * MAD tmpA, src0, src2, -src2 396fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King * MAD dst, src0, src1, -tmpA 3973141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 398fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King#define LRP_GROW (NINST(3) + NINST(3) - OINST(3)) 399fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King#define LRP_TMP 1 4003141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 4013141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_lrp(struct tgsi_transform_context *tctx, 40219df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 4033141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 404f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 40519df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 40619df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src0 = &inst->Src[0]; 40719df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src1 = &inst->Src[1]; 40819df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src2 = &inst->Src[2]; 40919df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 41019df602b39ec03f61edec308ad568be118beb3acEric Anholt 41119df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { 412fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King /* MAD tmpA, src0, src2, -src2 */ 41319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 414fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; 41519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 41619df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); 417fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King new_inst.Instruction.NumSrcRegs = 3; 41819df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src0, SWIZ(X, Y, Z, W)); 41919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], src2, SWIZ(X, Y, Z, W)); 420fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King reg_src(&new_inst.Src[2], src2, SWIZ(X, Y, Z, W)); 421fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King new_inst.Src[2].Register.Negate = !new_inst.Src[2].Register.Negate; 42219df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 42319df602b39ec03f61edec308ad568be118beb3acEric Anholt 424fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King /* MAD dst, src0, src1, -tmpA */ 42519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 426fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; 42719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 42819df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); 429fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King new_inst.Instruction.NumSrcRegs = 3; 430fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King reg_src(&new_inst.Src[0], src0, SWIZ(X, Y, Z, W)); 431fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King reg_src(&new_inst.Src[1], src1, SWIZ(X, Y, Z, W)); 432fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); 433fadfaa82c61a32c74531e1e1aaecfd2b3c5ac6d8Russell King new_inst.Src[2].Register.Negate = true; 43419df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 43519df602b39ec03f61edec308ad568be118beb3acEric Anholt } 4363141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 4373141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 4383141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* FRC - Fraction 4393141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.x = src.x - \lfloor src.x\rfloor 4403141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.y = src.y - \lfloor src.y\rfloor 4413141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.z = src.z - \lfloor src.z\rfloor 4423141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.w = src.w - \lfloor src.w\rfloor 4433141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 4443141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; needs: 1 tmp 4453141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * FLR tmpA, src 4463141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * SUB dst, src, tmpA 4473141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 4483141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define FRC_GROW (NINST(1) + NINST(2) - OINST(1)) 4493141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define FRC_TMP 1 4503141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 4513141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_frc(struct tgsi_transform_context *tctx, 45219df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 4533141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 454f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 45519df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 45619df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src = &inst->Src[0]; 45719df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 45819df602b39ec03f61edec308ad568be118beb3acEric Anholt 45919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { 46019df602b39ec03f61edec308ad568be118beb3acEric Anholt /* FLR tmpA, src */ 46119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 46219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; 46319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 46419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); 46519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 46619df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(X, Y, Z, W)); 46719df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 46819df602b39ec03f61edec308ad568be118beb3acEric Anholt 46919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* SUB dst, src, tmpA */ 47019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 471d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; 47219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 47319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); 47419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 47519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(X, Y, Z, W)); 47619df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); 477d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Src[1].Register.Negate = 1; 47819df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 47919df602b39ec03f61edec308ad568be118beb3acEric Anholt } 4803141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 4813141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 4823141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* POW - Power 4833141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.x = src0.x^{src1.x} 4843141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.y = src0.x^{src1.x} 4853141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.z = src0.x^{src1.x} 4863141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.w = src0.x^{src1.x} 4873141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 4883141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; needs: 1 tmp 4893141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * LG2 tmpA.x, src0.x 4903141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MUL tmpA.x, src1.x, tmpA.x 4913141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * EX2 dst, tmpA.x 4923141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 4933141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define POW_GROW (NINST(1) + NINST(2) + NINST(1) - OINST(2)) 4943141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define POW_TMP 1 4953141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 4963141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_pow(struct tgsi_transform_context *tctx, 49719df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 4983141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 499f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 50019df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 50119df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src0 = &inst->Src[0]; 50219df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src1 = &inst->Src[1]; 50319df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 50419df602b39ec03f61edec308ad568be118beb3acEric Anholt 50519df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { 50619df602b39ec03f61edec308ad568be118beb3acEric Anholt /* LG2 tmpA.x, src0.x */ 50719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 50819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_LG2; 50919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 51019df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 51119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 51219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src0, SWIZ(X, _, _, _)); 51319df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 51419df602b39ec03f61edec308ad568be118beb3acEric Anholt 51519df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MUL tmpA.x, src1.x, tmpA.x */ 51619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 51719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; 51819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 51919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 52019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 52119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src1, SWIZ(X, _, _, _)); 52219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, _, _, _)); 52319df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 52419df602b39ec03f61edec308ad568be118beb3acEric Anholt 52519df602b39ec03f61edec308ad568be118beb3acEric Anholt /* EX2 dst, tmpA.x */ 52619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 52719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; 52819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 52919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); 53019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 53119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X, _, _, _)); 53219df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 53319df602b39ec03f61edec308ad568be118beb3acEric Anholt } 5343141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 5353141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 5363141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* LIT - Light Coefficients 5373141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.x = 1.0 5383141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.y = max(src.x, 0.0) 5393141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.z = (src.x > 0.0) ? max(src.y, 0.0)^{clamp(src.w, -128.0, 128.0))} : 0 5403141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.w = 1.0 5413141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 5423141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; needs: 1 tmp, imm{0.0}, imm{1.0}, imm{128.0} 5433141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MAX tmpA.xy, src.xy, imm{0.0} 5443141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * CLAMP tmpA.z, src.w, -imm{128.0}, imm{128.0} 5453141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * LG2 tmpA.y, tmpA.y 5463141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MUL tmpA.y, tmpA.z, tmpA.y 5473141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * EX2 tmpA.y, tmpA.y 5483141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * CMP tmpA.y, -src.x, tmpA.y, imm{0.0} 5493141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.yz, tmpA.xy 5503141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.xw, imm{1.0} 5513141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 5523141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define LIT_GROW (NINST(1) + NINST(3) + NINST(1) + NINST(2) + \ 5533141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt NINST(1) + NINST(3) + NINST(1) + NINST(1) - OINST(1)) 5543141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define LIT_TMP 1 5553141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 5563141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_lit(struct tgsi_transform_context *tctx, 55719df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 5583141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 559f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 56019df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 56119df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src = &inst->Src[0]; 56219df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 56319df602b39ec03f61edec308ad568be118beb3acEric Anholt 56419df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_YZ) { 56519df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MAX tmpA.xy, src.xy, imm{0.0} */ 56619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 56719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MAX; 56819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 56919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XY); 57019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 57119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(X, Y, _, _)); 57219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->imm, SWIZ(X, X, _, _)); 57319df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 57419df602b39ec03f61edec308ad568be118beb3acEric Anholt 57519df602b39ec03f61edec308ad568be118beb3acEric Anholt /* CLAMP tmpA.z, src.w, -imm{128.0}, imm{128.0} */ 57619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 57719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_CLAMP; 57819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 57919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Z); 58019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 3; 58119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(_, _, W, _)); 58219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->imm, SWIZ(_, _, Z, _)); 58319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[1].Register.Negate = true; 58419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[2], &ctx->imm, SWIZ(_, _, Z, _)); 58519df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 58619df602b39ec03f61edec308ad568be118beb3acEric Anholt 58719df602b39ec03f61edec308ad568be118beb3acEric Anholt /* LG2 tmpA.y, tmpA.y */ 58819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 58919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_LG2; 59019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 59119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); 59219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 59319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y, _, _, _)); 59419df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 59519df602b39ec03f61edec308ad568be118beb3acEric Anholt 59619df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MUL tmpA.y, tmpA.z, tmpA.y */ 59719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 59819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; 59919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 60019df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); 60119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 60219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, Z, _, _)); 60319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_, Y, _, _)); 60419df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 60519df602b39ec03f61edec308ad568be118beb3acEric Anholt 60619df602b39ec03f61edec308ad568be118beb3acEric Anholt /* EX2 tmpA.y, tmpA.y */ 60719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 60819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; 60919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 61019df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); 61119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 61219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y, _, _, _)); 61319df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 61419df602b39ec03f61edec308ad568be118beb3acEric Anholt 61519df602b39ec03f61edec308ad568be118beb3acEric Anholt /* CMP tmpA.y, -src.x, tmpA.y, imm{0.0} */ 61619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 61719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_CMP; 61819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 61919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); 62019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 3; 62119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(_, X, _, _)); 62219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0].Register.Negate = true; 62319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_, Y, _, _)); 62419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[2], &ctx->imm, SWIZ(_, X, _, _)); 62519df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 62619df602b39ec03f61edec308ad568be118beb3acEric Anholt 62719df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.yz, tmpA.xy */ 62819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 62919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 63019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 63119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_YZ); 63219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 63319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, X, Y, _)); 63419df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 63519df602b39ec03f61edec308ad568be118beb3acEric Anholt } 63619df602b39ec03f61edec308ad568be118beb3acEric Anholt 63719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XW) { 63819df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.xw, imm{1.0} */ 63919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 64019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 64119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 64219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XW); 64319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 64419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(Y, _, _, Y)); 64519df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 64619df602b39ec03f61edec308ad568be118beb3acEric Anholt } 6473141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 6483141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 6493141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* EXP - Approximate Exponential Base 2 6503141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.x = 2^{\lfloor src.x\rfloor} 6513141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.y = src.x - \lfloor src.x\rfloor 6523141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.z = 2^{src.x} 6533141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.w = 1.0 6543141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 6553141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; needs: 1 tmp, imm{1.0} 65623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * if (lowering FLR) { 65723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * FRC tmpA.x, src.x 65823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * SUB tmpA.x, src.x, tmpA.x 65923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * } else { 66023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * FLR tmpA.x, src.x 66123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * } 6623141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * EX2 tmpA.y, src.x 6633141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * SUB dst.y, src.x, tmpA.x 6643141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * EX2 dst.x, tmpA.x 6653141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.z, tmpA.y 6663141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.w, imm{1.0} 6673141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 66823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King#define EXP_GROW (NINST(1) + NINST(2) + NINST(1) + NINST(2) + NINST(1) + \ 6693141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt NINST(1)+ NINST(1) - OINST(1)) 6703141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define EXP_TMP 1 6713141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 6723141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_exp(struct tgsi_transform_context *tctx, 67319df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 6743141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 675f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 67619df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 67719df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src = &inst->Src[0]; 67819df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 67919df602b39ec03f61edec308ad568be118beb3acEric Anholt 68019df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XY) { 68123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King if (ctx->config->lower_FLR) { 68223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King /* FRC tmpA.x, src.x */ 68323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst = tgsi_default_full_instruction(); 68423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.Opcode = TGSI_OPCODE_FRC; 68523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumDstRegs = 1; 68623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 68723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumSrcRegs = 1; 68823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); 68923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King tctx->emit_instruction(tctx, &new_inst); 69023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King 69123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King /* SUB tmpA.x, src.x, tmpA.x */ 69223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst = tgsi_default_full_instruction(); 693d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; 69423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumDstRegs = 1; 69523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 69623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumSrcRegs = 2; 69723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); 69823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, _, _, _)); 699d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Src[1].Register.Negate = 1; 70023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King tctx->emit_instruction(tctx, &new_inst); 70123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King } else { 70223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King /* FLR tmpA.x, src.x */ 70323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst = tgsi_default_full_instruction(); 70423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; 70523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumDstRegs = 1; 70623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 70723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumSrcRegs = 1; 70823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); 70923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King tctx->emit_instruction(tctx, &new_inst); 71023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King } 71119df602b39ec03f61edec308ad568be118beb3acEric Anholt } 71219df602b39ec03f61edec308ad568be118beb3acEric Anholt 71319df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_Z) { 71419df602b39ec03f61edec308ad568be118beb3acEric Anholt /* EX2 tmpA.y, src.x */ 71519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 71619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; 71719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 71819df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); 71919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 72019df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); 72119df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 72219df602b39ec03f61edec308ad568be118beb3acEric Anholt } 72319df602b39ec03f61edec308ad568be118beb3acEric Anholt 72419df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { 72519df602b39ec03f61edec308ad568be118beb3acEric Anholt /* SUB dst.y, src.x, tmpA.x */ 72619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 727d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; 72819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 72919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); 73019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 73119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(_, X, _, _)); 73219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_, X, _, _)); 733d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Src[1].Register.Negate = 1; 73419df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 73519df602b39ec03f61edec308ad568be118beb3acEric Anholt } 73619df602b39ec03f61edec308ad568be118beb3acEric Anholt 73719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_X) { 73819df602b39ec03f61edec308ad568be118beb3acEric Anholt /* EX2 dst.x, tmpA.x */ 73919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 74019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; 74119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 74219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_X); 74319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 74419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X, _, _, _)); 74519df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 74619df602b39ec03f61edec308ad568be118beb3acEric Anholt } 74719df602b39ec03f61edec308ad568be118beb3acEric Anholt 74819df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_Z) { 74919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.z, tmpA.y */ 75019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 75119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 75219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 75319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Z); 75419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 75519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, _, Y, _)); 75619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 75719df602b39ec03f61edec308ad568be118beb3acEric Anholt } 75819df602b39ec03f61edec308ad568be118beb3acEric Anholt 75919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { 76019df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.w, imm{1.0} */ 76119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 76219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 76319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 76419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); 76519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 76619df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_, _, _, Y)); 76719df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 76819df602b39ec03f61edec308ad568be118beb3acEric Anholt } 7693141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 7703141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 7713141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* LOG - Approximate Logarithm Base 2 7723141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.x = \lfloor\log_2{|src.x|}\rfloor 7733141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.y = \frac{|src.x|}{2^{\lfloor\log_2{|src.x|}\rfloor}} 7743141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.z = \log_2{|src.x|} 7753141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst.w = 1.0 7763141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 7773141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; needs: 1 tmp, imm{1.0} 7783141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * LG2 tmpA.x, |src.x| 77923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * if (lowering FLR) { 78023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * FRC tmpA.y, tmpA.x 78123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * SUB tmpA.y, tmpA.x, tmpA.y 78223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * } else { 78323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * FLR tmpA.y, tmpA.x 78423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * } 7853141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * EX2 tmpA.z, tmpA.y 7863141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * RCP tmpA.z, tmpA.z 7873141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MUL dst.y, |src.x|, tmpA.z 7883141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.xz, tmpA.yx 7893141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV dst.w, imm{1.0} 7903141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 79123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King#define LOG_GROW (NINST(1) + NINST(1) + NINST(2) + NINST(1) + NINST(1) + \ 7923141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt NINST(2) + NINST(1) + NINST(1) - OINST(1)) 7933141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define LOG_TMP 1 7943141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 7953141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_log(struct tgsi_transform_context *tctx, 79619df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 7973141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 798f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 79919df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 80019df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src = &inst->Src[0]; 80119df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 80219df602b39ec03f61edec308ad568be118beb3acEric Anholt 80319df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZ) { 80419df602b39ec03f61edec308ad568be118beb3acEric Anholt /* LG2 tmpA.x, |src.x| */ 80519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 80619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_LG2; 80719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 80819df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 80919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 81019df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(X, _, _, _)); 81119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0].Register.Absolute = true; 81219df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 81319df602b39ec03f61edec308ad568be118beb3acEric Anholt } 81419df602b39ec03f61edec308ad568be118beb3acEric Anholt 81519df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XY) { 81623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King if (ctx->config->lower_FLR) { 81723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King /* FRC tmpA.y, tmpA.x */ 81823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst = tgsi_default_full_instruction(); 81923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.Opcode = TGSI_OPCODE_FRC; 82023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumDstRegs = 1; 82123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); 82223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumSrcRegs = 1; 82323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, X, _, _)); 82423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King tctx->emit_instruction(tctx, &new_inst); 82523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King 82623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King /* SUB tmpA.y, tmpA.x, tmpA.y */ 82723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst = tgsi_default_full_instruction(); 828d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; 82923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumDstRegs = 1; 83023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); 83123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumSrcRegs = 2; 83223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, X, _, _)); 83323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_, Y, _, _)); 834d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Src[1].Register.Negate = 1; 83523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King tctx->emit_instruction(tctx, &new_inst); 83623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King } else { 83723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King /* FLR tmpA.y, tmpA.x */ 83823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst = tgsi_default_full_instruction(); 83923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; 84023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumDstRegs = 1; 84123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Y); 84223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumSrcRegs = 1; 84323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(_, X, _, _)); 84423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King tctx->emit_instruction(tctx, &new_inst); 84523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King } 84619df602b39ec03f61edec308ad568be118beb3acEric Anholt } 84719df602b39ec03f61edec308ad568be118beb3acEric Anholt 84819df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_Y) { 84919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* EX2 tmpA.z, tmpA.y */ 85019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 85119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_EX2; 85219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 85319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Z); 85419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 85519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y, _, _, _)); 85619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 85719df602b39ec03f61edec308ad568be118beb3acEric Anholt 85819df602b39ec03f61edec308ad568be118beb3acEric Anholt /* RCP tmpA.z, tmpA.z */ 85919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 86019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_RCP; 86119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 86219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_Z); 86319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 86419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Z, _, _, _)); 86519df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 86619df602b39ec03f61edec308ad568be118beb3acEric Anholt 86719df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MUL dst.y, |src.x|, tmpA.z */ 86819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 86919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; 87019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 87119df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_Y); 87219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 87319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src, SWIZ(_, X, _, _)); 87419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0].Register.Absolute = true; 87519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(_, Z, _, _)); 87619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 87719df602b39ec03f61edec308ad568be118beb3acEric Anholt } 87819df602b39ec03f61edec308ad568be118beb3acEric Anholt 87919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XZ) { 88019df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.xz, tmpA.yx */ 88119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 88219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 88319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 88419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XZ); 88519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 88619df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(Y, _, X, _)); 88719df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 88819df602b39ec03f61edec308ad568be118beb3acEric Anholt } 88919df602b39ec03f61edec308ad568be118beb3acEric Anholt 89019df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_W) { 89119df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV dst.w, imm{1.0} */ 89219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 89319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 89419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 89519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_W); 89619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 89719df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->imm, SWIZ(_, _, _, Y)); 89819df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 89919df602b39ec03f61edec308ad568be118beb3acEric Anholt } 9003141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 9013141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 9023141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* DP4 - 4-component Dot Product 9033141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w 9043141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 9053141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * DP3 - 3-component Dot Product 9063141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z 9073141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 9083141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * DPH - Homogeneous Dot Product 9093141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w 9103141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 9113141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * DP2 - 2-component Dot Product 9123141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst = src0.x \times src1.x + src0.y \times src1.y 9133141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 9143141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * DP2A - 2-component Dot Product And Add 9153141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * dst = src0.x \times src1.x + src0.y \times src1.y + src2.x 9163141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 9173141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * NOTE: these are translated into sequence of MUL/MAD(/ADD) scalar 9183141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * operations, which is what you'd prefer for a ISA that is natively 9193141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * scalar. Probably a native vector ISA would at least already have 9203141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * DP4/DP3 instructions, but perhaps there is room for an alternative 9213141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * translation for DPH/DP2/DP2A using vector instructions. 9223141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 9233141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; needs: 1 tmp 9243141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MUL tmpA.x, src0.x, src1.x 9253141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MAD tmpA.x, src0.y, src1.y, tmpA.x 9263141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * if (DPH || DP3 || DP4) { 9273141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MAD tmpA.x, src0.z, src1.z, tmpA.x 9283141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * if (DPH) { 9293141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ADD tmpA.x, src1.w, tmpA.x 9303141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * } else if (DP4) { 9313141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MAD tmpA.x, src0.w, src1.w, tmpA.x 9323141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * } 9333141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * } else if (DP2A) { 9343141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ADD tmpA.x, src2.x, tmpA.x 9353141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * } 9363141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; fixup last instruction to replicate into dst 9373141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 9383141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define DP4_GROW (NINST(2) + NINST(3) + NINST(3) + NINST(3) - OINST(2)) 9393141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define DP3_GROW (NINST(2) + NINST(3) + NINST(3) - OINST(2)) 9403141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define DPH_GROW (NINST(2) + NINST(3) + NINST(3) + NINST(2) - OINST(2)) 9413141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define DP2_GROW (NINST(2) + NINST(3) - OINST(2)) 9423141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define DP2A_GROW (NINST(2) + NINST(3) + NINST(2) - OINST(3)) 9433141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define DOTP_TMP 1 9443141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 9453141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_dotp(struct tgsi_transform_context *tctx, 94619df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 9473141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 948f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 94919df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_dst_register *dst = &inst->Dst[0]; 95019df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src0 = &inst->Src[0]; 95119df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src1 = &inst->Src[1]; 95219df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *src2 = &inst->Src[2]; /* only DP2A */ 95319df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 95419df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned opcode = inst->Instruction.Opcode; 95519df602b39ec03f61edec308ad568be118beb3acEric Anholt 95619df602b39ec03f61edec308ad568be118beb3acEric Anholt /* NOTE: any potential last instruction must replicate src on all 95719df602b39ec03f61edec308ad568be118beb3acEric Anholt * components (since it could be re-written to write to final dst) 95819df602b39ec03f61edec308ad568be118beb3acEric Anholt */ 95919df602b39ec03f61edec308ad568be118beb3acEric Anholt 96019df602b39ec03f61edec308ad568be118beb3acEric Anholt if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { 96119df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MUL tmpA.x, src0.x, src1.x */ 96219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 96319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; 96419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 96519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 96619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 96719df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src0, SWIZ(X, _, _, _)); 96819df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], src1, SWIZ(X, _, _, _)); 96919df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 97019df602b39ec03f61edec308ad568be118beb3acEric Anholt 97119df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MAD tmpA.x, src0.y, src1.y, tmpA.x */ 97219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 97319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; 97419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 97519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 97619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 3; 97719df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src0, SWIZ(Y, Y, Y, Y)); 97819df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], src1, SWIZ(Y, Y, Y, Y)); 97919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X, X, X, X)); 98019df602b39ec03f61edec308ad568be118beb3acEric Anholt 98119df602b39ec03f61edec308ad568be118beb3acEric Anholt if ((opcode == TGSI_OPCODE_DPH) || 98219df602b39ec03f61edec308ad568be118beb3acEric Anholt (opcode == TGSI_OPCODE_DP3) || 98319df602b39ec03f61edec308ad568be118beb3acEric Anholt (opcode == TGSI_OPCODE_DP4)) { 98419df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 98519df602b39ec03f61edec308ad568be118beb3acEric Anholt 98619df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MAD tmpA.x, src0.z, src1.z, tmpA.x */ 98719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 98819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; 98919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 99019df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 99119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 3; 99219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src0, SWIZ(Z, Z, Z, Z)); 99319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], src1, SWIZ(Z, Z, Z, Z)); 99419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X, X, X, X)); 99519df602b39ec03f61edec308ad568be118beb3acEric Anholt 99619df602b39ec03f61edec308ad568be118beb3acEric Anholt if (opcode == TGSI_OPCODE_DPH) { 99719df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 99819df602b39ec03f61edec308ad568be118beb3acEric Anholt 99919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* ADD tmpA.x, src1.w, tmpA.x */ 100019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 100119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; 100219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 100319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 100419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 100519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src1, SWIZ(W, W, W, W)); 100619df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, X, X, X)); 100719df602b39ec03f61edec308ad568be118beb3acEric Anholt } else if (opcode == TGSI_OPCODE_DP4) { 100819df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 100919df602b39ec03f61edec308ad568be118beb3acEric Anholt 101019df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MAD tmpA.x, src0.w, src1.w, tmpA.x */ 101119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 101219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MAD; 101319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 101419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 101519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 3; 101619df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src0, SWIZ(W, W, W, W)); 101719df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], src1, SWIZ(W, W, W, W)); 101819df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X, X, X, X)); 101919df602b39ec03f61edec308ad568be118beb3acEric Anholt } 102019df602b39ec03f61edec308ad568be118beb3acEric Anholt } else if (opcode == TGSI_OPCODE_DP2A) { 102119df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 102219df602b39ec03f61edec308ad568be118beb3acEric Anholt 102319df602b39ec03f61edec308ad568be118beb3acEric Anholt /* ADD tmpA.x, src2.x, tmpA.x */ 102419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 102519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; 102619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 102719df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_X); 102819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 102919df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], src2, SWIZ(X, X, X, X)); 103019df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, X, X, X)); 103119df602b39ec03f61edec308ad568be118beb3acEric Anholt } 103219df602b39ec03f61edec308ad568be118beb3acEric Anholt 103319df602b39ec03f61edec308ad568be118beb3acEric Anholt /* fixup last instruction to write to dst: */ 103419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); 103519df602b39ec03f61edec308ad568be118beb3acEric Anholt 103619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 103719df602b39ec03f61edec308ad568be118beb3acEric Anholt } 10383141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 10393141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 104023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King/* FLR - floor, CEIL - ceil 104123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * ; needs: 1 tmp 104223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * if (CEIL) { 104323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * FRC tmpA, -src 104423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * ADD dst, src, tmpA 104523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * } else { 104623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * FRC tmpA, src 104723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * SUB dst, src, tmpA 104823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King * } 104923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King */ 105023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King#define FLR_GROW (NINST(1) + NINST(2) - OINST(1)) 105123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King#define CEIL_GROW (NINST(1) + NINST(2) - OINST(1)) 105223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King#define FLR_TMP 1 105323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King#define CEIL_TMP 1 105423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell Kingstatic void 105523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell Kingtransform_flr_ceil(struct tgsi_transform_context *tctx, 105623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King struct tgsi_full_instruction *inst) 105723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King{ 105823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 105923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King struct tgsi_full_dst_register *dst = &inst->Dst[0]; 106023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King struct tgsi_full_src_register *src0 = &inst->Src[0]; 106123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King struct tgsi_full_instruction new_inst; 106223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King unsigned opcode = inst->Instruction.Opcode; 106323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King 106423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { 106523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King /* FLR: FRC tmpA, src CEIL: FRC tmpA, -src */ 106623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst = tgsi_default_full_instruction(); 106723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.Opcode = TGSI_OPCODE_FRC; 106823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumDstRegs = 1; 106923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); 107023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumSrcRegs = 1; 107123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[0], src0, SWIZ(X, Y, Z, W)); 107223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King 107323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King if (opcode == TGSI_OPCODE_CEIL) 107423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Src[0].Register.Negate = !new_inst.Src[0].Register.Negate; 107523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King tctx->emit_instruction(tctx, &new_inst); 107623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King 107723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King /* FLR: SUB dst, src, tmpA CEIL: ADD dst, src, tmpA */ 107823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst = tgsi_default_full_instruction(); 1079d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; 108023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumDstRegs = 1; 108123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); 108223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King new_inst.Instruction.NumSrcRegs = 2; 108323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[0], src0, SWIZ(X, Y, Z, W)); 108423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); 1085d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák if (opcode == TGSI_OPCODE_FLR) 1086d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Src[1].Register.Negate = 1; 108723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King tctx->emit_instruction(tctx, &new_inst); 108823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King } 108923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King} 109023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King 109165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King/* TRUNC - truncate off fractional part 109265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * dst.x = trunc(src.x) 109365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * dst.y = trunc(src.y) 109465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * dst.z = trunc(src.z) 109565460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * dst.w = trunc(src.w) 109665460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * 109765460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * ; needs: 1 tmp 109865460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * if (lower FLR) { 109965460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * FRC tmpA, |src| 110065460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * SUB tmpA, |src|, tmpA 110165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * } else { 110265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * FLR tmpA, |src| 110365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * } 110465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King * CMP dst, src, -tmpA, tmpA 110565460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King */ 110665460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King#define TRUNC_GROW (NINST(1) + NINST(2) + NINST(3) - OINST(1)) 110765460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King#define TRUNC_TMP 1 110865460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell Kingstatic void 110965460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell Kingtransform_trunc(struct tgsi_transform_context *tctx, 111065460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King struct tgsi_full_instruction *inst) 111165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King{ 111265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 111365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King struct tgsi_full_dst_register *dst = &inst->Dst[0]; 111465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King struct tgsi_full_src_register *src0 = &inst->Src[0]; 111565460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King struct tgsi_full_instruction new_inst; 111665460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King 111765460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) { 111865460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King if (ctx->config->lower_FLR) { 111965460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst = tgsi_default_full_instruction(); 112065460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.Opcode = TGSI_OPCODE_FRC; 112165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.NumDstRegs = 1; 112265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); 112365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.NumSrcRegs = 1; 112465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_src(&new_inst.Src[0], src0, SWIZ(X, Y, Z, W)); 112565460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Src[0].Register.Absolute = true; 112665460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Src[0].Register.Negate = false; 112765460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King tctx->emit_instruction(tctx, &new_inst); 112865460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King 112965460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst = tgsi_default_full_instruction(); 1130d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Instruction.Opcode = TGSI_OPCODE_ADD; 113165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.NumDstRegs = 1; 113265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); 113365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.NumSrcRegs = 2; 113465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_src(&new_inst.Src[0], src0, SWIZ(X, Y, Z, W)); 113565460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Src[0].Register.Absolute = true; 113665460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Src[0].Register.Negate = false; 113765460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); 1138d995115b1733ec14182e6bb4653b8f8389b87518Marek Olšák new_inst.Src[1].Register.Negate = 1; 113965460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King tctx->emit_instruction(tctx, &new_inst); 114065460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King } else { 114165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst = tgsi_default_full_instruction(); 114265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.Opcode = TGSI_OPCODE_FLR; 114365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.NumDstRegs = 1; 114465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW); 114565460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.NumSrcRegs = 1; 114665460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_src(&new_inst.Src[0], src0, SWIZ(X, Y, Z, W)); 114765460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Src[0].Register.Absolute = true; 114865460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Src[0].Register.Negate = false; 114965460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King tctx->emit_instruction(tctx, &new_inst); 115065460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King } 115165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King 115265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst = tgsi_default_full_instruction(); 115365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.Opcode = TGSI_OPCODE_CMP; 115465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.NumDstRegs = 1; 115565460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW); 115665460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Instruction.NumSrcRegs = 3; 115765460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_src(&new_inst.Src[0], src0, SWIZ(X, Y, Z, W)); 115865460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); 115965460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King new_inst.Src[1].Register.Negate = true; 116065460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King reg_src(&new_inst.Src[2], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); 116165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King tctx->emit_instruction(tctx, &new_inst); 116265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King } 116365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King} 116465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King 11653141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* Inserts a MOV_SAT for the needed components of tex coord. Note that 11663141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * in the case of TXP, the clamping must happen *after* projection, so 11673141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * we need to lower TXP to TEX. 11683141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * 11693141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV tmpA, src0 11703141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * if (opc == TXP) { 11713141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * ; do perspective division manually before clamping: 11723141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * RCP tmpB, tmpA.w 11733141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MUL tmpB.<pmask>, tmpA, tmpB.xxxx 11743141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * opc = TEX; 11753141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * } 11763141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * MOV_SAT tmpA.<mask>, tmpA ; <mask> is the clamped s/t/r coords 11773141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * <opc> dst, tmpA, ... 11783141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 11793141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define SAMP_GROW (NINST(1) + NINST(1) + NINST(2) + NINST(1)) 11803141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define SAMP_TMP 2 11813141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic int 11823141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_samp(struct tgsi_transform_context *tctx, 118319df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 11843141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 1185f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 118619df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *coord = &inst->Src[0]; 118719df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_src_register *samp; 118819df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 118919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* mask is clamped coords, pmask is all coords (for projection): */ 119019df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned mask = 0, pmask = 0, smask; 1191219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark unsigned tex = inst->Texture.Texture; 119219df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned opcode = inst->Instruction.Opcode; 1193219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark bool lower_txp = (opcode == TGSI_OPCODE_TXP) && 1194219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark (ctx->config->lower_TXP & (1 << tex)); 119519df602b39ec03f61edec308ad568be118beb3acEric Anholt 119619df602b39ec03f61edec308ad568be118beb3acEric Anholt if (opcode == TGSI_OPCODE_TXB2) { 119719df602b39ec03f61edec308ad568be118beb3acEric Anholt samp = &inst->Src[2]; 119819df602b39ec03f61edec308ad568be118beb3acEric Anholt } else { 119919df602b39ec03f61edec308ad568be118beb3acEric Anholt samp = &inst->Src[1]; 120019df602b39ec03f61edec308ad568be118beb3acEric Anholt } 120119df602b39ec03f61edec308ad568be118beb3acEric Anholt 120219df602b39ec03f61edec308ad568be118beb3acEric Anholt /* convert sampler # to bitmask to test: */ 120319df602b39ec03f61edec308ad568be118beb3acEric Anholt smask = 1 << samp->Register.Index; 120419df602b39ec03f61edec308ad568be118beb3acEric Anholt 120519df602b39ec03f61edec308ad568be118beb3acEric Anholt /* check if we actually need to lower this one: */ 1206219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark if (!(ctx->saturate & smask) && !lower_txp) 120719df602b39ec03f61edec308ad568be118beb3acEric Anholt return -1; 120819df602b39ec03f61edec308ad568be118beb3acEric Anholt 120919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* figure out which coordinates need saturating: 121019df602b39ec03f61edec308ad568be118beb3acEric Anholt * - RECT textures should not get saturated 121119df602b39ec03f61edec308ad568be118beb3acEric Anholt * - array index coords should not get saturated 121219df602b39ec03f61edec308ad568be118beb3acEric Anholt */ 1213219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark switch (tex) { 121419df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_3D: 121519df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_CUBE: 121619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_CUBE_ARRAY: 121719df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_SHADOWCUBE: 121819df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 121919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (ctx->config->saturate_r & smask) 122019df602b39ec03f61edec308ad568be118beb3acEric Anholt mask |= TGSI_WRITEMASK_Z; 122119df602b39ec03f61edec308ad568be118beb3acEric Anholt pmask |= TGSI_WRITEMASK_Z; 122219df602b39ec03f61edec308ad568be118beb3acEric Anholt /* fallthrough */ 122319df602b39ec03f61edec308ad568be118beb3acEric Anholt 122419df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_2D: 122519df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_2D_ARRAY: 122619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_SHADOW2D: 122719df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_SHADOW2D_ARRAY: 122819df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_2D_MSAA: 122919df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_2D_ARRAY_MSAA: 123019df602b39ec03f61edec308ad568be118beb3acEric Anholt if (ctx->config->saturate_t & smask) 123119df602b39ec03f61edec308ad568be118beb3acEric Anholt mask |= TGSI_WRITEMASK_Y; 123219df602b39ec03f61edec308ad568be118beb3acEric Anholt pmask |= TGSI_WRITEMASK_Y; 123319df602b39ec03f61edec308ad568be118beb3acEric Anholt /* fallthrough */ 123419df602b39ec03f61edec308ad568be118beb3acEric Anholt 123519df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_1D: 123619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_1D_ARRAY: 123719df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_SHADOW1D: 123819df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_TEXTURE_SHADOW1D_ARRAY: 123919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (ctx->config->saturate_s & smask) 124019df602b39ec03f61edec308ad568be118beb3acEric Anholt mask |= TGSI_WRITEMASK_X; 124119df602b39ec03f61edec308ad568be118beb3acEric Anholt pmask |= TGSI_WRITEMASK_X; 124219df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 124319df602b39ec03f61edec308ad568be118beb3acEric Anholt 1244219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark case TGSI_TEXTURE_RECT: 1245219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark case TGSI_TEXTURE_SHADOWRECT: 1246219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark /* we don't saturate, but in case of lower_txp we 1247219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark * still need to do the perspective divide: 1248219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark */ 1249219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark pmask = TGSI_WRITEMASK_XY; 1250219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark break; 125119df602b39ec03f61edec308ad568be118beb3acEric Anholt } 125219df602b39ec03f61edec308ad568be118beb3acEric Anholt 125319df602b39ec03f61edec308ad568be118beb3acEric Anholt /* sanity check.. driver could be asking to saturate a non- 125419df602b39ec03f61edec308ad568be118beb3acEric Anholt * existent coordinate component: 125519df602b39ec03f61edec308ad568be118beb3acEric Anholt */ 1256219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark if (!mask && !lower_txp) 125719df602b39ec03f61edec308ad568be118beb3acEric Anholt return -1; 125819df602b39ec03f61edec308ad568be118beb3acEric Anholt 125919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV tmpA, src0 */ 126019df602b39ec03f61edec308ad568be118beb3acEric Anholt create_mov(tctx, &ctx->tmp[A].dst, coord, TGSI_WRITEMASK_XYZW, 0); 126119df602b39ec03f61edec308ad568be118beb3acEric Anholt 126219df602b39ec03f61edec308ad568be118beb3acEric Anholt /* This is a bit sad.. we need to clamp *after* the coords 126319df602b39ec03f61edec308ad568be118beb3acEric Anholt * are projected, which means lowering TXP to TEX and doing 126419df602b39ec03f61edec308ad568be118beb3acEric Anholt * the projection ourself. But since I haven't figured out 126519df602b39ec03f61edec308ad568be118beb3acEric Anholt * how to make the lowering code deliver an electric shock 126619df602b39ec03f61edec308ad568be118beb3acEric Anholt * to anyone using GL_CLAMP, we must do this instead: 126719df602b39ec03f61edec308ad568be118beb3acEric Anholt */ 126819df602b39ec03f61edec308ad568be118beb3acEric Anholt if (opcode == TGSI_OPCODE_TXP) { 126919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* RCP tmpB.x tmpA.w */ 127019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 127119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_RCP; 127219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 127319df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_X); 127419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 1; 127519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(W, _, _, _)); 127619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 127719df602b39ec03f61edec308ad568be118beb3acEric Anholt 127819df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MUL tmpA.mask, tmpA, tmpB.xxxx */ 127919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 128019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_MUL; 128119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 128219df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, pmask); 128319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 2; 128419df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X, Y, Z, W)); 128519df602b39ec03f61edec308ad568be118beb3acEric Anholt reg_src(&new_inst.Src[1], &ctx->tmp[B].src, SWIZ(X, X, X, X)); 128619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 128719df602b39ec03f61edec308ad568be118beb3acEric Anholt 128819df602b39ec03f61edec308ad568be118beb3acEric Anholt opcode = TGSI_OPCODE_TEX; 128919df602b39ec03f61edec308ad568be118beb3acEric Anholt } 129019df602b39ec03f61edec308ad568be118beb3acEric Anholt 129119df602b39ec03f61edec308ad568be118beb3acEric Anholt /* MOV_SAT tmpA.<mask>, tmpA */ 1292219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark if (mask) { 1293e1c4e8aaaafddd0e04cf2a16e28ef8f1e09d8b44Marek Olšák create_mov(tctx, &ctx->tmp[A].dst, &ctx->tmp[A].src, mask, 1); 1294219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark } 129519df602b39ec03f61edec308ad568be118beb3acEric Anholt 129619df602b39ec03f61edec308ad568be118beb3acEric Anholt /* modify the texture samp instruction to take fixed up coord: */ 129719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = *inst; 129819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = opcode; 129919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0] = ctx->tmp[A].src; 130019df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 130119df602b39ec03f61edec308ad568be118beb3acEric Anholt 130219df602b39ec03f61edec308ad568be118beb3acEric Anholt return 0; 13033141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 13043141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 13053141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* Two-sided color emulation: 13063141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * For each COLOR input, create a corresponding BCOLOR input, plus 13073141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * CMP instruction to select front or back color based on FACE 13083141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 130919df602b39ec03f61edec308ad568be118beb3acEric Anholt#define TWOSIDE_GROW(n) ( \ 131019df602b39ec03f61edec308ad568be118beb3acEric Anholt 2 + /* FACE */ \ 13114abb789bca95e9c23b2339ea7732833203c94639Rob Clark ((n) * 3) + /* IN[], BCOLOR[n], <intrp> */\ 131219df602b39ec03f61edec308ad568be118beb3acEric Anholt ((n) * 1) + /* TEMP[] */ \ 131319df602b39ec03f61edec308ad568be118beb3acEric Anholt ((n) * NINST(3)) /* CMP instr */ \ 131419df602b39ec03f61edec308ad568be118beb3acEric Anholt ) 13153141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 13163141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 13173141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtemit_twoside(struct tgsi_transform_context *tctx) 13183141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 1319f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 132019df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_shader_info *info = ctx->info; 132119df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_declaration decl; 132219df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction new_inst; 132319df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned inbase, tmpbase; 132419df602b39ec03f61edec308ad568be118beb3acEric Anholt int i; 132519df602b39ec03f61edec308ad568be118beb3acEric Anholt 132619df602b39ec03f61edec308ad568be118beb3acEric Anholt inbase = info->file_max[TGSI_FILE_INPUT] + 1; 132719df602b39ec03f61edec308ad568be118beb3acEric Anholt tmpbase = info->file_max[TGSI_FILE_TEMPORARY] + 1; 132819df602b39ec03f61edec308ad568be118beb3acEric Anholt 132919df602b39ec03f61edec308ad568be118beb3acEric Anholt /* additional inputs for BCOLOR's */ 133019df602b39ec03f61edec308ad568be118beb3acEric Anholt for (i = 0; i < ctx->two_side_colors; i++) { 13314abb789bca95e9c23b2339ea7732833203c94639Rob Clark unsigned in_idx = ctx->two_side_idx[i]; 133219df602b39ec03f61edec308ad568be118beb3acEric Anholt decl = tgsi_default_full_declaration(); 133319df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Declaration.File = TGSI_FILE_INPUT; 133419df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Declaration.Semantic = true; 133519df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Range.First = decl.Range.Last = inbase + i; 133619df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Semantic.Name = TGSI_SEMANTIC_BCOLOR; 13374abb789bca95e9c23b2339ea7732833203c94639Rob Clark decl.Semantic.Index = info->input_semantic_index[in_idx]; 13384abb789bca95e9c23b2339ea7732833203c94639Rob Clark decl.Declaration.Interpolate = true; 13394abb789bca95e9c23b2339ea7732833203c94639Rob Clark decl.Interp.Interpolate = info->input_interpolate[in_idx]; 13404abb789bca95e9c23b2339ea7732833203c94639Rob Clark decl.Interp.Location = info->input_interpolate_loc[in_idx]; 13414abb789bca95e9c23b2339ea7732833203c94639Rob Clark decl.Interp.CylindricalWrap = info->input_cylindrical_wrap[in_idx]; 134219df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_declaration(tctx, &decl); 134319df602b39ec03f61edec308ad568be118beb3acEric Anholt } 134419df602b39ec03f61edec308ad568be118beb3acEric Anholt 134519df602b39ec03f61edec308ad568be118beb3acEric Anholt /* additional input for FACE */ 134619df602b39ec03f61edec308ad568be118beb3acEric Anholt if (ctx->two_side_colors && (ctx->face_idx == -1)) { 134719df602b39ec03f61edec308ad568be118beb3acEric Anholt decl = tgsi_default_full_declaration(); 134819df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Declaration.File = TGSI_FILE_INPUT; 134919df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Declaration.Semantic = true; 135019df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Range.First = decl.Range.Last = inbase + ctx->two_side_colors; 135119df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Semantic.Name = TGSI_SEMANTIC_FACE; 135219df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Semantic.Index = 0; 135319df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_declaration(tctx, &decl); 135419df602b39ec03f61edec308ad568be118beb3acEric Anholt 135519df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->face_idx = decl.Range.First; 135619df602b39ec03f61edec308ad568be118beb3acEric Anholt } 135719df602b39ec03f61edec308ad568be118beb3acEric Anholt 135819df602b39ec03f61edec308ad568be118beb3acEric Anholt /* additional temps for COLOR/BCOLOR selection: */ 135919df602b39ec03f61edec308ad568be118beb3acEric Anholt for (i = 0; i < ctx->two_side_colors; i++) { 136019df602b39ec03f61edec308ad568be118beb3acEric Anholt decl = tgsi_default_full_declaration(); 136119df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Declaration.File = TGSI_FILE_TEMPORARY; 136219df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Range.First = decl.Range.Last = tmpbase + ctx->numtmp + i; 136319df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_declaration(tctx, &decl); 136419df602b39ec03f61edec308ad568be118beb3acEric Anholt } 136519df602b39ec03f61edec308ad568be118beb3acEric Anholt 136619df602b39ec03f61edec308ad568be118beb3acEric Anholt /* and finally additional instructions to select COLOR/BCOLOR: */ 136719df602b39ec03f61edec308ad568be118beb3acEric Anholt for (i = 0; i < ctx->two_side_colors; i++) { 136819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst = tgsi_default_full_instruction(); 136919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.Opcode = TGSI_OPCODE_CMP; 137019df602b39ec03f61edec308ad568be118beb3acEric Anholt 137119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumDstRegs = 1; 137219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; 137319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Dst[0].Register.Index = tmpbase + ctx->numtmp + i; 137419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW; 137519df602b39ec03f61edec308ad568be118beb3acEric Anholt 137619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Instruction.NumSrcRegs = 3; 137719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0].Register.File = TGSI_FILE_INPUT; 137819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0].Register.Index = ctx->face_idx; 137919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X; 138019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X; 138119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X; 138219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_X; 138319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[1].Register.File = TGSI_FILE_INPUT; 138419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[1].Register.Index = inbase + i; 138519df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[1].Register.SwizzleX = TGSI_SWIZZLE_X; 138619df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_Y; 138719df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[1].Register.SwizzleZ = TGSI_SWIZZLE_Z; 138819df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[1].Register.SwizzleW = TGSI_SWIZZLE_W; 138919df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[2].Register.File = TGSI_FILE_INPUT; 139019df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[2].Register.Index = ctx->two_side_idx[i]; 139119df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[2].Register.SwizzleX = TGSI_SWIZZLE_X; 139219df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[2].Register.SwizzleY = TGSI_SWIZZLE_Y; 139319df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[2].Register.SwizzleZ = TGSI_SWIZZLE_Z; 139419df602b39ec03f61edec308ad568be118beb3acEric Anholt new_inst.Src[2].Register.SwizzleW = TGSI_SWIZZLE_W; 139519df602b39ec03f61edec308ad568be118beb3acEric Anholt 139619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, &new_inst); 139719df602b39ec03f61edec308ad568be118beb3acEric Anholt } 13983141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 13993141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 14003141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 14013141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtemit_decls(struct tgsi_transform_context *tctx) 14023141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 1403f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 140419df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_shader_info *info = ctx->info; 140519df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_declaration decl; 140619df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_immediate immed; 140719df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned tmpbase; 140819df602b39ec03f61edec308ad568be118beb3acEric Anholt int i; 140919df602b39ec03f61edec308ad568be118beb3acEric Anholt 141019df602b39ec03f61edec308ad568be118beb3acEric Anholt tmpbase = info->file_max[TGSI_FILE_TEMPORARY] + 1; 141119df602b39ec03f61edec308ad568be118beb3acEric Anholt 141219df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->color_base = tmpbase + ctx->numtmp; 141319df602b39ec03f61edec308ad568be118beb3acEric Anholt 141419df602b39ec03f61edec308ad568be118beb3acEric Anholt /* declare immediate: */ 141519df602b39ec03f61edec308ad568be118beb3acEric Anholt immed = tgsi_default_full_immediate(); 141619df602b39ec03f61edec308ad568be118beb3acEric Anholt immed.Immediate.NrTokens = 1 + 4; /* one for the token itself */ 141719df602b39ec03f61edec308ad568be118beb3acEric Anholt immed.u[0].Float = 0.0; 141819df602b39ec03f61edec308ad568be118beb3acEric Anholt immed.u[1].Float = 1.0; 141919df602b39ec03f61edec308ad568be118beb3acEric Anholt immed.u[2].Float = 128.0; 142019df602b39ec03f61edec308ad568be118beb3acEric Anholt immed.u[3].Float = 0.0; 142119df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_immediate(tctx, &immed); 142219df602b39ec03f61edec308ad568be118beb3acEric Anholt 142319df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->imm.Register.File = TGSI_FILE_IMMEDIATE; 142419df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->imm.Register.Index = info->immediate_count; 142519df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->imm.Register.SwizzleX = TGSI_SWIZZLE_X; 142619df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->imm.Register.SwizzleY = TGSI_SWIZZLE_Y; 142719df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->imm.Register.SwizzleZ = TGSI_SWIZZLE_Z; 142819df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->imm.Register.SwizzleW = TGSI_SWIZZLE_W; 142919df602b39ec03f61edec308ad568be118beb3acEric Anholt 143019df602b39ec03f61edec308ad568be118beb3acEric Anholt /* declare temp regs: */ 143119df602b39ec03f61edec308ad568be118beb3acEric Anholt for (i = 0; i < ctx->numtmp; i++) { 143219df602b39ec03f61edec308ad568be118beb3acEric Anholt decl = tgsi_default_full_declaration(); 143319df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Declaration.File = TGSI_FILE_TEMPORARY; 143419df602b39ec03f61edec308ad568be118beb3acEric Anholt decl.Range.First = decl.Range.Last = tmpbase + i; 143519df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_declaration(tctx, &decl); 143619df602b39ec03f61edec308ad568be118beb3acEric Anholt 143719df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->tmp[i].src.Register.File = TGSI_FILE_TEMPORARY; 143819df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->tmp[i].src.Register.Index = tmpbase + i; 143919df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->tmp[i].src.Register.SwizzleX = TGSI_SWIZZLE_X; 144019df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->tmp[i].src.Register.SwizzleY = TGSI_SWIZZLE_Y; 144119df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->tmp[i].src.Register.SwizzleZ = TGSI_SWIZZLE_Z; 144219df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->tmp[i].src.Register.SwizzleW = TGSI_SWIZZLE_W; 144319df602b39ec03f61edec308ad568be118beb3acEric Anholt 144419df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->tmp[i].dst.Register.File = TGSI_FILE_TEMPORARY; 144519df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->tmp[i].dst.Register.Index = tmpbase + i; 144619df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->tmp[i].dst.Register.WriteMask = TGSI_WRITEMASK_XYZW; 144719df602b39ec03f61edec308ad568be118beb3acEric Anholt } 144819df602b39ec03f61edec308ad568be118beb3acEric Anholt 144919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (ctx->two_side_colors) 145019df602b39ec03f61edec308ad568be118beb3acEric Anholt emit_twoside(tctx); 14513141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 14523141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 14533141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 1454f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholtrename_color_inputs(struct tgsi_lowering_context *ctx, 145519df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_full_instruction *inst) 14563141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 145719df602b39ec03f61edec308ad568be118beb3acEric Anholt unsigned i, j; 145819df602b39ec03f61edec308ad568be118beb3acEric Anholt for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { 145919df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_src_register *src = &inst->Src[i].Register; 146019df602b39ec03f61edec308ad568be118beb3acEric Anholt if (src->File == TGSI_FILE_INPUT) { 146119df602b39ec03f61edec308ad568be118beb3acEric Anholt for (j = 0; j < ctx->two_side_colors; j++) { 146219df602b39ec03f61edec308ad568be118beb3acEric Anholt if (src->Index == ctx->two_side_idx[j]) { 146319df602b39ec03f61edec308ad568be118beb3acEric Anholt src->File = TGSI_FILE_TEMPORARY; 146419df602b39ec03f61edec308ad568be118beb3acEric Anholt src->Index = ctx->color_base + j; 146519df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 146619df602b39ec03f61edec308ad568be118beb3acEric Anholt } 146719df602b39ec03f61edec308ad568be118beb3acEric Anholt } 146819df602b39ec03f61edec308ad568be118beb3acEric Anholt } 146919df602b39ec03f61edec308ad568be118beb3acEric Anholt } 14703141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 14713141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 14723141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 14733141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtstatic void 14743141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholttransform_instr(struct tgsi_transform_context *tctx, 14753141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt struct tgsi_full_instruction *inst) 14763141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 1477f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx); 147819df602b39ec03f61edec308ad568be118beb3acEric Anholt 147919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->emitted_decls) { 148019df602b39ec03f61edec308ad568be118beb3acEric Anholt emit_decls(tctx); 148119df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx->emitted_decls = 1; 148219df602b39ec03f61edec308ad568be118beb3acEric Anholt } 148319df602b39ec03f61edec308ad568be118beb3acEric Anholt 148419df602b39ec03f61edec308ad568be118beb3acEric Anholt /* if emulating two-sided-color, we need to re-write some 148519df602b39ec03f61edec308ad568be118beb3acEric Anholt * src registers: 148619df602b39ec03f61edec308ad568be118beb3acEric Anholt */ 148719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (ctx->two_side_colors) 148819df602b39ec03f61edec308ad568be118beb3acEric Anholt rename_color_inputs(ctx, inst); 148919df602b39ec03f61edec308ad568be118beb3acEric Anholt 149019df602b39ec03f61edec308ad568be118beb3acEric Anholt switch (inst->Instruction.Opcode) { 149119df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_DST: 149219df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_DST) 149319df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 149419df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_dst(tctx, inst); 149519df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 149619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_XPD: 149719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_XPD) 149819df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 149919df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_xpd(tctx, inst); 150019df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 150119df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_SCS: 150219df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_SCS) 150319df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 150419df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_scs(tctx, inst); 150519df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 150619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_LRP: 150719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_LRP) 150819df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 150919df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_lrp(tctx, inst); 151019df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 151119df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_FRC: 151219df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_FRC) 151319df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 151419df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_frc(tctx, inst); 151519df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 151619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_POW: 151719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_POW) 151819df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 151919df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_pow(tctx, inst); 152019df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 152119df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_LIT: 152219df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_LIT) 152319df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 152419df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_lit(tctx, inst); 152519df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 152619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_EXP: 152719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_EXP) 152819df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 152919df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_exp(tctx, inst); 153019df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 153119df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_LOG: 153219df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_LOG) 153319df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 153419df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_log(tctx, inst); 153519df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 153619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_DP4: 153719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_DP4) 153819df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 153919df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_dotp(tctx, inst); 154019df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 154119df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_DP3: 154219df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_DP3) 154319df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 154419df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_dotp(tctx, inst); 154519df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 154619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_DPH: 154719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_DPH) 154819df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 154919df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_dotp(tctx, inst); 155019df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 155119df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_DP2: 155219df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_DP2) 155319df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 155419df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_dotp(tctx, inst); 155519df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 155619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_DP2A: 155719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!ctx->config->lower_DP2A) 155819df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 155919df602b39ec03f61edec308ad568be118beb3acEric Anholt transform_dotp(tctx, inst); 156019df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 156123e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King case TGSI_OPCODE_FLR: 156223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King if (!ctx->config->lower_FLR) 156323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King goto skip; 156423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King transform_flr_ceil(tctx, inst); 156523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King break; 156623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King case TGSI_OPCODE_CEIL: 156723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King if (!ctx->config->lower_CEIL) 156823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King goto skip; 156923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King transform_flr_ceil(tctx, inst); 157023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King break; 157165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King case TGSI_OPCODE_TRUNC: 157265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King if (!ctx->config->lower_TRUNC) 157365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King goto skip; 157465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King transform_trunc(tctx, inst); 157565460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King break; 157619df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_TEX: 157719df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_TXP: 157819df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_TXB: 157919df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_TXB2: 158019df602b39ec03f61edec308ad568be118beb3acEric Anholt case TGSI_OPCODE_TXL: 158119df602b39ec03f61edec308ad568be118beb3acEric Anholt if (transform_samp(tctx, inst)) 158219df602b39ec03f61edec308ad568be118beb3acEric Anholt goto skip; 158319df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 158419df602b39ec03f61edec308ad568be118beb3acEric Anholt default: 158519df602b39ec03f61edec308ad568be118beb3acEric Anholt skip: 158619df602b39ec03f61edec308ad568be118beb3acEric Anholt tctx->emit_instruction(tctx, inst); 158719df602b39ec03f61edec308ad568be118beb3acEric Anholt break; 158819df602b39ec03f61edec308ad568be118beb3acEric Anholt } 15893141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 15903141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 15913141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt/* returns NULL if no lowering required, else returns the new 15923141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * tokens (which caller is required to free()). In either case 15933141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt * returns the current info. 15943141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt */ 15953141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholtconst struct tgsi_token * 1596f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholttgsi_transform_lowering(const struct tgsi_lowering_config *config, 1597f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt const struct tgsi_token *tokens, 1598f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_shader_info *info) 15993141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt{ 1600f9854e169f54c8a79c7c01733d74979d300d5dbaEric Anholt struct tgsi_lowering_context ctx; 160119df602b39ec03f61edec308ad568be118beb3acEric Anholt struct tgsi_token *newtoks; 160219df602b39ec03f61edec308ad568be118beb3acEric Anholt int newlen, numtmp; 160319df602b39ec03f61edec308ad568be118beb3acEric Anholt 160419df602b39ec03f61edec308ad568be118beb3acEric Anholt /* sanity check in case limit is ever increased: */ 1605b5105e67a860c6c3271ad7d48e2d80e84c3e8adeJosé Fonseca STATIC_ASSERT((sizeof(config->saturate_s) * 8) >= PIPE_MAX_SAMPLERS); 160619df602b39ec03f61edec308ad568be118beb3acEric Anholt 160723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King /* sanity check the lowering */ 160823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King assert(!(config->lower_FRC && (config->lower_FLR || config->lower_CEIL))); 160965460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King assert(!(config->lower_FRC && config->lower_TRUNC)); 161023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King 161119df602b39ec03f61edec308ad568be118beb3acEric Anholt memset(&ctx, 0, sizeof(ctx)); 161219df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.base.transform_instruction = transform_instr; 161319df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.info = info; 161419df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.config = config; 161519df602b39ec03f61edec308ad568be118beb3acEric Anholt 161619df602b39ec03f61edec308ad568be118beb3acEric Anholt tgsi_scan_shader(tokens, info); 161719df602b39ec03f61edec308ad568be118beb3acEric Anholt 161819df602b39ec03f61edec308ad568be118beb3acEric Anholt /* if we are adding fragment shader support to emulate two-sided 161919df602b39ec03f61edec308ad568be118beb3acEric Anholt * color, then figure out the number of additional inputs we need 162019df602b39ec03f61edec308ad568be118beb3acEric Anholt * to create for BCOLOR's.. 162119df602b39ec03f61edec308ad568be118beb3acEric Anholt */ 1622af249a7da9bf2621ab836d5074ef692677b11bbfMarek Olšák if ((info->processor == PIPE_SHADER_FRAGMENT) && 162319df602b39ec03f61edec308ad568be118beb3acEric Anholt config->color_two_side) { 162419df602b39ec03f61edec308ad568be118beb3acEric Anholt int i; 162519df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.face_idx = -1; 162619df602b39ec03f61edec308ad568be118beb3acEric Anholt for (i = 0; i <= info->file_max[TGSI_FILE_INPUT]; i++) { 162719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (info->input_semantic_name[i] == TGSI_SEMANTIC_COLOR) 162819df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.two_side_idx[ctx.two_side_colors++] = i; 162919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (info->input_semantic_name[i] == TGSI_SEMANTIC_FACE) 163019df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.face_idx = i; 163119df602b39ec03f61edec308ad568be118beb3acEric Anholt } 163219df602b39ec03f61edec308ad568be118beb3acEric Anholt } 163319df602b39ec03f61edec308ad568be118beb3acEric Anholt 163419df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.saturate = config->saturate_r | config->saturate_s | config->saturate_t; 16353141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 16363141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#define OPCS(x) ((config->lower_ ## x) ? info->opcode_count[TGSI_OPCODE_ ## x] : 0) 163719df602b39ec03f61edec308ad568be118beb3acEric Anholt /* if there are no instructions to lower, then we are done: */ 163819df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!(OPCS(DST) || 163919df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(XPD) || 164019df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(SCS) || 164119df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(LRP) || 164219df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(FRC) || 164319df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(POW) || 164419df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(LIT) || 164519df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(EXP) || 164619df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(LOG) || 164719df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(DP4) || 164819df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(DP3) || 164919df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(DPH) || 165019df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(DP2) || 165119df602b39ec03f61edec308ad568be118beb3acEric Anholt OPCS(DP2A) || 165223e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King OPCS(FLR) || 165323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King OPCS(CEIL) || 165465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King OPCS(TRUNC) || 1655219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark OPCS(TXP) || 165619df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.two_side_colors || 165719df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.saturate)) 165819df602b39ec03f61edec308ad568be118beb3acEric Anholt return NULL; 16593141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 16603141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#if 0 /* debug */ 166119df602b39ec03f61edec308ad568be118beb3acEric Anholt _debug_printf("BEFORE:"); 166219df602b39ec03f61edec308ad568be118beb3acEric Anholt tgsi_dump(tokens, 0); 16633141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#endif 16643141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 166519df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = 0; 166619df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen = tgsi_num_tokens(tokens); 166719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(DST)) { 166819df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += DST_GROW * OPCS(DST); 166919df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, DST_TMP); 167019df602b39ec03f61edec308ad568be118beb3acEric Anholt } 167119df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(XPD)) { 167219df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += XPD_GROW * OPCS(XPD); 167319df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, XPD_TMP); 167419df602b39ec03f61edec308ad568be118beb3acEric Anholt } 167519df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(SCS)) { 167619df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += SCS_GROW * OPCS(SCS); 167719df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, SCS_TMP); 167819df602b39ec03f61edec308ad568be118beb3acEric Anholt } 167919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(LRP)) { 168019df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += LRP_GROW * OPCS(LRP); 168119df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, LRP_TMP); 168219df602b39ec03f61edec308ad568be118beb3acEric Anholt } 168319df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(FRC)) { 168419df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += FRC_GROW * OPCS(FRC); 168519df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, FRC_TMP); 168619df602b39ec03f61edec308ad568be118beb3acEric Anholt } 168719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(POW)) { 168819df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += POW_GROW * OPCS(POW); 168919df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, POW_TMP); 169019df602b39ec03f61edec308ad568be118beb3acEric Anholt } 169119df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(LIT)) { 169219df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += LIT_GROW * OPCS(LIT); 169319df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, LIT_TMP); 169419df602b39ec03f61edec308ad568be118beb3acEric Anholt } 169519df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(EXP)) { 169619df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += EXP_GROW * OPCS(EXP); 169719df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, EXP_TMP); 169819df602b39ec03f61edec308ad568be118beb3acEric Anholt } 169919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(LOG)) { 170019df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += LOG_GROW * OPCS(LOG); 170119df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, LOG_TMP); 170219df602b39ec03f61edec308ad568be118beb3acEric Anholt } 170319df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(DP4)) { 170419df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += DP4_GROW * OPCS(DP4); 170519df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, DOTP_TMP); 170619df602b39ec03f61edec308ad568be118beb3acEric Anholt } 170719df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(DP3)) { 170819df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += DP3_GROW * OPCS(DP3); 170919df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, DOTP_TMP); 171019df602b39ec03f61edec308ad568be118beb3acEric Anholt } 171119df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(DPH)) { 171219df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += DPH_GROW * OPCS(DPH); 171319df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, DOTP_TMP); 171419df602b39ec03f61edec308ad568be118beb3acEric Anholt } 171519df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(DP2)) { 171619df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += DP2_GROW * OPCS(DP2); 171719df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, DOTP_TMP); 171819df602b39ec03f61edec308ad568be118beb3acEric Anholt } 171919df602b39ec03f61edec308ad568be118beb3acEric Anholt if (OPCS(DP2A)) { 172019df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += DP2A_GROW * OPCS(DP2A); 172119df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, DOTP_TMP); 172219df602b39ec03f61edec308ad568be118beb3acEric Anholt } 172323e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King if (OPCS(FLR)) { 172423e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King newlen += FLR_GROW * OPCS(FLR); 172523e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King numtmp = MAX2(numtmp, FLR_TMP); 172623e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King } 172723e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King if (OPCS(CEIL)) { 172823e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King newlen += CEIL_GROW * OPCS(CEIL); 172923e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King numtmp = MAX2(numtmp, CEIL_TMP); 173023e870a888e24b25f9b61a9b1e486e3ef2c7a12cRussell King } 173165460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King if (OPCS(TRUNC)) { 173265460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King newlen += TRUNC_GROW * OPCS(TRUNC); 173365460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King numtmp = MAX2(numtmp, TRUNC_TMP); 173465460cf4c87b9b0c423db80fbd31fd44fbfde7ceRussell King } 1735219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark if (ctx.saturate || config->lower_TXP) { 1736219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark int n = 0; 1737219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark 1738219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark if (ctx.saturate) { 1739219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark n = info->opcode_count[TGSI_OPCODE_TEX] + 1740219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark info->opcode_count[TGSI_OPCODE_TXP] + 1741219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark info->opcode_count[TGSI_OPCODE_TXB] + 1742219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark info->opcode_count[TGSI_OPCODE_TXB2] + 1743219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark info->opcode_count[TGSI_OPCODE_TXL]; 1744219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark } else if (config->lower_TXP) { 1745219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark n = info->opcode_count[TGSI_OPCODE_TXP]; 1746219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark } 1747219440ddebcd804d6b8cb0a79c4bbdd7701ea355Rob Clark 174819df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += SAMP_GROW * n; 174919df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp = MAX2(numtmp, SAMP_TMP); 175019df602b39ec03f61edec308ad568be118beb3acEric Anholt } 175119df602b39ec03f61edec308ad568be118beb3acEric Anholt 175219df602b39ec03f61edec308ad568be118beb3acEric Anholt /* specifically don't include two_side_colors temps in the count: */ 175319df602b39ec03f61edec308ad568be118beb3acEric Anholt ctx.numtmp = numtmp; 175419df602b39ec03f61edec308ad568be118beb3acEric Anholt 175519df602b39ec03f61edec308ad568be118beb3acEric Anholt if (ctx.two_side_colors) { 175619df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += TWOSIDE_GROW(ctx.two_side_colors); 175719df602b39ec03f61edec308ad568be118beb3acEric Anholt /* note: we permanently consume temp regs, re-writing references 175819df602b39ec03f61edec308ad568be118beb3acEric Anholt * to IN.COLOR[n] to TEMP[m] (holding the output of of the CMP 175919df602b39ec03f61edec308ad568be118beb3acEric Anholt * instruction that selects which varying to use): 176019df602b39ec03f61edec308ad568be118beb3acEric Anholt */ 176119df602b39ec03f61edec308ad568be118beb3acEric Anholt numtmp += ctx.two_side_colors; 176219df602b39ec03f61edec308ad568be118beb3acEric Anholt } 176319df602b39ec03f61edec308ad568be118beb3acEric Anholt 176419df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += 2 * numtmp; 176519df602b39ec03f61edec308ad568be118beb3acEric Anholt newlen += 5; /* immediate */ 176619df602b39ec03f61edec308ad568be118beb3acEric Anholt 176719df602b39ec03f61edec308ad568be118beb3acEric Anholt newtoks = tgsi_alloc_tokens(newlen); 176819df602b39ec03f61edec308ad568be118beb3acEric Anholt if (!newtoks) 176919df602b39ec03f61edec308ad568be118beb3acEric Anholt return NULL; 177019df602b39ec03f61edec308ad568be118beb3acEric Anholt 177119df602b39ec03f61edec308ad568be118beb3acEric Anholt tgsi_transform_shader(tokens, newtoks, newlen, &ctx.base); 177219df602b39ec03f61edec308ad568be118beb3acEric Anholt 177319df602b39ec03f61edec308ad568be118beb3acEric Anholt tgsi_scan_shader(newtoks, info); 17743141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 17753141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#if 0 /* debug */ 177619df602b39ec03f61edec308ad568be118beb3acEric Anholt _debug_printf("AFTER:"); 177719df602b39ec03f61edec308ad568be118beb3acEric Anholt tgsi_dump(newtoks, 0); 17783141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt#endif 17793141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt 178019df602b39ec03f61edec308ad568be118beb3acEric Anholt return newtoks; 17813141dc8e8794217e5aec094d3ce2e8a1c4e50e58Eric Anholt} 1782