i915_fpc_emit.c revision 5d7609715a44d08f29d4b605c4bea2742a194493
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,
2193af1f3b9220733f5e3a76fe38fbc397974678234Brian			uint dest,
2203af1f3b9220733f5e3a76fe38fbc397974678234Brian			uint destmask,
2213af1f3b9220733f5e3a76fe38fbc397974678234Brian			uint sampler,
2223af1f3b9220733f5e3a76fe38fbc397974678234Brian			uint coord,
2230235b3252100eda553babea42c014445358a2985Brian			uint opcode )
2243af1f3b9220733f5e3a76fe38fbc397974678234Brian{
2250235b3252100eda553babea42c014445358a2985Brian   const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
2260235b3252100eda553babea42c014445358a2985Brian   int temp = -1;
2270235b3252100eda553babea42c014445358a2985Brian
228c990d0fd57a05301429b3af75b7fed0337621941Brian   if (coord != k) {
2290235b3252100eda553babea42c014445358a2985Brian      /* texcoord is swizzled or negated.  Need to allocate a new temporary
2300235b3252100eda553babea42c014445358a2985Brian       * register (a utemp / unpreserved temp) won't do.
2313af1f3b9220733f5e3a76fe38fbc397974678234Brian       */
2320235b3252100eda553babea42c014445358a2985Brian      uint tempReg;
2330235b3252100eda553babea42c014445358a2985Brian
2340235b3252100eda553babea42c014445358a2985Brian      temp = i915_get_temp(p);           /* get temp reg index */
2350235b3252100eda553babea42c014445358a2985Brian      tempReg = UREG(REG_TYPE_R, temp);  /* make i915 register */
2360235b3252100eda553babea42c014445358a2985Brian
2370235b3252100eda553babea42c014445358a2985Brian      i915_emit_arith( p, A0_MOV,
2380235b3252100eda553babea42c014445358a2985Brian                       tempReg, A0_DEST_CHANNEL_ALL, /* dest reg, writemask */
2390235b3252100eda553babea42c014445358a2985Brian                       0,                            /* saturate */
2400235b3252100eda553babea42c014445358a2985Brian                       coord, 0, 0 );                /* src0, src1, src2 */
2410235b3252100eda553babea42c014445358a2985Brian
2420235b3252100eda553babea42c014445358a2985Brian      /* new src texcoord is tempReg */
2430235b3252100eda553babea42c014445358a2985Brian      coord = tempReg;
2443af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
2453af1f3b9220733f5e3a76fe38fbc397974678234Brian
2463af1f3b9220733f5e3a76fe38fbc397974678234Brian   /* Don't worry about saturate as we only support
2473af1f3b9220733f5e3a76fe38fbc397974678234Brian    */
2483af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (destmask != A0_DEST_CHANNEL_ALL) {
2490235b3252100eda553babea42c014445358a2985Brian      /* if not writing to XYZW... */
2503af1f3b9220733f5e3a76fe38fbc397974678234Brian      uint tmp = i915_get_utemp(p);
2510235b3252100eda553babea42c014445358a2985Brian      i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode );
2523af1f3b9220733f5e3a76fe38fbc397974678234Brian      i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
2530235b3252100eda553babea42c014445358a2985Brian      /* XXX release utemp here? */
2543af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
2553af1f3b9220733f5e3a76fe38fbc397974678234Brian   else {
2563af1f3b9220733f5e3a76fe38fbc397974678234Brian      assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
2574a796264dfc1bdba37a7204f3439a8da213109edVinson Lee      assert(dest == UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
2583af1f3b9220733f5e3a76fe38fbc397974678234Brian
2595d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      /* Output register being oC or oD defines a phase boundary */
2605d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      if (GET_UREG_TYPE(dest) == REG_TYPE_OC ||
2615d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin          GET_UREG_TYPE(dest) == REG_TYPE_OD)
2625d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         p->nr_tex_indirect++;
2635d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin
2645d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      /* Reading from an r# register whose contents depend on output of the
2655d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin       * current phase defines a phase boundary.
2665d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin       */
2675d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      if (GET_UREG_TYPE(coord) == REG_TYPE_R &&
2685d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin          p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
2695d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         p->nr_tex_indirect++;
2703af1f3b9220733f5e3a76fe38fbc397974678234Brian
271c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      if (p->csr< p->program + I915_PROGRAM_SIZE) {
272c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin         *(p->csr++) = (opcode |
2735d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin                        T0_DEST( dest ) |
2745d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin                        T0_SAMPLER( sampler ));
2753af1f3b9220733f5e3a76fe38fbc397974678234Brian
276c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin         *(p->csr++) = T1_ADDRESS_REG( coord );
277c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin         *(p->csr++) = T2_MBZ;
278c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      }
2795d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      else
2805d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         i915_program_error(p, "Out of instructions");
2815d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin
2825d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      if (GET_UREG_TYPE(dest) == REG_TYPE_R)
2835d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
2843af1f3b9220733f5e3a76fe38fbc397974678234Brian
2853af1f3b9220733f5e3a76fe38fbc397974678234Brian      p->nr_tex_insn++;
2863af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
2870235b3252100eda553babea42c014445358a2985Brian
2880235b3252100eda553babea42c014445358a2985Brian   if (temp >= 0)
2890235b3252100eda553babea42c014445358a2985Brian      i915_release_temp(p, temp);
2900235b3252100eda553babea42c014445358a2985Brian
2910235b3252100eda553babea42c014445358a2985Brian   return dest;
2923af1f3b9220733f5e3a76fe38fbc397974678234Brian}
2933af1f3b9220733f5e3a76fe38fbc397974678234Brian
2943af1f3b9220733f5e3a76fe38fbc397974678234Brian
2953af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
2963af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const1f(struct i915_fp_compile * p, float c0)
2973af1f3b9220733f5e3a76fe38fbc397974678234Brian{
298c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian   struct i915_fragment_shader *ifs = p->shader;
2995961732c1b59403b4e736fa354a64d4a0e5d8af2Michal   unsigned reg, idx;
3003af1f3b9220733f5e3a76fe38fbc397974678234Brian
3013af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 0.0)
3023af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO);
3033af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 1.0)
3043af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE);
3053af1f3b9220733f5e3a76fe38fbc397974678234Brian
3063af1f3b9220733f5e3a76fe38fbc397974678234Brian   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
307c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
3083af1f3b9220733f5e3a76fe38fbc397974678234Brian         continue;
3093af1f3b9220733f5e3a76fe38fbc397974678234Brian      for (idx = 0; idx < 4; idx++) {
310c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         if (!(ifs->constant_flags[reg] & (1 << idx)) ||
311c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian             ifs->constants[reg][idx] == c0) {
312c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constants[reg][idx] = c0;
313c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constant_flags[reg] |= 1 << idx;
314c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            if (reg + 1 > ifs->num_constants)
315c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian               ifs->num_constants = reg + 1;
3163af1f3b9220733f5e3a76fe38fbc397974678234Brian            return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE);
3173af1f3b9220733f5e3a76fe38fbc397974678234Brian         }
3183af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
3193af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
3203af1f3b9220733f5e3a76fe38fbc397974678234Brian
3215d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   i915_program_error(p, "i915_emit_const1f: out of constants");
3223af1f3b9220733f5e3a76fe38fbc397974678234Brian   return 0;
3233af1f3b9220733f5e3a76fe38fbc397974678234Brian}
3243af1f3b9220733f5e3a76fe38fbc397974678234Brian
3253af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
3263af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
3273af1f3b9220733f5e3a76fe38fbc397974678234Brian{
328c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian   struct i915_fragment_shader *ifs = p->shader;
3295961732c1b59403b4e736fa354a64d4a0e5d8af2Michal   unsigned reg, idx;
3303af1f3b9220733f5e3a76fe38fbc397974678234Brian
3313af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 0.0)
3323af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W);
3333af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 1.0)
3343af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W);
3353af1f3b9220733f5e3a76fe38fbc397974678234Brian
3363af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c1 == 0.0)
3373af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W);
3383af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c1 == 1.0)
3393af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
3403af1f3b9220733f5e3a76fe38fbc397974678234Brian
341c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   // XXX emit swizzle here for 0, 1, -1 and any combination thereof
342c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   // we can use swizzle + neg for that
3433af1f3b9220733f5e3a76fe38fbc397974678234Brian   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
344c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      if (ifs->constant_flags[reg] == 0xf ||
345c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
3463af1f3b9220733f5e3a76fe38fbc397974678234Brian         continue;
3473af1f3b9220733f5e3a76fe38fbc397974678234Brian      for (idx = 0; idx < 3; idx++) {
348c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         if (!(ifs->constant_flags[reg] & (3 << idx))) {
349c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constants[reg][idx + 0] = c0;
350c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constants[reg][idx + 1] = c1;
351c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constant_flags[reg] |= 3 << idx;
352c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            if (reg + 1 > ifs->num_constants)
353c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian               ifs->num_constants = reg + 1;
354c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian            return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE);
3553af1f3b9220733f5e3a76fe38fbc397974678234Brian         }
3563af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
3573af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
3583af1f3b9220733f5e3a76fe38fbc397974678234Brian
3595d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   i915_program_error(p, "i915_emit_const2f: out of constants");
3603af1f3b9220733f5e3a76fe38fbc397974678234Brian   return 0;
3613af1f3b9220733f5e3a76fe38fbc397974678234Brian}
3623af1f3b9220733f5e3a76fe38fbc397974678234Brian
3633af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
3643af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const4f(struct i915_fp_compile * p,
3653af1f3b9220733f5e3a76fe38fbc397974678234Brian                  float c0, float c1, float c2, float c3)
3663af1f3b9220733f5e3a76fe38fbc397974678234Brian{
367c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian   struct i915_fragment_shader *ifs = p->shader;
3685961732c1b59403b4e736fa354a64d4a0e5d8af2Michal   unsigned reg;
3693af1f3b9220733f5e3a76fe38fbc397974678234Brian
3705d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   // XXX emit swizzle here for 0, 1, -1 and any combination thereof
3715d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   // we can use swizzle + neg for that
3725d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   printf("const %f %f %f %f\n",c0,c1,c2,c3);
3733af1f3b9220733f5e3a76fe38fbc397974678234Brian   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
374c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      if (ifs->constant_flags[reg] == 0xf &&
375c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][0] == c0 &&
376c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][1] == c1 &&
377c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][2] == c2 &&
378c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][3] == c3) {
3793af1f3b9220733f5e3a76fe38fbc397974678234Brian         return UREG(REG_TYPE_CONST, reg);
3803af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
381c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      else if (ifs->constant_flags[reg] == 0) {
382c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian
383c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][0] = c0;
384c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][1] = c1;
385c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][2] = c2;
386c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][3] = c3;
387c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constant_flags[reg] = 0xf;
388c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         if (reg + 1 > ifs->num_constants)
389c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->num_constants = reg + 1;
3903af1f3b9220733f5e3a76fe38fbc397974678234Brian         return UREG(REG_TYPE_CONST, reg);
3913af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
3923af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
3933af1f3b9220733f5e3a76fe38fbc397974678234Brian
3945d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   i915_program_error(p, "i915_emit_const4f: out of constants");
3953af1f3b9220733f5e3a76fe38fbc397974678234Brian   return 0;
3963af1f3b9220733f5e3a76fe38fbc397974678234Brian}
3973af1f3b9220733f5e3a76fe38fbc397974678234Brian
3983af1f3b9220733f5e3a76fe38fbc397974678234Brian
3993af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
4003af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const4fv(struct i915_fp_compile * p, const float * c)
4013af1f3b9220733f5e3a76fe38fbc397974678234Brian{
4023af1f3b9220733f5e3a76fe38fbc397974678234Brian   return i915_emit_const4f(p, c[0], c[1], c[2], c[3]);
4033af1f3b9220733f5e3a76fe38fbc397974678234Brian}
404