brw_wm_fp.c revision 88451b04e9cd39db9cc9315aaf69e074614f22f9
19f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/* 29f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Copyright (C) Intel Corp. 2006. All Rights Reserved. 39f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 49f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt develop this 3D driver. 59f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 69f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Permission is hereby granted, free of charge, to any person obtaining 79f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt a copy of this software and associated documentation files (the 89f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "Software"), to deal in the Software without restriction, including 99f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt without limitation the rights to use, copy, modify, merge, publish, 109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt distribute, sublicense, and/or sell copies of the Software, and to 119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt permit persons to whom the Software is furnished to do so, subject to 129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt the following conditions: 139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt The above copyright notice and this permission notice (including the 159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt next paragraph) shall be included in all copies or substantial 169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt portions of the Software. 179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt **********************************************************************/ 279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* 289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Authors: 299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Keith Whitwell <keith@tungstengraphics.com> 309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "glheader.h" 349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "macros.h" 359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "enums.h" 369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_context.h" 379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_wm.h" 389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_util.h" 399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 40064ae479a770bf434958d673baf6f7530f642697Brian#include "shader/prog_parameter.h" 41064ae479a770bf434958d673baf6f7530f642697Brian#include "shader/prog_print.h" 42064ae479a770bf434958d673baf6f7530f642697Brian#include "shader/prog_statevars.h" 43064ae479a770bf434958d673baf6f7530f642697Brian 449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS 469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define X 0 489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define Y 1 499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define Z 2 509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define W 3 519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic const char *wm_opcode_strings[] = { 549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "PIXELXY", 559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "DELTAXY", 569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "PIXELW", 579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "LINTERP", 589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "PINTERP", 599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "CINTERP", 609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "WPOSXY", 619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "FB_WRITE" 629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}; 639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 64e7b0ec9ae79d4ec4aba402b9124fde55d914da92Keith Whitwell#if 0 659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic const char *wm_file_strings[] = { 669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "PAYLOAD" 679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}; 68e7b0ec9ae79d4ec4aba402b9124fde55d914da92Keith Whitwell#endif 699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*********************************************************************** 729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Source regs 739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_reg(GLuint file, GLuint idx) 769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register reg; 789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.File = file; 799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.Index = idx; 809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.Swizzle = SWIZZLE_NOOP; 819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.RelAddr = 0; 829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.NegateBase = 0; 839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.Abs = 0; 849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.NegateAbs = 0; 859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return reg; 869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_reg_from_dst(struct prog_dst_register dst) 899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return src_reg(dst.File, dst.Index); 919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_undef( void ) 949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return src_reg(PROGRAM_UNDEFINED, 0); 969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic GLboolean src_is_undef(struct prog_src_register src) 999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return src.File == PROGRAM_UNDEFINED; 1019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_swizzle( struct prog_src_register reg, int x, int y, int z, int w ) 1049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.Swizzle = MAKE_SWIZZLE4(x,y,z,w); 1069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return reg; 1079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_swizzle1( struct prog_src_register reg, int x ) 1109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return src_swizzle(reg, x, x, x, x); 1129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*********************************************************************** 1169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Dest regs 1179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 1189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_reg(GLuint file, GLuint idx) 1209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register reg; 1229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.File = file; 1239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.Index = idx; 1249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.WriteMask = WRITEMASK_XYZW; 1259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.CondMask = 0; 1269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.CondSwizzle = 0; 1279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.pad = 0; 1289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.CondSrc = 0; 1299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return reg; 1309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_mask( struct prog_dst_register reg, int mask ) 1339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt reg.WriteMask &= mask; 1359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return reg; 1369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_undef( void ) 1399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return dst_reg(PROGRAM_UNDEFINED, 0); 1419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register get_temp( struct brw_wm_compile *c ) 1469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt int bit = ffs( ~c->fp_temp ); 1489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (!bit) { 1509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt _mesa_printf("%s: out of temporaries\n", __FILE__); 1519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt exit(1); 1529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 1539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->fp_temp |= 1<<(bit-1); 1559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return dst_reg(PROGRAM_TEMPORARY, FIRST_INTERNAL_TEMP+(bit-1)); 1569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void release_temp( struct brw_wm_compile *c, struct prog_dst_register temp ) 1609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->fp_temp &= ~1<<(temp.Index + 1 - FIRST_INTERNAL_TEMP); 1629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*********************************************************************** 1669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Instructions 1679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 1689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction *get_fp_inst(struct brw_wm_compile *c) 1709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return &c->prog_instructions[c->nr_fp_insns++]; 1729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction *emit_insn(struct brw_wm_compile *c, 1759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt const struct prog_instruction *inst0) 1769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_instruction *inst = get_fp_inst(c); 1789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt *inst = *inst0; 1799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return inst; 1809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 1819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction * emit_op(struct brw_wm_compile *c, 1839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint op, 1849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register dest, 1859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint saturate, 1869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint tex_src_unit, 1879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint tex_src_target, 1889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register src0, 1899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register src1, 1909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register src2 ) 1919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 1929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_instruction *inst = get_fp_inst(c); 1939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt memset(inst, 0, sizeof(*inst)); 1959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 1969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->Opcode = op; 1979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->DstReg = dest; 1989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SaturateMode = saturate; 1999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->TexSrcUnit = tex_src_unit; 2009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->TexSrcTarget = tex_src_target; 2019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SrcReg[0] = src0; 2029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SrcReg[1] = src1; 2039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SrcReg[2] = src2; 2049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return inst; 2069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 2079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*********************************************************************** 2129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Special instructions for interpolation and other tasks 2139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 2149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_xy( struct brw_wm_compile *c ) 2169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 2179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (src_is_undef(c->pixel_xy)) { 2189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register pixel_xy = get_temp(c); 2199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH); 2209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* Emit the out calculations, and hold onto the results. Use 2239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * two instructions as a temporary is required. 2249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 2259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* pixel_xy.xy = PIXELXY payload[0]; 2269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 2279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 2289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WM_PIXELXY, 2299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(pixel_xy, WRITEMASK_XY), 2309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 2319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt payload_r0_depth, 2329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 2339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 2349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->pixel_xy = src_reg_from_dst(pixel_xy); 2369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 2379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return c->pixel_xy; 2399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 2409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_delta_xy( struct brw_wm_compile *c ) 2429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 2439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (src_is_undef(c->delta_xy)) { 2449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register delta_xy = get_temp(c); 2459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register pixel_xy = get_pixel_xy(c); 2469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH); 2479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* deltas.xy = DELTAXY pixel_xy, payload[0] 2499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 2509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 2519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WM_DELTAXY, 2529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(delta_xy, WRITEMASK_XY), 2539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 2549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt pixel_xy, 2559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt payload_r0_depth, 2569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 2579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->delta_xy = src_reg_from_dst(delta_xy); 2599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 2609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return c->delta_xy; 2629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 2639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_w( struct brw_wm_compile *c ) 2659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 2669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (src_is_undef(c->pixel_w)) { 2679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register pixel_w = get_temp(c); 2689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register deltas = get_delta_xy(c); 2699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register interp_wpos = src_reg(PROGRAM_PAYLOAD, FRAG_ATTRIB_WPOS); 2709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* deltas.xyw = DELTAS2 deltas.xy, payload.interp_wpos.x 2739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 2749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 2759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WM_PIXELW, 2769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(pixel_w, WRITEMASK_W), 2779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 2789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt interp_wpos, 2799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt deltas, 2809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 2819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->pixel_w = src_reg_from_dst(pixel_w); 2849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 2859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return c->pixel_w; 2879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 2889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void emit_interp( struct brw_wm_compile *c, 2909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint idx ) 2919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 2929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx); 2939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx); 2949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register deltas = get_delta_xy(c); 2959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register arg2; 2969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint opcode; 2979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 2989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* Need to use PINTERP on attributes which have been 2999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * multiplied by 1/W in the SF program, and LINTERP on those 3009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * which have not: 3019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 3029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt switch (idx) { 3039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case FRAG_ATTRIB_WPOS: 3049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt opcode = WM_LINTERP; 3059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt arg2 = src_undef(); 3069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* Have to treat wpos.xy specially: 3089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 3099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 3109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WM_WPOSXY, 3119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(dst, WRITEMASK_XY), 3129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 3139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt get_pixel_xy(c), 3149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 3159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 3169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst = dst_mask(dst, WRITEMASK_ZW); 3189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw 3209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 3219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 3229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WM_LINTERP, 3239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst, 3249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 3259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt interp, 3269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt deltas, 3279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt arg2); 3289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 3299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case FRAG_ATTRIB_COL0: 3309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case FRAG_ATTRIB_COL1: 3319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (c->key.flat_shade) { 3329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 3339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WM_CINTERP, 3349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst, 3359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 3369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt interp, 3379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 3389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 3399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 3409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt else { 3419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 3429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WM_LINTERP, 3439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst, 3449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 3459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt interp, 3469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt deltas, 3479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 3489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 3499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 3509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt default: 3519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 3529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WM_PINTERP, 3539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst, 3549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 3559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt interp, 3569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt deltas, 3579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt get_pixel_w(c)); 3589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 3599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 3609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->fp_interp_emitted |= 1<<idx; 3629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 3639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*********************************************************************** 3669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Hacks to extend the program parameter and constant lists. 3679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 3689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/* Add the fog parameters to the parameter list of the original 3709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * program, rather than creating a new list. Doesn't really do any 3719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * harm and it's not as if the parameter handling isn't a big hack 3729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * anyway. 3739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 374064ae479a770bf434958d673baf6f7530f642697Brianstatic struct prog_src_register search_or_add_param5(struct brw_wm_compile *c, 375064ae479a770bf434958d673baf6f7530f642697Brian GLint s0, 376064ae479a770bf434958d673baf6f7530f642697Brian GLint s1, 377064ae479a770bf434958d673baf6f7530f642697Brian GLint s2, 378064ae479a770bf434958d673baf6f7530f642697Brian GLint s3, 379064ae479a770bf434958d673baf6f7530f642697Brian GLint s4) 3809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 3819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters; 382064ae479a770bf434958d673baf6f7530f642697Brian gl_state_index tokens[STATE_LENGTH]; 3839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint idx; 3849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tokens[0] = s0; 3859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tokens[1] = s1; 3869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tokens[2] = s2; 3879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tokens[3] = s3; 3889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tokens[4] = s4; 3899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt for (idx = 0; idx < paramList->NumParameters; idx++) { 3919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (paramList->Parameters[idx].Type == PROGRAM_STATE_VAR && 3929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt memcmp(paramList->Parameters[idx].StateIndexes, tokens, sizeof(tokens)) == 0) 3939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return src_reg(PROGRAM_STATE_VAR, idx); 3949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 3959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt idx = _mesa_add_state_reference( paramList, tokens ); 3979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 3989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* Recalculate state dependency: 3999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 40001b7f2ab2e7a9291bf54475e816e88804ee7cd53Xiang, Haihao c->fp->param_state = paramList->StateFlags; 4019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return src_reg(PROGRAM_STATE_VAR, idx); 4039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 4049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c, 4079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLfloat s0, 4089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLfloat s1, 4099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLfloat s2, 4109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLfloat s3) 4119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 4129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters; 4139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLfloat values[4]; 4149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint idx; 415064ae479a770bf434958d673baf6f7530f642697Brian GLuint swizzle; 4169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt values[0] = s0; 4189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt values[1] = s1; 4199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt values[2] = s2; 4209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt values[3] = s3; 4219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* Have to search, otherwise multiple compilations will each grow 4239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * the parameter list. 4249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 4259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt for (idx = 0; idx < paramList->NumParameters; idx++) { 4269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (paramList->Parameters[idx].Type == PROGRAM_CONSTANT && 4279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt memcmp(paramList->ParameterValues[idx], values, sizeof(values)) == 0) 4289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* XXX: this mimics the mesa bug which puts all constants and 4309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * parameters into the "PROGRAM_STATE_VAR" category: 4319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 4329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return src_reg(PROGRAM_STATE_VAR, idx); 4339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 4349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 435064ae479a770bf434958d673baf6f7530f642697Brian idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle ); 436064ae479a770bf434958d673baf6f7530f642697Brian /* XXX what about swizzle? */ 4379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return src_reg(PROGRAM_STATE_VAR, idx); 4389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 4399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*********************************************************************** 4439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Expand various instructions here to simpler forms. 4449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 4459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_dst( struct brw_wm_compile *c, 4469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt const struct prog_instruction *inst ) 4479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 4489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register src0 = inst->SrcReg[0]; 4499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register src1 = inst->SrcReg[1]; 4509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register dst = inst->DstReg; 4519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (dst.WriteMask & WRITEMASK_Y) { 4539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* dst.y = mul src0.y, src1.y 4549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 4559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 4569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_MUL, 4579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(dst, WRITEMASK_Y), 4589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SaturateMode, 0, 0, 4599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src0, 4609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src1, 4619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 4629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 4639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (dst.WriteMask & WRITEMASK_XZ) { 4669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint z = GET_SWZ(src0.Swizzle, Z); 4679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* dst.xz = swz src0.1zzz 4699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 4709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 4719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_SWZ, 4729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(dst, WRITEMASK_XZ), 4739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SaturateMode, 0, 0, 4749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle(src0, SWIZZLE_ONE, z, z, z), 4759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 4769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 4779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 4789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (dst.WriteMask & WRITEMASK_W) { 4799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* dst.w = mov src1.w 4809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 4819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 4829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_MOV, 4839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(dst, WRITEMASK_W), 4849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SaturateMode, 0, 0, 4859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src1, 4869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 4879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 4889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 4899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 4909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_lit( struct brw_wm_compile *c, 4939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt const struct prog_instruction *inst ) 4949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 4959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register src0 = inst->SrcReg[0]; 4969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register dst = inst->DstReg; 4979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 4989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (dst.WriteMask & WRITEMASK_XW) { 4999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* dst.xw = swz src0.1111 5009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 5019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 5029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_SWZ, 5039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(dst, WRITEMASK_XW), 5049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 5059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle1(src0, SWIZZLE_ONE), 5069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 5079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 5089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 5099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 5109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 5119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (dst.WriteMask & WRITEMASK_YZ) { 5129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 5139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_LIT, 5149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(dst, WRITEMASK_YZ), 5159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SaturateMode, 0, 0, 5169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src0, 5179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 5189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 5199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 5209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 5219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 5229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_tex( struct brw_wm_compile *c, 5239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt const struct prog_instruction *inst ) 5249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 525e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell struct prog_src_register coord; 526e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell struct prog_dst_register tmpcoord; 527e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell 528e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { 529e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell struct prog_src_register scale = 530064ae479a770bf434958d673baf6f7530f642697Brian search_or_add_param5( c, 531e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell STATE_INTERNAL, 532e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell STATE_TEXRECT_SCALE, 533e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell inst->TexSrcUnit, 534064ae479a770bf434958d673baf6f7530f642697Brian 0,0 ); 535e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell 536e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell tmpcoord = get_temp(c); 537e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell 538e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell /* coord.xy = MUL inst->SrcReg[0], { 1/width, 1/height } 539e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell */ 540e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell emit_op(c, 541e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell OPCODE_MUL, 542e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell tmpcoord, 543e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell 0, 0, 0, 544e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell inst->SrcReg[0], 545e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell scale, 546e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell src_undef()); 547e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell 548e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell coord = src_reg_from_dst(tmpcoord); 549e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell } 550e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell else { 551e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell coord = inst->SrcReg[0]; 552e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell } 553e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell 5549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* Need to emit YUV texture conversions by hand. Probably need to 5559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * do this here - the alternative is in brw_wm_emit.c, but the 5569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * conversion requires allocating a temporary variable which we 5579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * don't have the facility to do that late in the compilation. 5589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 5599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (!(c->key.yuvtex_mask & (1<<inst->TexSrcUnit))) { 5609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 5619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_TEX, 5629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->DstReg, 5639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SaturateMode, 5649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->TexSrcUnit, 5659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->TexSrcTarget, 566e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell coord, 5679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 5689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 5699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 5709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt else { 5719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* 5729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt CONST C0 = { -.5, -.0625, -.5, 1.164 } 5739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt CONST C1 = { 1.596, -0.813, 2.018, -.391 } 5749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt UYV = TEX ... 5759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt UYV.xyz = ADD UYV, C0 5769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt UYV.y = MUL UYV.y, C0.w 5779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt RGB.xyz = MAD UYV.xxz, C1, UYV.y 5789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt RGB.y = MAD UYV.z, C1.w, RGB.y 5799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 5809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register dst = inst->DstReg; 5819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register src0 = inst->SrcReg[0]; 5829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register tmp = get_temp(c); 5839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register tmpsrc = src_reg_from_dst(tmp); 5849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register C0 = search_or_add_const4f( c, -.5, -.0625, -.5, 1.164 ); 5859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register C1 = search_or_add_const4f( c, 1.596, -0.813, 2.018, -.391 ); 5869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 5879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* tmp = TEX ... 5889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 5899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 5909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_TEX, 5919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tmp, 5929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->SaturateMode, 5939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->TexSrcUnit, 5949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt inst->TexSrcTarget, 5959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src0, 5969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 5979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 5989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 5999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* tmp.xyz = ADD TMP, C0 6009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 6019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 6029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_ADD, 6039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(tmp, WRITEMASK_XYZ), 6049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 6059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tmpsrc, 6069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt C0, 6079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 6089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* YUV.y = MUL YUV.y, C0.w 6109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 6119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 6129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_MUL, 6139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(tmp, WRITEMASK_Y), 6149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 6159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tmpsrc, 6169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle1(C0, W), 6179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 6189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* RGB.xyz = MAD YUV.xxz, C1, YUV.y 6209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 6219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 6229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_MAD, 6239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(dst, WRITEMASK_XYZ), 6249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 6259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle(tmpsrc, X,X,Z,Z), 6269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt C1, 6279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle1(tmpsrc, Y)); 6289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* RGB.y = MAD YUV.z, C1.w, RGB.y 6309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 6319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 6329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_MAD, 6339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(dst, WRITEMASK_Y), 6349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 6359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle1(tmpsrc, Z), 6369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle1(C1, W), 6379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle1(src_reg_from_dst(dst), Y)); 638e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell 639e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell release_temp(c, tmp); 6409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 641e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell 642e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell if (inst->TexSrcTarget == GL_TEXTURE_RECTANGLE_NV) 643e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell release_temp(c, tmpcoord); 6449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 6459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic GLboolean projtex( struct brw_wm_compile *c, 6489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt const struct prog_instruction *inst ) 6499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 6509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register src = inst->SrcReg[0]; 6519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* Only try to detect the simplest cases. Could detect (later) 6539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * cases where we are trying to emit code like RCP {1.0}, MUL x, 6549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * {1.0}, and so on. 6559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * 6569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * More complex cases than this typically only arise from 6579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * user-provided fragment programs anyway: 6589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 6599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) 6609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return 0; /* ut2004 gun rendering !?! */ 6619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt else if (src.File == PROGRAM_INPUT && 6629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GET_SWZ(src.Swizzle, W) == W && 66388451b04e9cd39db9cc9315aaf69e074614f22f9Xiang, Haihao (c->key.projtex_mask & (1<<(src.Index + FRAG_ATTRIB_WPOS - FRAG_ATTRIB_TEX0))) == 0) 6649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return 0; 6659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt else 6669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return 1; 6679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 6689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_txp( struct brw_wm_compile *c, 6719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt const struct prog_instruction *inst ) 6729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 6739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register src0 = inst->SrcReg[0]; 6749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (projtex(c, inst)) { 6769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register tmp = get_temp(c); 6779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_instruction tmp_inst; 6789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* tmp0.w = RCP inst.arg[0][3] 6809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 6819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 6829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_RCP, 6839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(tmp, WRITEMASK_W), 6849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 6859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)), 6869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef(), 6879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 6889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* tmp0.xyz = MUL inst.arg[0], tmp0.wwww 6909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 6919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 6929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_MUL, 6939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(tmp, WRITEMASK_XYZ), 6949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 6959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src0, 6969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_swizzle1(src_reg_from_dst(tmp), W), 6979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_undef()); 6989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 6999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* dst = precalc(TEX tmp0) 7009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 7019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tmp_inst = *inst; 7029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt tmp_inst.SrcReg[0] = src_reg_from_dst(tmp); 7039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt precalc_tex(c, &tmp_inst); 7049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt release_temp(c, tmp); 7069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 7079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt else 7089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt { 7099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* dst = precalc(TEX src0) 7109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 7119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt precalc_tex(c, inst); 7129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 7139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 7149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*********************************************************************** 7209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Add instructions to perform fog blending 7219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 7229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void fog_blend( struct brw_wm_compile *c, 7249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register fog_factor ) 7259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 7269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); 727064ae479a770bf434958d673baf6f7530f642697Brian struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 ); 7289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */ 7309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 7329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OPCODE_LRP, 7339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(outcolor, WRITEMASK_XYZ), 7349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 7359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt fog_factor, 7369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt src_reg_from_dst(outcolor), 7379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt fogcolor); 7389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 7399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/* This one is simple - just take the interpolated fog coordinate and 7439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * use it as the fog blend factor. 7449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 7459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void fog_interpolated( struct brw_wm_compile *c ) 7469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 7479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register fogc = src_reg(PROGRAM_INPUT, FRAG_ATTRIB_FOGC); 7489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (!(c->fp_interp_emitted & (1<<FRAG_ATTRIB_FOGC))) 7509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_interp(c, FRAG_ATTRIB_FOGC); 7519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt fog_blend( c, src_swizzle1(fogc, GET_SWZ(fogc.Swizzle,X))); 7539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 7549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void emit_fog( struct brw_wm_compile *c ) 7569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 7579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (!c->fp->program.FogOption) 7589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt return; 7599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (1) 7619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt fog_interpolated( c ); 7629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt else { 7639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* TODO: per-pixel fog */ 7649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt assert(0); 7659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 7669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 7679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void emit_fb_write( struct brw_wm_compile *c ) 7699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 7709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); 7719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH); 7729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPR); 7739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_op(c, 7759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WM_FB_WRITE, 7769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt dst_mask(dst_undef(),0), 7779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 0, 0, 0, 7789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt outcolor, 7799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt payload_r0_depth, 7809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt outdepth); 7819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 7829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*********************************************************************** 7879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Emit INTERP instructions ahead of first use of each attrib. 7889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 7899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void validate_src_regs( struct brw_wm_compile *c, 7919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt const struct prog_instruction *inst ) 7929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 7939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint nr_args = brw_wm_nr_args( inst->Opcode ); 7949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint i; 7959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 7969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt for (i = 0; i < nr_args; i++) { 7979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (inst->SrcReg[i].File == PROGRAM_INPUT) { 7989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint idx = inst->SrcReg[i].Index; 7999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (!(c->fp_interp_emitted & (1<<idx))) { 8009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_interp(c, idx); 8019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 8029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 8039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 8049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 8059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 808cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwellstatic void print_insns( const struct prog_instruction *insn, 809cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell GLuint nr ) 810cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell{ 811cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell GLuint i; 812cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell for (i = 0; i < nr; i++, insn++) { 813cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell _mesa_printf("%3d: ", i); 814cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell if (insn->Opcode < MAX_OPCODE) 815cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell _mesa_print_instruction(insn); 816cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell else if (insn->Opcode < MAX_WM_OPCODE) { 817cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell GLuint idx = insn->Opcode - MAX_OPCODE; 818cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell 819cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell _mesa_print_alu_instruction(insn, 820cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell wm_opcode_strings[idx], 821cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell 3); 822cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell } 823cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell else 824cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell _mesa_printf("UNKNOWN\n"); 825cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell 826cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell } 827cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell} 828cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell 8299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_wm_pass_fp( struct brw_wm_compile *c ) 8309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{ 8319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct brw_fragment_program *fp = c->fp; 8329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt GLuint insn; 8339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (INTEL_DEBUG & DEBUG_WM) { 8359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt _mesa_printf("\n\n\npre-fp:\n"); 836133f14168009393c5f396d218521625cb79b653fKeith Whitwell _mesa_print_program(&fp->program.Base); 8379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt _mesa_printf("\n"); 8389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 8399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->pixel_xy = src_undef(); 8419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->delta_xy = src_undef(); 8429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->pixel_w = src_undef(); 8439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt c->nr_fp_insns = 0; 8449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* Emit preamble instructions: 8469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 8479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) { 8509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt const struct prog_instruction *inst = &fp->program.Base.Instructions[insn]; 8519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt struct prog_instruction *out; 8529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* Check for INPUT values, emit INTERP instructions where 8549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * necessary: 8559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 8569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt validate_src_regs(c, inst); 8579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt switch (inst->Opcode) { 8609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_SWZ: 8619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out = emit_insn(c, inst); 8629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out->Opcode = OPCODE_MOV; 8639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 8649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_ABS: 8669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out = emit_insn(c, inst); 8679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out->Opcode = OPCODE_MOV; 8689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out->SrcReg[0].NegateBase = 0; 8699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out->SrcReg[0].Abs = 1; 8709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 8719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_SUB: 8739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out = emit_insn(c, inst); 8749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out->Opcode = OPCODE_ADD; 8759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out->SrcReg[1].NegateBase ^= 0xf; 8769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 8779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_SCS: 8799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out = emit_insn(c, inst); 8809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* This should probably be done in the parser. 8819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 8829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out->DstReg.WriteMask &= WRITEMASK_XY; 8839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 8849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_DST: 8869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt precalc_dst(c, inst); 8879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 8889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_LIT: 8909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt precalc_lit(c, inst); 8919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 8929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_TXP: 8949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt precalc_txp(c, inst); 8959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 8969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 8979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_XPD: 8989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out = emit_insn(c, inst); 8999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* This should probably be done in the parser. 9009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 9019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out->DstReg.WriteMask &= WRITEMASK_XYZ; 9029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 9039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 9049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_KIL: 9059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out = emit_insn(c, inst); 9069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /* This should probably be done in the parser. 9079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */ 9089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt out->DstReg.WriteMask = 0; 9099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 9109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 9119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_END: 9129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt case OPCODE_PRINT: 9139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 9149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 9159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt default: 9169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_insn(c, inst); 9179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt break; 9189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 9199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 9209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 9219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_fog(c); 9229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt emit_fb_write(c); 9239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 9249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 9259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt if (INTEL_DEBUG & DEBUG_WM) { 9269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt _mesa_printf("\n\n\npass_fp:\n"); 927cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell print_insns( c->prog_instructions, c->nr_fp_insns ); 9289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt _mesa_printf("\n"); 9299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt } 9309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt} 9319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt 932