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 333af1f3b9220733f5e3a76fe38fbc397974678234Brianuint 343af1f3b9220733f5e3a76fe38fbc397974678234Briani915_get_temp(struct i915_fp_compile *p) 353af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 363af1f3b9220733f5e3a76fe38fbc397974678234Brian int bit = ffs(~p->temp_flag); 373af1f3b9220733f5e3a76fe38fbc397974678234Brian if (!bit) { 385d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin i915_program_error(p, "i915_get_temp: out of temporaries"); 393af1f3b9220733f5e3a76fe38fbc397974678234Brian return 0; 403af1f3b9220733f5e3a76fe38fbc397974678234Brian } 413af1f3b9220733f5e3a76fe38fbc397974678234Brian 423af1f3b9220733f5e3a76fe38fbc397974678234Brian p->temp_flag |= 1 << (bit - 1); 430235b3252100eda553babea42c014445358a2985Brian return bit - 1; 443af1f3b9220733f5e3a76fe38fbc397974678234Brian} 453af1f3b9220733f5e3a76fe38fbc397974678234Brian 463af1f3b9220733f5e3a76fe38fbc397974678234Brian 470235b3252100eda553babea42c014445358a2985Brianstatic void 480235b3252100eda553babea42c014445358a2985Briani915_release_temp(struct i915_fp_compile *p, int reg) 490235b3252100eda553babea42c014445358a2985Brian{ 500235b3252100eda553babea42c014445358a2985Brian p->temp_flag &= ~(1 << reg); 510235b3252100eda553babea42c014445358a2985Brian} 520235b3252100eda553babea42c014445358a2985Brian 530235b3252100eda553babea42c014445358a2985Brian 540235b3252100eda553babea42c014445358a2985Brian/** 550235b3252100eda553babea42c014445358a2985Brian * Get unpreserved temporary, a temp whose value is not preserved between 560235b3252100eda553babea42c014445358a2985Brian * PS program phases. 570235b3252100eda553babea42c014445358a2985Brian */ 583af1f3b9220733f5e3a76fe38fbc397974678234Brianuint 593af1f3b9220733f5e3a76fe38fbc397974678234Briani915_get_utemp(struct i915_fp_compile * p) 603af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 613af1f3b9220733f5e3a76fe38fbc397974678234Brian int bit = ffs(~p->utemp_flag); 623af1f3b9220733f5e3a76fe38fbc397974678234Brian if (!bit) { 635d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin i915_program_error(p, "i915_get_utemp: out of temporaries"); 643af1f3b9220733f5e3a76fe38fbc397974678234Brian return 0; 653af1f3b9220733f5e3a76fe38fbc397974678234Brian } 663af1f3b9220733f5e3a76fe38fbc397974678234Brian 673af1f3b9220733f5e3a76fe38fbc397974678234Brian p->utemp_flag |= 1 << (bit - 1); 683af1f3b9220733f5e3a76fe38fbc397974678234Brian return UREG(REG_TYPE_U, (bit - 1)); 693af1f3b9220733f5e3a76fe38fbc397974678234Brian} 703af1f3b9220733f5e3a76fe38fbc397974678234Brian 713af1f3b9220733f5e3a76fe38fbc397974678234Brianvoid 723af1f3b9220733f5e3a76fe38fbc397974678234Briani915_release_utemps(struct i915_fp_compile *p) 733af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 743af1f3b9220733f5e3a76fe38fbc397974678234Brian p->utemp_flag = ~0x7; 753af1f3b9220733f5e3a76fe38fbc397974678234Brian} 763af1f3b9220733f5e3a76fe38fbc397974678234Brian 773af1f3b9220733f5e3a76fe38fbc397974678234Brian 783af1f3b9220733f5e3a76fe38fbc397974678234Brianuint 793af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_decl(struct i915_fp_compile *p, 803af1f3b9220733f5e3a76fe38fbc397974678234Brian uint type, uint nr, uint d0_flags) 813af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 823af1f3b9220733f5e3a76fe38fbc397974678234Brian uint reg = UREG(type, nr); 833af1f3b9220733f5e3a76fe38fbc397974678234Brian 843af1f3b9220733f5e3a76fe38fbc397974678234Brian if (type == REG_TYPE_T) { 853af1f3b9220733f5e3a76fe38fbc397974678234Brian if (p->decl_t & (1 << nr)) 863af1f3b9220733f5e3a76fe38fbc397974678234Brian return reg; 873af1f3b9220733f5e3a76fe38fbc397974678234Brian 883af1f3b9220733f5e3a76fe38fbc397974678234Brian p->decl_t |= (1 << nr); 893af1f3b9220733f5e3a76fe38fbc397974678234Brian } 903af1f3b9220733f5e3a76fe38fbc397974678234Brian else if (type == REG_TYPE_S) { 913af1f3b9220733f5e3a76fe38fbc397974678234Brian if (p->decl_s & (1 << nr)) 923af1f3b9220733f5e3a76fe38fbc397974678234Brian return reg; 933af1f3b9220733f5e3a76fe38fbc397974678234Brian 943af1f3b9220733f5e3a76fe38fbc397974678234Brian p->decl_s |= (1 << nr); 953af1f3b9220733f5e3a76fe38fbc397974678234Brian } 963af1f3b9220733f5e3a76fe38fbc397974678234Brian else 973af1f3b9220733f5e3a76fe38fbc397974678234Brian return reg; 983af1f3b9220733f5e3a76fe38fbc397974678234Brian 99c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin if (p->decl< p->declarations + I915_PROGRAM_SIZE) { 100c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); 101c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin *(p->decl++) = D1_MBZ; 102c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin *(p->decl++) = D2_MBZ; 103c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin } 104c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin else 1055d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin i915_program_error(p, "Out of declarations"); 1063af1f3b9220733f5e3a76fe38fbc397974678234Brian 1073af1f3b9220733f5e3a76fe38fbc397974678234Brian p->nr_decl_insn++; 1083af1f3b9220733f5e3a76fe38fbc397974678234Brian return reg; 1093af1f3b9220733f5e3a76fe38fbc397974678234Brian} 1103af1f3b9220733f5e3a76fe38fbc397974678234Brian 1113af1f3b9220733f5e3a76fe38fbc397974678234Brianuint 1123af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_arith(struct i915_fp_compile * p, 1133af1f3b9220733f5e3a76fe38fbc397974678234Brian uint op, 1143af1f3b9220733f5e3a76fe38fbc397974678234Brian uint dest, 1153af1f3b9220733f5e3a76fe38fbc397974678234Brian uint mask, 1163af1f3b9220733f5e3a76fe38fbc397974678234Brian uint saturate, uint src0, uint src1, uint src2) 1173af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 1183af1f3b9220733f5e3a76fe38fbc397974678234Brian uint c[3]; 1193af1f3b9220733f5e3a76fe38fbc397974678234Brian uint nr_const = 0; 1203af1f3b9220733f5e3a76fe38fbc397974678234Brian 1213af1f3b9220733f5e3a76fe38fbc397974678234Brian assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); 1223af1f3b9220733f5e3a76fe38fbc397974678234Brian dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); 1233af1f3b9220733f5e3a76fe38fbc397974678234Brian assert(dest); 1243af1f3b9220733f5e3a76fe38fbc397974678234Brian 1253af1f3b9220733f5e3a76fe38fbc397974678234Brian if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) 1263af1f3b9220733f5e3a76fe38fbc397974678234Brian c[nr_const++] = 0; 1273af1f3b9220733f5e3a76fe38fbc397974678234Brian if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) 1283af1f3b9220733f5e3a76fe38fbc397974678234Brian c[nr_const++] = 1; 1293af1f3b9220733f5e3a76fe38fbc397974678234Brian if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) 1303af1f3b9220733f5e3a76fe38fbc397974678234Brian c[nr_const++] = 2; 1313af1f3b9220733f5e3a76fe38fbc397974678234Brian 1323af1f3b9220733f5e3a76fe38fbc397974678234Brian /* Recursively call this function to MOV additional const values 1333af1f3b9220733f5e3a76fe38fbc397974678234Brian * into temporary registers. Use utemp registers for this - 1343af1f3b9220733f5e3a76fe38fbc397974678234Brian * currently shouldn't be possible to run out, but keep an eye on 1353af1f3b9220733f5e3a76fe38fbc397974678234Brian * this. 1363af1f3b9220733f5e3a76fe38fbc397974678234Brian */ 1373af1f3b9220733f5e3a76fe38fbc397974678234Brian if (nr_const > 1) { 1383af1f3b9220733f5e3a76fe38fbc397974678234Brian uint s[3], first, i, old_utemp_flag; 1393af1f3b9220733f5e3a76fe38fbc397974678234Brian 1403af1f3b9220733f5e3a76fe38fbc397974678234Brian s[0] = src0; 1413af1f3b9220733f5e3a76fe38fbc397974678234Brian s[1] = src1; 1423af1f3b9220733f5e3a76fe38fbc397974678234Brian s[2] = src2; 1433af1f3b9220733f5e3a76fe38fbc397974678234Brian old_utemp_flag = p->utemp_flag; 1443af1f3b9220733f5e3a76fe38fbc397974678234Brian 1453af1f3b9220733f5e3a76fe38fbc397974678234Brian first = GET_UREG_NR(s[c[0]]); 1463af1f3b9220733f5e3a76fe38fbc397974678234Brian for (i = 1; i < nr_const; i++) { 1473af1f3b9220733f5e3a76fe38fbc397974678234Brian if (GET_UREG_NR(s[c[i]]) != first) { 1483af1f3b9220733f5e3a76fe38fbc397974678234Brian uint tmp = i915_get_utemp(p); 1493af1f3b9220733f5e3a76fe38fbc397974678234Brian 1503af1f3b9220733f5e3a76fe38fbc397974678234Brian i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, 1513af1f3b9220733f5e3a76fe38fbc397974678234Brian s[c[i]], 0, 0); 1523af1f3b9220733f5e3a76fe38fbc397974678234Brian s[c[i]] = tmp; 1533af1f3b9220733f5e3a76fe38fbc397974678234Brian } 1543af1f3b9220733f5e3a76fe38fbc397974678234Brian } 1553af1f3b9220733f5e3a76fe38fbc397974678234Brian 1563af1f3b9220733f5e3a76fe38fbc397974678234Brian src0 = s[0]; 1573af1f3b9220733f5e3a76fe38fbc397974678234Brian src1 = s[1]; 1583af1f3b9220733f5e3a76fe38fbc397974678234Brian src2 = s[2]; 1593af1f3b9220733f5e3a76fe38fbc397974678234Brian p->utemp_flag = old_utemp_flag; /* restore */ 1603af1f3b9220733f5e3a76fe38fbc397974678234Brian } 1613af1f3b9220733f5e3a76fe38fbc397974678234Brian 162c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin if (p->csr< p->program + I915_PROGRAM_SIZE) { 163c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); 164c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); 165c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); 166c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin } 167c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin else 1685d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin i915_program_error(p, "Out of instructions"); 1695d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin 1705d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin if (GET_UREG_TYPE(dest) == REG_TYPE_R) 1715d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect; 1723af1f3b9220733f5e3a76fe38fbc397974678234Brian 1733af1f3b9220733f5e3a76fe38fbc397974678234Brian p->nr_alu_insn++; 1743af1f3b9220733f5e3a76fe38fbc397974678234Brian return dest; 1753af1f3b9220733f5e3a76fe38fbc397974678234Brian} 1763af1f3b9220733f5e3a76fe38fbc397974678234Brian 1770235b3252100eda553babea42c014445358a2985Brian 1780235b3252100eda553babea42c014445358a2985Brian/** 1790235b3252100eda553babea42c014445358a2985Brian * Emit a texture load or texkill instruction. 1800235b3252100eda553babea42c014445358a2985Brian * \param dest the dest i915 register 1810235b3252100eda553babea42c014445358a2985Brian * \param destmask the dest register writemask 1820235b3252100eda553babea42c014445358a2985Brian * \param sampler the i915 sampler register 1830235b3252100eda553babea42c014445358a2985Brian * \param coord the i915 source texcoord operand 1840235b3252100eda553babea42c014445358a2985Brian * \param opcode the instruction opcode 1850235b3252100eda553babea42c014445358a2985Brian */ 1863af1f3b9220733f5e3a76fe38fbc397974678234Brianuint i915_emit_texld( struct i915_fp_compile *p, 187e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin uint dest, 188e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin uint destmask, 189e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin uint sampler, 190e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin uint coord, 191e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin uint opcode, 192e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin uint num_coord ) 1933af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 1940235b3252100eda553babea42c014445358a2985Brian const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord)); 195e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin 1960235b3252100eda553babea42c014445358a2985Brian int temp = -1; 197e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin uint ignore = 0; 198e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin 199e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin /* Eliminate the useless texture coordinates. Otherwise we end up generating 200e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin * a swizzle for no reason below. */ 201e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin switch(num_coord) { 202e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin case 0: 203e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin /* Ignore x */ 204e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin ignore |= (0xf << UREG_CHANNEL_X_SHIFT); 205e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin case 1: 206e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin /* Ignore y */ 207e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin ignore |= (0xf << UREG_CHANNEL_Y_SHIFT); 208e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin case 2: 209e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin /* Ignore z */ 210e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin ignore |= (0xf << UREG_CHANNEL_Z_SHIFT); 211e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin case 3: 212e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin /* Ignore w */ 213e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin ignore |= (0xf << UREG_CHANNEL_W_SHIFT); 214e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin } 2150235b3252100eda553babea42c014445358a2985Brian 21663dbd3fefba93ccfb984ed589795f6784bb4d1e3Stéphane Marchesin if ( (coord & ~ignore ) != (k & ~ignore) ) { 2170235b3252100eda553babea42c014445358a2985Brian /* texcoord is swizzled or negated. Need to allocate a new temporary 2180235b3252100eda553babea42c014445358a2985Brian * register (a utemp / unpreserved temp) won't do. 2193af1f3b9220733f5e3a76fe38fbc397974678234Brian */ 2200235b3252100eda553babea42c014445358a2985Brian uint tempReg; 2210235b3252100eda553babea42c014445358a2985Brian 2220235b3252100eda553babea42c014445358a2985Brian temp = i915_get_temp(p); /* get temp reg index */ 2230235b3252100eda553babea42c014445358a2985Brian tempReg = UREG(REG_TYPE_R, temp); /* make i915 register */ 2240235b3252100eda553babea42c014445358a2985Brian 2250235b3252100eda553babea42c014445358a2985Brian i915_emit_arith( p, A0_MOV, 2260235b3252100eda553babea42c014445358a2985Brian tempReg, A0_DEST_CHANNEL_ALL, /* dest reg, writemask */ 2270235b3252100eda553babea42c014445358a2985Brian 0, /* saturate */ 2280235b3252100eda553babea42c014445358a2985Brian coord, 0, 0 ); /* src0, src1, src2 */ 2290235b3252100eda553babea42c014445358a2985Brian 2300235b3252100eda553babea42c014445358a2985Brian /* new src texcoord is tempReg */ 2310235b3252100eda553babea42c014445358a2985Brian coord = tempReg; 2323af1f3b9220733f5e3a76fe38fbc397974678234Brian } 2333af1f3b9220733f5e3a76fe38fbc397974678234Brian 2343af1f3b9220733f5e3a76fe38fbc397974678234Brian /* Don't worry about saturate as we only support 2353af1f3b9220733f5e3a76fe38fbc397974678234Brian */ 2363af1f3b9220733f5e3a76fe38fbc397974678234Brian if (destmask != A0_DEST_CHANNEL_ALL) { 2370235b3252100eda553babea42c014445358a2985Brian /* if not writing to XYZW... */ 2383af1f3b9220733f5e3a76fe38fbc397974678234Brian uint tmp = i915_get_utemp(p); 239e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode, num_coord ); 2403af1f3b9220733f5e3a76fe38fbc397974678234Brian i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); 2410235b3252100eda553babea42c014445358a2985Brian /* XXX release utemp here? */ 2423af1f3b9220733f5e3a76fe38fbc397974678234Brian } 2433af1f3b9220733f5e3a76fe38fbc397974678234Brian else { 2443af1f3b9220733f5e3a76fe38fbc397974678234Brian assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); 2454a796264dfc1bdba37a7204f3439a8da213109edVinson Lee assert(dest == UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); 2463af1f3b9220733f5e3a76fe38fbc397974678234Brian 2475d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin /* Output register being oC or oD defines a phase boundary */ 2485d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin if (GET_UREG_TYPE(dest) == REG_TYPE_OC || 2495d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin GET_UREG_TYPE(dest) == REG_TYPE_OD) 2505d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin p->nr_tex_indirect++; 2515d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin 2525d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin /* Reading from an r# register whose contents depend on output of the 2535d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin * current phase defines a phase boundary. 2545d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin */ 2555d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin if (GET_UREG_TYPE(coord) == REG_TYPE_R && 2565d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect) 2575d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin p->nr_tex_indirect++; 2583af1f3b9220733f5e3a76fe38fbc397974678234Brian 259c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin if (p->csr< p->program + I915_PROGRAM_SIZE) { 260c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin *(p->csr++) = (opcode | 2615d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin T0_DEST( dest ) | 2625d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin T0_SAMPLER( sampler )); 2633af1f3b9220733f5e3a76fe38fbc397974678234Brian 264c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin *(p->csr++) = T1_ADDRESS_REG( coord ); 265c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin *(p->csr++) = T2_MBZ; 266c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin } 2675d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin else 2685d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin i915_program_error(p, "Out of instructions"); 2695d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin 2705d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin if (GET_UREG_TYPE(dest) == REG_TYPE_R) 2715d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect; 2723af1f3b9220733f5e3a76fe38fbc397974678234Brian 2733af1f3b9220733f5e3a76fe38fbc397974678234Brian p->nr_tex_insn++; 2743af1f3b9220733f5e3a76fe38fbc397974678234Brian } 2750235b3252100eda553babea42c014445358a2985Brian 2760235b3252100eda553babea42c014445358a2985Brian if (temp >= 0) 2770235b3252100eda553babea42c014445358a2985Brian i915_release_temp(p, temp); 2780235b3252100eda553babea42c014445358a2985Brian 2790235b3252100eda553babea42c014445358a2985Brian return dest; 2803af1f3b9220733f5e3a76fe38fbc397974678234Brian} 2813af1f3b9220733f5e3a76fe38fbc397974678234Brian 2823af1f3b9220733f5e3a76fe38fbc397974678234Brian 2833af1f3b9220733f5e3a76fe38fbc397974678234Brianuint 2843af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const1f(struct i915_fp_compile * p, float c0) 2853af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 286c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian struct i915_fragment_shader *ifs = p->shader; 2875961732c1b59403b4e736fa354a64d4a0e5d8af2Michal unsigned reg, idx; 2883af1f3b9220733f5e3a76fe38fbc397974678234Brian 2893af1f3b9220733f5e3a76fe38fbc397974678234Brian if (c0 == 0.0) 2903af1f3b9220733f5e3a76fe38fbc397974678234Brian return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); 2913af1f3b9220733f5e3a76fe38fbc397974678234Brian if (c0 == 1.0) 2923af1f3b9220733f5e3a76fe38fbc397974678234Brian return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); 2933af1f3b9220733f5e3a76fe38fbc397974678234Brian 2943af1f3b9220733f5e3a76fe38fbc397974678234Brian for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { 295c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER) 2963af1f3b9220733f5e3a76fe38fbc397974678234Brian continue; 2973af1f3b9220733f5e3a76fe38fbc397974678234Brian for (idx = 0; idx < 4; idx++) { 298c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian if (!(ifs->constant_flags[reg] & (1 << idx)) || 299c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][idx] == c0) { 300c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][idx] = c0; 301c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constant_flags[reg] |= 1 << idx; 302c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian if (reg + 1 > ifs->num_constants) 303c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->num_constants = reg + 1; 3043af1f3b9220733f5e3a76fe38fbc397974678234Brian return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); 3053af1f3b9220733f5e3a76fe38fbc397974678234Brian } 3063af1f3b9220733f5e3a76fe38fbc397974678234Brian } 3073af1f3b9220733f5e3a76fe38fbc397974678234Brian } 3083af1f3b9220733f5e3a76fe38fbc397974678234Brian 3095d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin i915_program_error(p, "i915_emit_const1f: out of constants"); 3103af1f3b9220733f5e3a76fe38fbc397974678234Brian return 0; 3113af1f3b9220733f5e3a76fe38fbc397974678234Brian} 3123af1f3b9220733f5e3a76fe38fbc397974678234Brian 3133af1f3b9220733f5e3a76fe38fbc397974678234Brianuint 3143af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) 3153af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 316c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian struct i915_fragment_shader *ifs = p->shader; 3175961732c1b59403b4e736fa354a64d4a0e5d8af2Michal unsigned reg, idx; 3183af1f3b9220733f5e3a76fe38fbc397974678234Brian 3193af1f3b9220733f5e3a76fe38fbc397974678234Brian if (c0 == 0.0) 3203af1f3b9220733f5e3a76fe38fbc397974678234Brian return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); 3213af1f3b9220733f5e3a76fe38fbc397974678234Brian if (c0 == 1.0) 3223af1f3b9220733f5e3a76fe38fbc397974678234Brian return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); 3233af1f3b9220733f5e3a76fe38fbc397974678234Brian 3243af1f3b9220733f5e3a76fe38fbc397974678234Brian if (c1 == 0.0) 3253af1f3b9220733f5e3a76fe38fbc397974678234Brian return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); 3263af1f3b9220733f5e3a76fe38fbc397974678234Brian if (c1 == 1.0) 3273af1f3b9220733f5e3a76fe38fbc397974678234Brian return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); 3283af1f3b9220733f5e3a76fe38fbc397974678234Brian 329c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin // XXX emit swizzle here for 0, 1, -1 and any combination thereof 330c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin // we can use swizzle + neg for that 3313af1f3b9220733f5e3a76fe38fbc397974678234Brian for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { 332c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian if (ifs->constant_flags[reg] == 0xf || 333c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constant_flags[reg] == I915_CONSTFLAG_USER) 3343af1f3b9220733f5e3a76fe38fbc397974678234Brian continue; 3353af1f3b9220733f5e3a76fe38fbc397974678234Brian for (idx = 0; idx < 3; idx++) { 336c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian if (!(ifs->constant_flags[reg] & (3 << idx))) { 337c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][idx + 0] = c0; 338c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][idx + 1] = c1; 339c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constant_flags[reg] |= 3 << idx; 340c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian if (reg + 1 > ifs->num_constants) 341c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->num_constants = reg + 1; 342c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE); 3433af1f3b9220733f5e3a76fe38fbc397974678234Brian } 3443af1f3b9220733f5e3a76fe38fbc397974678234Brian } 3453af1f3b9220733f5e3a76fe38fbc397974678234Brian } 3463af1f3b9220733f5e3a76fe38fbc397974678234Brian 3475d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin i915_program_error(p, "i915_emit_const2f: out of constants"); 3483af1f3b9220733f5e3a76fe38fbc397974678234Brian return 0; 3493af1f3b9220733f5e3a76fe38fbc397974678234Brian} 3503af1f3b9220733f5e3a76fe38fbc397974678234Brian 3513af1f3b9220733f5e3a76fe38fbc397974678234Brianuint 3523af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const4f(struct i915_fp_compile * p, 3533af1f3b9220733f5e3a76fe38fbc397974678234Brian float c0, float c1, float c2, float c3) 3543af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 355c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian struct i915_fragment_shader *ifs = p->shader; 3565961732c1b59403b4e736fa354a64d4a0e5d8af2Michal unsigned reg; 3573af1f3b9220733f5e3a76fe38fbc397974678234Brian 3585d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin // XXX emit swizzle here for 0, 1, -1 and any combination thereof 3595d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin // we can use swizzle + neg for that 3603af1f3b9220733f5e3a76fe38fbc397974678234Brian for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { 361c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian if (ifs->constant_flags[reg] == 0xf && 362c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][0] == c0 && 363c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][1] == c1 && 364c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][2] == c2 && 365c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][3] == c3) { 3663af1f3b9220733f5e3a76fe38fbc397974678234Brian return UREG(REG_TYPE_CONST, reg); 3673af1f3b9220733f5e3a76fe38fbc397974678234Brian } 368c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian else if (ifs->constant_flags[reg] == 0) { 369c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian 370c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][0] = c0; 371c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][1] = c1; 372c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][2] = c2; 373c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constants[reg][3] = c3; 374c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->constant_flags[reg] = 0xf; 375c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian if (reg + 1 > ifs->num_constants) 376c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian ifs->num_constants = reg + 1; 3773af1f3b9220733f5e3a76fe38fbc397974678234Brian return UREG(REG_TYPE_CONST, reg); 3783af1f3b9220733f5e3a76fe38fbc397974678234Brian } 3793af1f3b9220733f5e3a76fe38fbc397974678234Brian } 3803af1f3b9220733f5e3a76fe38fbc397974678234Brian 3815d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin i915_program_error(p, "i915_emit_const4f: out of constants"); 3823af1f3b9220733f5e3a76fe38fbc397974678234Brian return 0; 3833af1f3b9220733f5e3a76fe38fbc397974678234Brian} 3843af1f3b9220733f5e3a76fe38fbc397974678234Brian 3853af1f3b9220733f5e3a76fe38fbc397974678234Brian 3863af1f3b9220733f5e3a76fe38fbc397974678234Brianuint 3873af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const4fv(struct i915_fp_compile * p, const float * c) 3883af1f3b9220733f5e3a76fe38fbc397974678234Brian{ 3893af1f3b9220733f5e3a76fe38fbc397974678234Brian return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); 3903af1f3b9220733f5e3a76fe38fbc397974678234Brian} 391