i915_fpc_emit.c revision 63dbd3fefba93ccfb984ed589795f6784bb4d1e3
13af1f3b9220733f5e3a76fe38fbc397974678234Brian/**************************************************************************
23af1f3b9220733f5e3a76fe38fbc397974678234Brian *
33af1f3b9220733f5e3a76fe38fbc397974678234Brian * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
43af1f3b9220733f5e3a76fe38fbc397974678234Brian * All Rights Reserved.
53af1f3b9220733f5e3a76fe38fbc397974678234Brian *
63af1f3b9220733f5e3a76fe38fbc397974678234Brian * Permission is hereby granted, free of charge, to any person obtaining a
73af1f3b9220733f5e3a76fe38fbc397974678234Brian * copy of this software and associated documentation files (the
83af1f3b9220733f5e3a76fe38fbc397974678234Brian * "Software"), to deal in the Software without restriction, including
93af1f3b9220733f5e3a76fe38fbc397974678234Brian * without limitation the rights to use, copy, modify, merge, publish,
103af1f3b9220733f5e3a76fe38fbc397974678234Brian * distribute, sub license, and/or sell copies of the Software, and to
113af1f3b9220733f5e3a76fe38fbc397974678234Brian * permit persons to whom the Software is furnished to do so, subject to
123af1f3b9220733f5e3a76fe38fbc397974678234Brian * the following conditions:
133af1f3b9220733f5e3a76fe38fbc397974678234Brian *
143af1f3b9220733f5e3a76fe38fbc397974678234Brian * The above copyright notice and this permission notice (including the
153af1f3b9220733f5e3a76fe38fbc397974678234Brian * next paragraph) shall be included in all copies or substantial portions
163af1f3b9220733f5e3a76fe38fbc397974678234Brian * of the Software.
173af1f3b9220733f5e3a76fe38fbc397974678234Brian *
183af1f3b9220733f5e3a76fe38fbc397974678234Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
193af1f3b9220733f5e3a76fe38fbc397974678234Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
203af1f3b9220733f5e3a76fe38fbc397974678234Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
213af1f3b9220733f5e3a76fe38fbc397974678234Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
223af1f3b9220733f5e3a76fe38fbc397974678234Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
233af1f3b9220733f5e3a76fe38fbc397974678234Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
243af1f3b9220733f5e3a76fe38fbc397974678234Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
253af1f3b9220733f5e3a76fe38fbc397974678234Brian *
263af1f3b9220733f5e3a76fe38fbc397974678234Brian **************************************************************************/
273af1f3b9220733f5e3a76fe38fbc397974678234Brian
283af1f3b9220733f5e3a76fe38fbc397974678234Brian#include "i915_reg.h"
293af1f3b9220733f5e3a76fe38fbc397974678234Brian#include "i915_context.h"
303af1f3b9220733f5e3a76fe38fbc397974678234Brian#include "i915_fpc.h"
312c4661f8fce8a27f2082c6ac498f9fb188878476Michal Krol#include "util/u_math.h"
323af1f3b9220733f5e3a76fe38fbc397974678234Brian
333af1f3b9220733f5e3a76fe38fbc397974678234Brian
343af1f3b9220733f5e3a76fe38fbc397974678234Brian#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
353af1f3b9220733f5e3a76fe38fbc397974678234Brian#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
363af1f3b9220733f5e3a76fe38fbc397974678234Brian#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
373af1f3b9220733f5e3a76fe38fbc397974678234Brian#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT)
383af1f3b9220733f5e3a76fe38fbc397974678234Brian#define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT)
393af1f3b9220733f5e3a76fe38fbc397974678234Brian#define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT)
403af1f3b9220733f5e3a76fe38fbc397974678234Brian#define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT)
413af1f3b9220733f5e3a76fe38fbc397974678234Brian#define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT)
423af1f3b9220733f5e3a76fe38fbc397974678234Brian
433af1f3b9220733f5e3a76fe38fbc397974678234Brian/* These are special, and don't have swizzle/negate bits.
443af1f3b9220733f5e3a76fe38fbc397974678234Brian */
453af1f3b9220733f5e3a76fe38fbc397974678234Brian#define T0_SAMPLER( reg )     (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT)
463af1f3b9220733f5e3a76fe38fbc397974678234Brian#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \
473af1f3b9220733f5e3a76fe38fbc397974678234Brian			       (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT))
483af1f3b9220733f5e3a76fe38fbc397974678234Brian
493af1f3b9220733f5e3a76fe38fbc397974678234Brian
503af1f3b9220733f5e3a76fe38fbc397974678234Brian/* Macros for translating UREG's into the various register fields used
513af1f3b9220733f5e3a76fe38fbc397974678234Brian * by the I915 programmable unit.
523af1f3b9220733f5e3a76fe38fbc397974678234Brian */
533af1f3b9220733f5e3a76fe38fbc397974678234Brian#define UREG_A0_DEST_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
543af1f3b9220733f5e3a76fe38fbc397974678234Brian#define UREG_A0_SRC0_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
553af1f3b9220733f5e3a76fe38fbc397974678234Brian#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
563af1f3b9220733f5e3a76fe38fbc397974678234Brian#define UREG_A1_SRC1_SHIFT_LEFT  (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
573af1f3b9220733f5e3a76fe38fbc397974678234Brian#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
583af1f3b9220733f5e3a76fe38fbc397974678234Brian#define UREG_A2_SRC2_SHIFT_LEFT  (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
593af1f3b9220733f5e3a76fe38fbc397974678234Brian
603af1f3b9220733f5e3a76fe38fbc397974678234Brian#define UREG_MASK         0xffffff00
613af1f3b9220733f5e3a76fe38fbc397974678234Brian#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
623af1f3b9220733f5e3a76fe38fbc397974678234Brian  			   (REG_NR_MASK << UREG_NR_SHIFT))
633af1f3b9220733f5e3a76fe38fbc397974678234Brian
643af1f3b9220733f5e3a76fe38fbc397974678234Brian
653af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
663af1f3b9220733f5e3a76fe38fbc397974678234Briani915_get_temp(struct i915_fp_compile *p)
673af1f3b9220733f5e3a76fe38fbc397974678234Brian{
683af1f3b9220733f5e3a76fe38fbc397974678234Brian   int bit = ffs(~p->temp_flag);
693af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (!bit) {
705d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      i915_program_error(p, "i915_get_temp: out of temporaries");
713af1f3b9220733f5e3a76fe38fbc397974678234Brian      return 0;
723af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
733af1f3b9220733f5e3a76fe38fbc397974678234Brian
743af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->temp_flag |= 1 << (bit - 1);
750235b3252100eda553babea42c014445358a2985Brian   return bit - 1;
763af1f3b9220733f5e3a76fe38fbc397974678234Brian}
773af1f3b9220733f5e3a76fe38fbc397974678234Brian
783af1f3b9220733f5e3a76fe38fbc397974678234Brian
790235b3252100eda553babea42c014445358a2985Brianstatic void
800235b3252100eda553babea42c014445358a2985Briani915_release_temp(struct i915_fp_compile *p, int reg)
810235b3252100eda553babea42c014445358a2985Brian{
820235b3252100eda553babea42c014445358a2985Brian   p->temp_flag &= ~(1 << reg);
830235b3252100eda553babea42c014445358a2985Brian}
840235b3252100eda553babea42c014445358a2985Brian
850235b3252100eda553babea42c014445358a2985Brian
860235b3252100eda553babea42c014445358a2985Brian/**
870235b3252100eda553babea42c014445358a2985Brian * Get unpreserved temporary, a temp whose value is not preserved between
880235b3252100eda553babea42c014445358a2985Brian * PS program phases.
890235b3252100eda553babea42c014445358a2985Brian */
903af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
913af1f3b9220733f5e3a76fe38fbc397974678234Briani915_get_utemp(struct i915_fp_compile * p)
923af1f3b9220733f5e3a76fe38fbc397974678234Brian{
933af1f3b9220733f5e3a76fe38fbc397974678234Brian   int bit = ffs(~p->utemp_flag);
943af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (!bit) {
955d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      i915_program_error(p, "i915_get_utemp: out of temporaries");
963af1f3b9220733f5e3a76fe38fbc397974678234Brian      return 0;
973af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
983af1f3b9220733f5e3a76fe38fbc397974678234Brian
993af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->utemp_flag |= 1 << (bit - 1);
1003af1f3b9220733f5e3a76fe38fbc397974678234Brian   return UREG(REG_TYPE_U, (bit - 1));
1013af1f3b9220733f5e3a76fe38fbc397974678234Brian}
1023af1f3b9220733f5e3a76fe38fbc397974678234Brian
1033af1f3b9220733f5e3a76fe38fbc397974678234Brianvoid
1043af1f3b9220733f5e3a76fe38fbc397974678234Briani915_release_utemps(struct i915_fp_compile *p)
1053af1f3b9220733f5e3a76fe38fbc397974678234Brian{
1063af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->utemp_flag = ~0x7;
1073af1f3b9220733f5e3a76fe38fbc397974678234Brian}
1083af1f3b9220733f5e3a76fe38fbc397974678234Brian
1093af1f3b9220733f5e3a76fe38fbc397974678234Brian
1103af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
1113af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_decl(struct i915_fp_compile *p,
1123af1f3b9220733f5e3a76fe38fbc397974678234Brian               uint type, uint nr, uint d0_flags)
1133af1f3b9220733f5e3a76fe38fbc397974678234Brian{
1143af1f3b9220733f5e3a76fe38fbc397974678234Brian   uint reg = UREG(type, nr);
1153af1f3b9220733f5e3a76fe38fbc397974678234Brian
1163af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (type == REG_TYPE_T) {
1173af1f3b9220733f5e3a76fe38fbc397974678234Brian      if (p->decl_t & (1 << nr))
1183af1f3b9220733f5e3a76fe38fbc397974678234Brian         return reg;
1193af1f3b9220733f5e3a76fe38fbc397974678234Brian
1203af1f3b9220733f5e3a76fe38fbc397974678234Brian      p->decl_t |= (1 << nr);
1213af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
1223af1f3b9220733f5e3a76fe38fbc397974678234Brian   else if (type == REG_TYPE_S) {
1233af1f3b9220733f5e3a76fe38fbc397974678234Brian      if (p->decl_s & (1 << nr))
1243af1f3b9220733f5e3a76fe38fbc397974678234Brian         return reg;
1253af1f3b9220733f5e3a76fe38fbc397974678234Brian
1263af1f3b9220733f5e3a76fe38fbc397974678234Brian      p->decl_s |= (1 << nr);
1273af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
1283af1f3b9220733f5e3a76fe38fbc397974678234Brian   else
1293af1f3b9220733f5e3a76fe38fbc397974678234Brian      return reg;
1303af1f3b9220733f5e3a76fe38fbc397974678234Brian
131c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   if (p->decl< p->declarations + I915_PROGRAM_SIZE) {
132c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
133c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->decl++) = D1_MBZ;
134c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->decl++) = D2_MBZ;
135c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   }
136c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   else
1375d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      i915_program_error(p, "Out of declarations");
1383af1f3b9220733f5e3a76fe38fbc397974678234Brian
1393af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->nr_decl_insn++;
1403af1f3b9220733f5e3a76fe38fbc397974678234Brian   return reg;
1413af1f3b9220733f5e3a76fe38fbc397974678234Brian}
1423af1f3b9220733f5e3a76fe38fbc397974678234Brian
1433af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
1443af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_arith(struct i915_fp_compile * p,
1453af1f3b9220733f5e3a76fe38fbc397974678234Brian                uint op,
1463af1f3b9220733f5e3a76fe38fbc397974678234Brian                uint dest,
1473af1f3b9220733f5e3a76fe38fbc397974678234Brian                uint mask,
1483af1f3b9220733f5e3a76fe38fbc397974678234Brian                uint saturate, uint src0, uint src1, uint src2)
1493af1f3b9220733f5e3a76fe38fbc397974678234Brian{
1503af1f3b9220733f5e3a76fe38fbc397974678234Brian   uint c[3];
1513af1f3b9220733f5e3a76fe38fbc397974678234Brian   uint nr_const = 0;
1523af1f3b9220733f5e3a76fe38fbc397974678234Brian
1533af1f3b9220733f5e3a76fe38fbc397974678234Brian   assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
1543af1f3b9220733f5e3a76fe38fbc397974678234Brian   dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
1553af1f3b9220733f5e3a76fe38fbc397974678234Brian   assert(dest);
1563af1f3b9220733f5e3a76fe38fbc397974678234Brian
1573af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (GET_UREG_TYPE(src0) == REG_TYPE_CONST)
1583af1f3b9220733f5e3a76fe38fbc397974678234Brian      c[nr_const++] = 0;
1593af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (GET_UREG_TYPE(src1) == REG_TYPE_CONST)
1603af1f3b9220733f5e3a76fe38fbc397974678234Brian      c[nr_const++] = 1;
1613af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (GET_UREG_TYPE(src2) == REG_TYPE_CONST)
1623af1f3b9220733f5e3a76fe38fbc397974678234Brian      c[nr_const++] = 2;
1633af1f3b9220733f5e3a76fe38fbc397974678234Brian
1643af1f3b9220733f5e3a76fe38fbc397974678234Brian   /* Recursively call this function to MOV additional const values
1653af1f3b9220733f5e3a76fe38fbc397974678234Brian    * into temporary registers.  Use utemp registers for this -
1663af1f3b9220733f5e3a76fe38fbc397974678234Brian    * currently shouldn't be possible to run out, but keep an eye on
1673af1f3b9220733f5e3a76fe38fbc397974678234Brian    * this.
1683af1f3b9220733f5e3a76fe38fbc397974678234Brian    */
1693af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (nr_const > 1) {
1703af1f3b9220733f5e3a76fe38fbc397974678234Brian      uint s[3], first, i, old_utemp_flag;
1713af1f3b9220733f5e3a76fe38fbc397974678234Brian
1723af1f3b9220733f5e3a76fe38fbc397974678234Brian      s[0] = src0;
1733af1f3b9220733f5e3a76fe38fbc397974678234Brian      s[1] = src1;
1743af1f3b9220733f5e3a76fe38fbc397974678234Brian      s[2] = src2;
1753af1f3b9220733f5e3a76fe38fbc397974678234Brian      old_utemp_flag = p->utemp_flag;
1763af1f3b9220733f5e3a76fe38fbc397974678234Brian
1773af1f3b9220733f5e3a76fe38fbc397974678234Brian      first = GET_UREG_NR(s[c[0]]);
1783af1f3b9220733f5e3a76fe38fbc397974678234Brian      for (i = 1; i < nr_const; i++) {
1793af1f3b9220733f5e3a76fe38fbc397974678234Brian         if (GET_UREG_NR(s[c[i]]) != first) {
1803af1f3b9220733f5e3a76fe38fbc397974678234Brian            uint tmp = i915_get_utemp(p);
1813af1f3b9220733f5e3a76fe38fbc397974678234Brian
1823af1f3b9220733f5e3a76fe38fbc397974678234Brian            i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0,
1833af1f3b9220733f5e3a76fe38fbc397974678234Brian                            s[c[i]], 0, 0);
1843af1f3b9220733f5e3a76fe38fbc397974678234Brian            s[c[i]] = tmp;
1853af1f3b9220733f5e3a76fe38fbc397974678234Brian         }
1863af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
1873af1f3b9220733f5e3a76fe38fbc397974678234Brian
1883af1f3b9220733f5e3a76fe38fbc397974678234Brian      src0 = s[0];
1893af1f3b9220733f5e3a76fe38fbc397974678234Brian      src1 = s[1];
1903af1f3b9220733f5e3a76fe38fbc397974678234Brian      src2 = s[2];
1913af1f3b9220733f5e3a76fe38fbc397974678234Brian      p->utemp_flag = old_utemp_flag;   /* restore */
1923af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
1933af1f3b9220733f5e3a76fe38fbc397974678234Brian
194c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   if (p->csr< p->program + I915_PROGRAM_SIZE) {
195c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
196c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
197c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
198c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   }
199c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   else
2005d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      i915_program_error(p, "Out of instructions");
2015d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin
2025d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   if (GET_UREG_TYPE(dest) == REG_TYPE_R)
2035d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
2043af1f3b9220733f5e3a76fe38fbc397974678234Brian
2053af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->nr_alu_insn++;
2063af1f3b9220733f5e3a76fe38fbc397974678234Brian   return dest;
2073af1f3b9220733f5e3a76fe38fbc397974678234Brian}
2083af1f3b9220733f5e3a76fe38fbc397974678234Brian
2090235b3252100eda553babea42c014445358a2985Brian
2100235b3252100eda553babea42c014445358a2985Brian/**
2110235b3252100eda553babea42c014445358a2985Brian * Emit a texture load or texkill instruction.
2120235b3252100eda553babea42c014445358a2985Brian * \param dest  the dest i915 register
2130235b3252100eda553babea42c014445358a2985Brian * \param destmask  the dest register writemask
2140235b3252100eda553babea42c014445358a2985Brian * \param sampler  the i915 sampler register
2150235b3252100eda553babea42c014445358a2985Brian * \param coord  the i915 source texcoord operand
2160235b3252100eda553babea42c014445358a2985Brian * \param opcode  the instruction opcode
2170235b3252100eda553babea42c014445358a2985Brian */
2183af1f3b9220733f5e3a76fe38fbc397974678234Brianuint i915_emit_texld( struct i915_fp_compile *p,
219e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint dest,
220e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint destmask,
221e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint sampler,
222e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint coord,
223e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint opcode,
224e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint num_coord )
2253af1f3b9220733f5e3a76fe38fbc397974678234Brian{
2260235b3252100eda553babea42c014445358a2985Brian   const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
227e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin
2280235b3252100eda553babea42c014445358a2985Brian   int temp = -1;
229e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin   uint ignore = 0;
230e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin
231e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin   /* Eliminate the useless texture coordinates. Otherwise we end up generating
232e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin    * a swizzle for no reason below. */
233e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin   switch(num_coord) {
234e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      case 0:
235e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         /* Ignore x */
236e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         ignore |= (0xf << UREG_CHANNEL_X_SHIFT);
237e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      case 1:
238e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         /* Ignore y */
239e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         ignore |= (0xf << UREG_CHANNEL_Y_SHIFT);
240e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      case 2:
241e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         /* Ignore z */
242e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         ignore |= (0xf << UREG_CHANNEL_Z_SHIFT);
243e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      case 3:
244e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         /* Ignore w */
245e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         ignore |= (0xf << UREG_CHANNEL_W_SHIFT);
246e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin   }
2470235b3252100eda553babea42c014445358a2985Brian
24863dbd3fefba93ccfb984ed589795f6784bb4d1e3Stéphane Marchesin   if ( (coord & ~ignore ) != (k & ~ignore) ) {
2490235b3252100eda553babea42c014445358a2985Brian      /* texcoord is swizzled or negated.  Need to allocate a new temporary
2500235b3252100eda553babea42c014445358a2985Brian       * register (a utemp / unpreserved temp) won't do.
2513af1f3b9220733f5e3a76fe38fbc397974678234Brian       */
2520235b3252100eda553babea42c014445358a2985Brian      uint tempReg;
2530235b3252100eda553babea42c014445358a2985Brian
2540235b3252100eda553babea42c014445358a2985Brian      temp = i915_get_temp(p);           /* get temp reg index */
2550235b3252100eda553babea42c014445358a2985Brian      tempReg = UREG(REG_TYPE_R, temp);  /* make i915 register */
2560235b3252100eda553babea42c014445358a2985Brian
2570235b3252100eda553babea42c014445358a2985Brian      i915_emit_arith( p, A0_MOV,
2580235b3252100eda553babea42c014445358a2985Brian                       tempReg, A0_DEST_CHANNEL_ALL, /* dest reg, writemask */
2590235b3252100eda553babea42c014445358a2985Brian                       0,                            /* saturate */
2600235b3252100eda553babea42c014445358a2985Brian                       coord, 0, 0 );                /* src0, src1, src2 */
2610235b3252100eda553babea42c014445358a2985Brian
2620235b3252100eda553babea42c014445358a2985Brian      /* new src texcoord is tempReg */
2630235b3252100eda553babea42c014445358a2985Brian      coord = tempReg;
2643af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
2653af1f3b9220733f5e3a76fe38fbc397974678234Brian
2663af1f3b9220733f5e3a76fe38fbc397974678234Brian   /* Don't worry about saturate as we only support
2673af1f3b9220733f5e3a76fe38fbc397974678234Brian    */
2683af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (destmask != A0_DEST_CHANNEL_ALL) {
2690235b3252100eda553babea42c014445358a2985Brian      /* if not writing to XYZW... */
2703af1f3b9220733f5e3a76fe38fbc397974678234Brian      uint tmp = i915_get_utemp(p);
271e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode, num_coord );
2723af1f3b9220733f5e3a76fe38fbc397974678234Brian      i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
2730235b3252100eda553babea42c014445358a2985Brian      /* XXX release utemp here? */
2743af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
2753af1f3b9220733f5e3a76fe38fbc397974678234Brian   else {
2763af1f3b9220733f5e3a76fe38fbc397974678234Brian      assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
2774a796264dfc1bdba37a7204f3439a8da213109edVinson Lee      assert(dest == UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
2783af1f3b9220733f5e3a76fe38fbc397974678234Brian
2795d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      /* Output register being oC or oD defines a phase boundary */
2805d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      if (GET_UREG_TYPE(dest) == REG_TYPE_OC ||
2815d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin          GET_UREG_TYPE(dest) == REG_TYPE_OD)
2825d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         p->nr_tex_indirect++;
2835d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin
2845d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      /* Reading from an r# register whose contents depend on output of the
2855d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin       * current phase defines a phase boundary.
2865d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin       */
2875d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      if (GET_UREG_TYPE(coord) == REG_TYPE_R &&
2885d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin          p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
2895d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         p->nr_tex_indirect++;
2903af1f3b9220733f5e3a76fe38fbc397974678234Brian
291c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      if (p->csr< p->program + I915_PROGRAM_SIZE) {
292c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin         *(p->csr++) = (opcode |
2935d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin                        T0_DEST( dest ) |
2945d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin                        T0_SAMPLER( sampler ));
2953af1f3b9220733f5e3a76fe38fbc397974678234Brian
296c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin         *(p->csr++) = T1_ADDRESS_REG( coord );
297c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin         *(p->csr++) = T2_MBZ;
298c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      }
2995d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      else
3005d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         i915_program_error(p, "Out of instructions");
3015d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin
3025d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      if (GET_UREG_TYPE(dest) == REG_TYPE_R)
3035d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
3043af1f3b9220733f5e3a76fe38fbc397974678234Brian
3053af1f3b9220733f5e3a76fe38fbc397974678234Brian      p->nr_tex_insn++;
3063af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
3070235b3252100eda553babea42c014445358a2985Brian
3080235b3252100eda553babea42c014445358a2985Brian   if (temp >= 0)
3090235b3252100eda553babea42c014445358a2985Brian      i915_release_temp(p, temp);
3100235b3252100eda553babea42c014445358a2985Brian
3110235b3252100eda553babea42c014445358a2985Brian   return dest;
3123af1f3b9220733f5e3a76fe38fbc397974678234Brian}
3133af1f3b9220733f5e3a76fe38fbc397974678234Brian
3143af1f3b9220733f5e3a76fe38fbc397974678234Brian
3153af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
3163af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const1f(struct i915_fp_compile * p, float c0)
3173af1f3b9220733f5e3a76fe38fbc397974678234Brian{
318c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian   struct i915_fragment_shader *ifs = p->shader;
3195961732c1b59403b4e736fa354a64d4a0e5d8af2Michal   unsigned reg, idx;
3203af1f3b9220733f5e3a76fe38fbc397974678234Brian
3213af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 0.0)
3223af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO);
3233af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 1.0)
3243af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE);
3253af1f3b9220733f5e3a76fe38fbc397974678234Brian
3263af1f3b9220733f5e3a76fe38fbc397974678234Brian   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
327c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
3283af1f3b9220733f5e3a76fe38fbc397974678234Brian         continue;
3293af1f3b9220733f5e3a76fe38fbc397974678234Brian      for (idx = 0; idx < 4; idx++) {
330c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         if (!(ifs->constant_flags[reg] & (1 << idx)) ||
331c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian             ifs->constants[reg][idx] == c0) {
332c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constants[reg][idx] = c0;
333c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constant_flags[reg] |= 1 << idx;
334c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            if (reg + 1 > ifs->num_constants)
335c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian               ifs->num_constants = reg + 1;
3363af1f3b9220733f5e3a76fe38fbc397974678234Brian            return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE);
3373af1f3b9220733f5e3a76fe38fbc397974678234Brian         }
3383af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
3393af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
3403af1f3b9220733f5e3a76fe38fbc397974678234Brian
3415d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   i915_program_error(p, "i915_emit_const1f: out of constants");
3423af1f3b9220733f5e3a76fe38fbc397974678234Brian   return 0;
3433af1f3b9220733f5e3a76fe38fbc397974678234Brian}
3443af1f3b9220733f5e3a76fe38fbc397974678234Brian
3453af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
3463af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
3473af1f3b9220733f5e3a76fe38fbc397974678234Brian{
348c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian   struct i915_fragment_shader *ifs = p->shader;
3495961732c1b59403b4e736fa354a64d4a0e5d8af2Michal   unsigned reg, idx;
3503af1f3b9220733f5e3a76fe38fbc397974678234Brian
3513af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 0.0)
3523af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W);
3533af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 1.0)
3543af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W);
3553af1f3b9220733f5e3a76fe38fbc397974678234Brian
3563af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c1 == 0.0)
3573af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W);
3583af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c1 == 1.0)
3593af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
3603af1f3b9220733f5e3a76fe38fbc397974678234Brian
361c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   // XXX emit swizzle here for 0, 1, -1 and any combination thereof
362c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   // we can use swizzle + neg for that
3633af1f3b9220733f5e3a76fe38fbc397974678234Brian   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
364c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      if (ifs->constant_flags[reg] == 0xf ||
365c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
3663af1f3b9220733f5e3a76fe38fbc397974678234Brian         continue;
3673af1f3b9220733f5e3a76fe38fbc397974678234Brian      for (idx = 0; idx < 3; idx++) {
368c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         if (!(ifs->constant_flags[reg] & (3 << idx))) {
369c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constants[reg][idx + 0] = c0;
370c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constants[reg][idx + 1] = c1;
371c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constant_flags[reg] |= 3 << idx;
372c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            if (reg + 1 > ifs->num_constants)
373c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian               ifs->num_constants = reg + 1;
374c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian            return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE);
3753af1f3b9220733f5e3a76fe38fbc397974678234Brian         }
3763af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
3773af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
3783af1f3b9220733f5e3a76fe38fbc397974678234Brian
3795d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   i915_program_error(p, "i915_emit_const2f: out of constants");
3803af1f3b9220733f5e3a76fe38fbc397974678234Brian   return 0;
3813af1f3b9220733f5e3a76fe38fbc397974678234Brian}
3823af1f3b9220733f5e3a76fe38fbc397974678234Brian
3833af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
3843af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const4f(struct i915_fp_compile * p,
3853af1f3b9220733f5e3a76fe38fbc397974678234Brian                  float c0, float c1, float c2, float c3)
3863af1f3b9220733f5e3a76fe38fbc397974678234Brian{
387c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian   struct i915_fragment_shader *ifs = p->shader;
3885961732c1b59403b4e736fa354a64d4a0e5d8af2Michal   unsigned reg;
3893af1f3b9220733f5e3a76fe38fbc397974678234Brian
3905d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   // XXX emit swizzle here for 0, 1, -1 and any combination thereof
3915d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   // we can use swizzle + neg for that
3923af1f3b9220733f5e3a76fe38fbc397974678234Brian   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
393c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      if (ifs->constant_flags[reg] == 0xf &&
394c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][0] == c0 &&
395c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][1] == c1 &&
396c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][2] == c2 &&
397c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][3] == c3) {
3983af1f3b9220733f5e3a76fe38fbc397974678234Brian         return UREG(REG_TYPE_CONST, reg);
3993af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
400c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      else if (ifs->constant_flags[reg] == 0) {
401c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian
402c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][0] = c0;
403c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][1] = c1;
404c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][2] = c2;
405c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][3] = c3;
406c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constant_flags[reg] = 0xf;
407c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         if (reg + 1 > ifs->num_constants)
408c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->num_constants = reg + 1;
4093af1f3b9220733f5e3a76fe38fbc397974678234Brian         return UREG(REG_TYPE_CONST, reg);
4103af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
4113af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
4123af1f3b9220733f5e3a76fe38fbc397974678234Brian
4135d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   i915_program_error(p, "i915_emit_const4f: out of constants");
4143af1f3b9220733f5e3a76fe38fbc397974678234Brian   return 0;
4153af1f3b9220733f5e3a76fe38fbc397974678234Brian}
4163af1f3b9220733f5e3a76fe38fbc397974678234Brian
4173af1f3b9220733f5e3a76fe38fbc397974678234Brian
4183af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
4193af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const4fv(struct i915_fp_compile * p, const float * c)
4203af1f3b9220733f5e3a76fe38fbc397974678234Brian{
4213af1f3b9220733f5e3a76fe38fbc397974678234Brian   return i915_emit_const4f(p, c[0], c[1], c[2], c[3]);
4223af1f3b9220733f5e3a76fe38fbc397974678234Brian}
423