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