brw_wm_fp.c revision 2f78d4a2cd009d8d6a5f470d5738586b7f89f3d9
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
33ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/glheader.h"
34ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/macros.h"
35ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/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
114c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paulstatic struct prog_src_register src_swizzle4( struct prog_src_register reg, uint swizzle )
115c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul{
116c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   reg.Swizzle = swizzle;
117c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   return reg;
118c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul}
119c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul
1209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
1229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Dest regs
1239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
1249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_reg(GLuint file, GLuint idx)
1269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register reg;
1289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.File = file;
1299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Index = idx;
1309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.WriteMask = WRITEMASK_XYZW;
13195fa98d61a857448e690a0671b2e1e1d2873f0ecBrian Paul   reg.RelAddr = 0;
1329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.CondMask = 0;
1339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.CondSwizzle = 0;
1349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.CondSrc = 0;
13595fa98d61a857448e690a0671b2e1e1d2873f0ecBrian Paul   reg.pad = 0;
1369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
1379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_mask( struct prog_dst_register reg, int mask )
1409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.WriteMask &= mask;
1429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
1439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_undef( void )
1469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return dst_reg(PROGRAM_UNDEFINED, 0);
1489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register get_temp( struct brw_wm_compile *c )
1539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1543105bc1d885ea8ce083d2be85cbeac46d4d873a1Andrzej Trznadel   int bit = _mesa_ffs( ~c->fp_temp );
1559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (!bit) {
1579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      _mesa_printf("%s: out of temporaries\n", __FILE__);
1589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      exit(1);
1599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
1609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->fp_temp |= 1<<(bit-1);
1629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return dst_reg(PROGRAM_TEMPORARY, FIRST_INTERNAL_TEMP+(bit-1));
1639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void release_temp( struct brw_wm_compile *c, struct prog_dst_register temp )
1679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1683105bc1d885ea8ce083d2be85cbeac46d4d873a1Andrzej Trznadel   c->fp_temp &= ~(1 << (temp.Index - FIRST_INTERNAL_TEMP));
1699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
1739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Instructions
1749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
1759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction *get_fp_inst(struct brw_wm_compile *c)
1779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return &c->prog_instructions[c->nr_fp_insns++];
1799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction *emit_insn(struct brw_wm_compile *c,
1829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt					const struct prog_instruction *inst0)
1839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_instruction *inst = get_fp_inst(c);
1859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   *inst = *inst0;
186d19d0596daf004b56d80f78fa1a329b43c2ebf94Zou Nan hai   inst->Data = (void *)inst0;
1879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return inst;
1889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction * emit_op(struct brw_wm_compile *c,
1919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint op,
1929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_dst_register dest,
1939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint saturate,
1949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint tex_src_unit,
1959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint tex_src_target,
1969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src0,
1979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src1,
1989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src2 )
1999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_instruction *inst = get_fp_inst(c);
2019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   memset(inst, 0, sizeof(*inst));
2039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->Opcode = op;
2059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->DstReg = dest;
2069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SaturateMode = saturate;
2079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->TexSrcUnit = tex_src_unit;
2089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->TexSrcTarget = tex_src_target;
2099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[0] = src0;
2109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[1] = src1;
2119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[2] = src2;
2129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return inst;
2139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
2149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
2199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Special instructions for interpolation and other tasks
2209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
2219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_xy( struct brw_wm_compile *c )
2239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->pixel_xy)) {
2259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register pixel_xy = get_temp(c);
2269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
2279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Emit the out calculations, and hold onto the results.  Use
2309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       * two instructions as a temporary is required.
2319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
2329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* pixel_xy.xy = PIXELXY payload[0];
2339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
2349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
2359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PIXELXY,
2369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(pixel_xy, WRITEMASK_XY),
2379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
2389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      payload_r0_depth,
2399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
2409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
2419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->pixel_xy = src_reg_from_dst(pixel_xy);
2439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
2449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->pixel_xy;
2469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
2479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_delta_xy( struct brw_wm_compile *c )
2499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->delta_xy)) {
2519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register delta_xy = get_temp(c);
2529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register pixel_xy = get_pixel_xy(c);
2539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
2549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* deltas.xy = DELTAXY pixel_xy, payload[0]
2569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
2579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
2589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_DELTAXY,
2599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(delta_xy, WRITEMASK_XY),
2609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
2619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      pixel_xy,
2629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      payload_r0_depth,
2639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
2649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->delta_xy = src_reg_from_dst(delta_xy);
2669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
2679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->delta_xy;
2699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
2709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
2729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->pixel_w)) {
2749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register pixel_w = get_temp(c);
2759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register deltas = get_delta_xy(c);
2769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register interp_wpos = src_reg(PROGRAM_PAYLOAD, FRAG_ATTRIB_WPOS);
2779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* deltas.xyw = DELTAS2 deltas.xy, payload.interp_wpos.x
2809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
2819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
2829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PIXELW,
2839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(pixel_w, WRITEMASK_W),
2849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
2859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp_wpos,
2869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
2879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
2889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->pixel_w = src_reg_from_dst(pixel_w);
2919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
2929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->pixel_w;
2949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
2959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void emit_interp( struct brw_wm_compile *c,
2979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 GLuint idx )
2989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
3009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
3019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register deltas = get_delta_xy(c);
3029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register arg2;
3039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint opcode;
3049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Need to use PINTERP on attributes which have been
3069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * multiplied by 1/W in the SF program, and LINTERP on those
3079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * which have not:
3089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
3099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   switch (idx) {
3109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_WPOS:
3119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      opcode = WM_LINTERP;
3129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      arg2 = src_undef();
3139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Have to treat wpos.xy specially:
3159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_WPOSXY,
3189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_XY),
3199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
3209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      get_pixel_xy(c),
3219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
3229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      dst = dst_mask(dst, WRITEMASK_ZW);
3259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw
3279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_LINTERP,
3309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst,
3319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
3329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp,
3339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
3349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      arg2);
3359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
3369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_COL0:
3379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_COL1:
3389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (c->key.flat_shade) {
3399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 emit_op(c,
3409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 WM_CINTERP,
3419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 dst,
3429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 0, 0, 0,
3439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 interp,
3449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 src_undef(),
3459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 src_undef());
3469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
3479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      else {
3489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 emit_op(c,
3499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 WM_LINTERP,
3509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 dst,
3519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 0, 0, 0,
3529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 interp,
3539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 deltas,
3549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 src_undef());
3559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
3569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
3579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   default:
3589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PINTERP,
3609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst,
3619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
3629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp,
3639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
3649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      get_pixel_w(c));
3659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
3669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->fp_interp_emitted |= 1<<idx;
3699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
371c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan haistatic void emit_ddx( struct brw_wm_compile *c,
372c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai        const struct prog_instruction *inst )
373c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai{
374c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai    GLuint idx = inst->SrcReg[0].Index;
375c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai    struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
376c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai
377c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai    c->fp_deriv_emitted |= 1<<idx;
378c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai    emit_op(c,
379c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            OPCODE_DDX,
380c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            inst->DstReg,
381c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            0, 0, 0,
382c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            interp,
383c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            get_pixel_w(c),
384c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            src_undef());
385c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai}
386c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai
387c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan haistatic void emit_ddy( struct brw_wm_compile *c,
388c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai        const struct prog_instruction *inst )
389c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai{
390c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai    GLuint idx = inst->SrcReg[0].Index;
391c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai    struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
392c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai
393c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai    c->fp_deriv_emitted |= 1<<idx;
394c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai    emit_op(c,
395c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            OPCODE_DDY,
396c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            inst->DstReg,
397c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            0, 0, 0,
398c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            interp,
399c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            get_pixel_w(c),
400c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai            src_undef());
401c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai}
4029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
4049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Hacks to extend the program parameter and constant lists.
4059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
4069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/* Add the fog parameters to the parameter list of the original
4089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * program, rather than creating a new list.  Doesn't really do any
4099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * harm and it's not as if the parameter handling isn't a big hack
4109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * anyway.
4119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
412064ae479a770bf434958d673baf6f7530f642697Brianstatic struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
413064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s0,
414064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s1,
415064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s2,
416064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s3,
417064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s4)
4189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
4199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
420064ae479a770bf434958d673baf6f7530f642697Brian   gl_state_index tokens[STATE_LENGTH];
4219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint idx;
4229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[0] = s0;
4239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[1] = s1;
4249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[2] = s2;
4259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[3] = s3;
4269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[4] = s4;
4279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (idx = 0; idx < paramList->NumParameters; idx++) {
4299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (paramList->Parameters[idx].Type == PROGRAM_STATE_VAR &&
4309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  memcmp(paramList->Parameters[idx].StateIndexes, tokens, sizeof(tokens)) == 0)
4319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 return src_reg(PROGRAM_STATE_VAR, idx);
4329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
4339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   idx = _mesa_add_state_reference( paramList, tokens );
4359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_STATE_VAR, idx);
4379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
4389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c,
4419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s0,
4429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s1,
4439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s2,
4449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s3)
4459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
4469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
4479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLfloat values[4];
4489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint idx;
449064ae479a770bf434958d673baf6f7530f642697Brian   GLuint swizzle;
4509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[0] = s0;
4529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[1] = s1;
4539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[2] = s2;
4549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[3] = s3;
4559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Have to search, otherwise multiple compilations will each grow
4579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * the parameter list.
4589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
4599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (idx = 0; idx < paramList->NumParameters; idx++) {
4609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (paramList->Parameters[idx].Type == PROGRAM_CONSTANT &&
4619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  memcmp(paramList->ParameterValues[idx], values, sizeof(values)) == 0)
4629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* XXX: this mimics the mesa bug which puts all constants and
4649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  * parameters into the "PROGRAM_STATE_VAR" category:
4659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
4669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 return src_reg(PROGRAM_STATE_VAR, idx);
4679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
4689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
469064ae479a770bf434958d673baf6f7530f642697Brian   idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
4707eca6be25f31cbbe5b72a70bf6b1e17c0e6df34dEric Anholt   assert(swizzle == SWIZZLE_NOOP); /* Need to handle swizzle in reg setup */
4719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_STATE_VAR, idx);
4729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
4739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
4779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Expand various instructions here to simpler forms.
4789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
4799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_dst( struct brw_wm_compile *c,
4809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
4819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
4829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
4839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src1 = inst->SrcReg[1];
4849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = inst->DstReg;
4859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_Y) {
4879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.y = mul src0.y, src1.y
4889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
4899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
4909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
4919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_Y),
4929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      inst->SaturateMode, 0, 0,
4939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
4949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src1,
4959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
4969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
4979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_XZ) {
500b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      struct prog_instruction *swz;
5019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      GLuint z = GET_SWZ(src0.Swizzle, Z);
5029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.xz = swz src0.1zzz
5049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
505b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz = emit_op(c,
506b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    OPCODE_SWZ,
507b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    dst_mask(dst, WRITEMASK_XZ),
508b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    inst->SaturateMode, 0, 0,
509b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_swizzle(src0, SWIZZLE_ONE, z, z, z),
510b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef(),
511b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef());
512b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      /* Avoid letting negation flag of src0 affect our 1 constant. */
513b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz->SrcReg[0].NegateBase &= ~NEGATE_X;
5149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_W) {
5169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.w = mov src1.w
5179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
5189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
5199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MOV,
5209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_W),
5219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      inst->SaturateMode, 0, 0,
5229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src1,
5239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
5249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
5259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
5279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_lit( struct brw_wm_compile *c,
5309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 const struct prog_instruction *inst )
5319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
5339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = inst->DstReg;
5349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_XW) {
536b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      struct prog_instruction *swz;
537b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt
5389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.xw = swz src0.1111
5399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
540b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz = emit_op(c,
541b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    OPCODE_SWZ,
542b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    dst_mask(dst, WRITEMASK_XW),
543b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    0, 0, 0,
544b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_swizzle1(src0, SWIZZLE_ONE),
545b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef(),
546b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef());
547b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      /* Avoid letting the negation flag of src0 affect our 1 constant. */
548b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz->SrcReg[0].NegateBase = 0;
5499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_YZ) {
5539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
5549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_LIT,
5559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_YZ),
5569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      inst->SaturateMode, 0, 0,
5579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
5589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
5599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
5609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
5629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5639e7903e492ad842481a166484e0474dd4f3100baBrian Paul
5649e7903e492ad842481a166484e0474dd4f3100baBrian Paul/**
5659e7903e492ad842481a166484e0474dd4f3100baBrian Paul * Some TEX instructions require extra code, cube map coordinate
5669e7903e492ad842481a166484e0474dd4f3100baBrian Paul * normalization, or coordinate scaling for RECT textures, etc.
5679e7903e492ad842481a166484e0474dd4f3100baBrian Paul * This function emits those extra instructions and the TEX
5689e7903e492ad842481a166484e0474dd4f3100baBrian Paul * instruction itself.
5699e7903e492ad842481a166484e0474dd4f3100baBrian Paul */
5709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_tex( struct brw_wm_compile *c,
5719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 const struct prog_instruction *inst )
5729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
573e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   struct prog_src_register coord;
574e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   struct prog_dst_register tmpcoord;
5759e7903e492ad842481a166484e0474dd4f3100baBrian Paul   const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
576e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
577175db68db59c6b917306adff98442d590df9af06Xiang, Haihao   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
578175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_instruction *out;
579175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_dst_register tmp0 = get_temp(c);
580175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register tmp0src = src_reg_from_dst(tmp0);
581175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_dst_register tmp1 = get_temp(c);
582175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register tmp1src = src_reg_from_dst(tmp1);
583175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register src0 = inst->SrcReg[0];
584175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
5859e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* find longest component of coord vector and normalize it */
586175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       tmpcoord = get_temp(c);
587175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       coord = src_reg_from_dst(tmpcoord);
588175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
5899e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmpcoord = src0 (i.e.: coord = src0) */
590175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       out = emit_op(c, OPCODE_MOV,
591175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     tmpcoord,
592175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     0, 0, 0,
593175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src0,
594175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src_undef(),
595175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src_undef());
596175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       out->SrcReg[0].NegateBase = 0;
597175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       out->SrcReg[0].Abs = 1;
598175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
5999e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp0 = MAX(coord.X, coord.Y) */
600175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MAX,
601175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0,
602175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               0, 0, 0,
603175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, X),
604175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, Y),
605175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
606175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6079e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp1 = MAX(tmp0, coord.Z) */
608175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MAX,
609175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp1,
610175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               0, 0, 0,
611175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0src,
612175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, Z),
613175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
614175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6159e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp0 = 1 / tmp1 */
616175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_RCP,
617175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0,
618175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               0, 0, 0,
619175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp1src,
620175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef(),
621175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
622175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6239e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmpCoord = src0 * tmp0 */
624175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MUL,
625175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmpcoord,
626175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               0, 0, 0,
627175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src0,
628175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0src,
629175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
630175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
631175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       release_temp(c, tmp0);
632175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       release_temp(c, tmp1);
6339e7903e492ad842481a166484e0474dd4f3100baBrian Paul   }
6349e7903e492ad842481a166484e0474dd4f3100baBrian Paul   else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
635e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      struct prog_src_register scale =
636064ae479a770bf434958d673baf6f7530f642697Brian	 search_or_add_param5( c,
637e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell			       STATE_INTERNAL,
638e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell			       STATE_TEXRECT_SCALE,
639a3024caff1c790cf9f24476926aa62198f1e7b53Xiang, Haihao			       unit,
640064ae479a770bf434958d673baf6f7530f642697Brian			       0,0 );
641e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
642e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      tmpcoord = get_temp(c);
643e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
644e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      /* coord.xy   = MUL inst->SrcReg[0], { 1/width, 1/height }
645e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell       */
646e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      emit_op(c,
647e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      OPCODE_MUL,
648e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      tmpcoord,
649e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      0, 0, 0,
650e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      inst->SrcReg[0],
651e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      scale,
652e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      src_undef());
653e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
654e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      coord = src_reg_from_dst(tmpcoord);
655e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   }
656e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   else {
657e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      coord = inst->SrcReg[0];
658e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   }
659e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
6609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Need to emit YUV texture conversions by hand.  Probably need to
6619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * do this here - the alternative is in brw_wm_emit.c, but the
6629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * conversion requires allocating a temporary variable which we
6639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * don't have the facility to do that late in the compilation.
6649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
6659e7903e492ad842481a166484e0474dd4f3100baBrian Paul   if (c->key.yuvtex_mask & (1 << unit)) {
6669e7903e492ad842481a166484e0474dd4f3100baBrian Paul      /* convert ycbcr to RGBA */
6679e7903e492ad842481a166484e0474dd4f3100baBrian Paul      GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
6687676980d38cff417015bca8d23549d567d74228bZou Nan hai
6699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /*
6709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 CONST C0 = { -.5, -.0625,  -.5, 1.164 }
6719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 CONST C1 = { 1.596, -0.813, 2.018, -.391 }
6729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV     = TEX ...
6739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV.xyz = ADD UYV,     C0
6749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV.y   = MUL UYV.y,   C0.w
6757676980d38cff417015bca8d23549d567d74228bZou Nan hai 	 if (UV swaped)
6767676980d38cff417015bca8d23549d567d74228bZou Nan hai	    RGB.xyz = MAD UYV.zzx, C1,   UYV.y
6777676980d38cff417015bca8d23549d567d74228bZou Nan hai	 else
6787676980d38cff417015bca8d23549d567d74228bZou Nan hai	    RGB.xyz = MAD UYV.xxz, C1,   UYV.y
6799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 RGB.y   = MAD UYV.z,   C1.w, RGB.y
6809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      */
6819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register dst = inst->DstReg;
6829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register tmp = get_temp(c);
6839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register tmpsrc = src_reg_from_dst(tmp);
6849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register C0 = search_or_add_const4f( c,  -.5, -.0625, -.5, 1.164 );
6859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register C1 = search_or_add_const4f( c, 1.596, -0.813, 2.018, -.391 );
6869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp     = TEX ...
6889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
6899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
6909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_TEX,
6919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      tmp,
6929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      inst->SaturateMode,
693a3024caff1c790cf9f24476926aa62198f1e7b53Xiang, Haihao	      unit,
6949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      inst->TexSrcTarget,
6957676980d38cff417015bca8d23549d567d74228bZou Nan hai	      coord,
6969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
6979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
6989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp.xyz =  ADD TMP, C0
7009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
7019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
7029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_ADD,
7039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_XYZ),
7049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
7059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      tmpsrc,
7069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      C0,
7079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
7089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* YUV.y   = MUL YUV.y, C0.w
7109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
7117676980d38cff417015bca8d23549d567d74228bZou Nan hai
7129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
7139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
7149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_Y),
7159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
7169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      tmpsrc,
7179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(C0, W),
7189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
7199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7207676980d38cff417015bca8d23549d567d74228bZou Nan hai      /*
7217676980d38cff417015bca8d23549d567d74228bZou Nan hai       * if (UV swaped)
7227676980d38cff417015bca8d23549d567d74228bZou Nan hai       *     RGB.xyz = MAD YUV.zzx, C1, YUV.y
7237676980d38cff417015bca8d23549d567d74228bZou Nan hai       * else
7247676980d38cff417015bca8d23549d567d74228bZou Nan hai       *     RGB.xyz = MAD YUV.xxz, C1, YUV.y
7259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
7267676980d38cff417015bca8d23549d567d74228bZou Nan hai
7279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
7289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MAD,
7299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_XYZ),
7309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
7317676980d38cff417015bca8d23549d567d74228bZou Nan hai	      swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),
7329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      C1,
7339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(tmpsrc, Y));
7349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /*  RGB.y   = MAD YUV.z, C1.w, RGB.y
7369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
7379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
7389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MAD,
7399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_Y),
7409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
7419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(tmpsrc, Z),
7429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(C1, W),
7439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src_reg_from_dst(dst), Y));
744e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
745e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      release_temp(c, tmp);
7469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
7479e7903e492ad842481a166484e0474dd4f3100baBrian Paul   else {
7489e7903e492ad842481a166484e0474dd4f3100baBrian Paul      /* ordinary RGBA tex instruction */
7499e7903e492ad842481a166484e0474dd4f3100baBrian Paul      emit_op(c,
7509e7903e492ad842481a166484e0474dd4f3100baBrian Paul	      OPCODE_TEX,
7519e7903e492ad842481a166484e0474dd4f3100baBrian Paul	      inst->DstReg,
7529e7903e492ad842481a166484e0474dd4f3100baBrian Paul	      inst->SaturateMode,
7539e7903e492ad842481a166484e0474dd4f3100baBrian Paul	      unit,
7549e7903e492ad842481a166484e0474dd4f3100baBrian Paul	      inst->TexSrcTarget,
7559e7903e492ad842481a166484e0474dd4f3100baBrian Paul	      coord,
7569e7903e492ad842481a166484e0474dd4f3100baBrian Paul	      src_undef(),
7579e7903e492ad842481a166484e0474dd4f3100baBrian Paul	      src_undef());
7589e7903e492ad842481a166484e0474dd4f3100baBrian Paul   }
759e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
760c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   /* For GL_EXT_texture_swizzle: */
761c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) {
762c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul      /* swizzle the result of the TEX instruction */
763c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul      struct prog_src_register tmpsrc = src_reg_from_dst(inst->DstReg);
7643dcc48e6882385f58ec9b19a3a7d5307ef9fc976Brian Paul      emit_op(c, OPCODE_SWZ,
765c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              inst->DstReg,
766c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              SATURATE_OFF, /* saturate already done above */
767c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              0, 0,   /* tex unit, target N/A */
768c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]),
769c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_undef(),
770c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_undef());
771c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   }
772c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul
77328c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger   if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
77428c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger       (inst->TexSrcTarget == TEXTURE_CUBE_INDEX))
775e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      release_temp(c, tmpcoord);
7769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
7779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic GLboolean projtex( struct brw_wm_compile *c,
7809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			  const struct prog_instruction *inst )
7819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
7829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src = inst->SrcReg[0];
7839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Only try to detect the simplest cases.  Could detect (later)
7859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * cases where we are trying to emit code like RCP {1.0}, MUL x,
7869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * {1.0}, and so on.
7879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    *
7889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * More complex cases than this typically only arise from
7899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * user-provided fragment programs anyway:
7909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
7919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX)
7929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      return 0;  /* ut2004 gun rendering !?! */
7939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else if (src.File == PROGRAM_INPUT &&
7949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    GET_SWZ(src.Swizzle, W) == W &&
79588451b04e9cd39db9cc9315aaf69e074614f22f9Xiang, Haihao           (c->key.projtex_mask & (1<<(src.Index + FRAG_ATTRIB_WPOS - FRAG_ATTRIB_TEX0))) == 0)
7969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      return 0;
7979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else
7989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      return 1;
7999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
8009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_txp( struct brw_wm_compile *c,
8039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
8049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
8059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
8069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (projtex(c, inst)) {
8089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register tmp = get_temp(c);
8099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_instruction tmp_inst;
8109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp0.w = RCP inst.arg[0][3]
8129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_RCP,
8159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_W),
8169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
8179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),
8189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
8199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
8209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp0.xyz =  MUL inst.arg[0], tmp0.wwww
8229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
8259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_XYZ),
8269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      0, 0, 0,
8279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
8289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src_reg_from_dst(tmp), W),
8299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
8309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst = precalc(TEX tmp0)
8329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      tmp_inst = *inst;
8349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      tmp_inst.SrcReg[0] = src_reg_from_dst(tmp);
8359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      precalc_tex(c, &tmp_inst);
8369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      release_temp(c, tmp);
8389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
8399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else
8409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   {
8419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst = precalc(TEX src0)
8429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      precalc_tex(c, inst);
8449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
8459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
8469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void emit_fb_write( struct brw_wm_compile *c )
8509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
8519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
8529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPR);
853f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   struct prog_src_register outcolor;
854fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   GLuint i;
855fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
8567936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   struct prog_instruction *inst, *last_inst;
857fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   struct brw_context *brw = c->func.brw;
858fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
859fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   /* inst->Sampler is not used by backend,
860fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai      use it for fb write target and eot */
861fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
862fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   if (brw->state.nr_draw_regions > 1) {
863fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai       for (i = 0 ; i < brw->state.nr_draw_regions; i++) {
864fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai	   outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);
8657936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai	   last_inst = inst = emit_op(c,
866fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai		   WM_FB_WRITE, dst_mask(dst_undef(),0), 0, 0, 0,
867fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai		   outcolor, payload_r0_depth, outdepth);
8687936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai	   inst->Sampler = (i<<1);
8697936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai	   if (c->fp_fragcolor_emitted) {
8707936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai	       outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
8717936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai	       last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
8727936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai		       0, 0, 0, outcolor, payload_r0_depth, outdepth);
8737936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai	       inst->Sampler = (i<<1);
8747936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai	   }
875fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai       }
8767936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai       last_inst->Sampler |= 1; //eot
877f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   }
878f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   else {
879f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul      /* if gl_FragData[0] is written, use it, else use gl_FragColor */
880f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul      if (c->fp->program.Base.OutputsWritten & (1 << FRAG_RESULT_DATA0))
881f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0);
882f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul      else
883f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
884f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul
8857936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai       inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
8867936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai	       0, 0, 0, outcolor, payload_r0_depth, outdepth);
8877936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai       inst->Sampler = 1|(0<<1);
888fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   }
8899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
8909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
8959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Emit INTERP instructions ahead of first use of each attrib.
8969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
8979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void validate_src_regs( struct brw_wm_compile *c,
8999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
9009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
9019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint nr_args = brw_wm_nr_args( inst->Opcode );
9029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint i;
9039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (i = 0; i < nr_args; i++) {
9059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (inst->SrcReg[i].File == PROGRAM_INPUT) {
9069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 GLuint idx = inst->SrcReg[i].Index;
9079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 if (!(c->fp_interp_emitted & (1<<idx))) {
9089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    emit_interp(c, idx);
9099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 }
9109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
9119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
9129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
9139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9147936c614abc165270852bc5e7e316747a9cacdfbZou Nan haistatic void validate_dst_regs( struct brw_wm_compile *c,
9157936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai			       const struct prog_instruction *inst )
9167936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai{
9177936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   if (inst->DstReg.File == PROGRAM_OUTPUT) {
9187936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai       GLuint idx = inst->DstReg.Index;
9197936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai       if (idx == FRAG_RESULT_COLR)
9207936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai	   c->fp_fragcolor_emitted = 1;
9217936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   }
9227936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai}
9239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
924cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwellstatic void print_insns( const struct prog_instruction *insn,
925cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell			 GLuint nr )
926cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell{
927cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   GLuint i;
928cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   for (i = 0; i < nr; i++, insn++) {
929cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      _mesa_printf("%3d: ", i);
930cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      if (insn->Opcode < MAX_OPCODE)
931cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell	 _mesa_print_instruction(insn);
932cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      else if (insn->Opcode < MAX_WM_OPCODE) {
933cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell	 GLuint idx = insn->Opcode - MAX_OPCODE;
934cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell
935cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell	 _mesa_print_alu_instruction(insn,
936cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell				     wm_opcode_strings[idx],
937cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell				     3);
938cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      }
939cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      else
940cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell	 _mesa_printf("UNKNOWN\n");
941cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell
942cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   }
943cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell}
944cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell
9452f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
9462f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul/**
9472f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * Initial pass for fragment program code generation.
9482f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * This function is used by both the GLSL and non-GLSL paths.
9492f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul */
9509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_wm_pass_fp( struct brw_wm_compile *c )
9519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
9529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct brw_fragment_program *fp = c->fp;
9539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint insn;
9549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (INTEL_DEBUG & DEBUG_WM) {
956fc3971d80051b34836716579fd060dbb122d036bEric Anholt      _mesa_printf("pre-fp:\n");
957133f14168009393c5f396d218521625cb79b653fKeith Whitwell      _mesa_print_program(&fp->program.Base);
9589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      _mesa_printf("\n");
9599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
9609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->pixel_xy = src_undef();
9629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->delta_xy = src_undef();
9639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->pixel_w = src_undef();
9649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->nr_fp_insns = 0;
9659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9662f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Emit preamble instructions.  This is where special instructions such as
9672f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * WM_CINTERP, WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
9682f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * compute shader inputs from varying vars.
9699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
9709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
9719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
9727936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      validate_src_regs(c, inst);
9737936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      validate_dst_regs(c, inst);
9747936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   }
9752f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
9762f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Loop over all instructions doing assorted simplifications and
9772f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * transformations.
9782f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
9797936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
9807936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
9819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_instruction *out;
9829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Check for INPUT values, emit INTERP instructions where
9849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       * necessary:
9859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      switch (inst->Opcode) {
9889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SWZ:
9899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
9909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_MOV;
9919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
9929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_ABS:
9949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
9959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_MOV;
9969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->SrcReg[0].NegateBase = 0;
9979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->SrcReg[0].Abs = 1;
9989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
9999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SUB:
10019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
10029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_ADD;
10039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->SrcReg[1].NegateBase ^= 0xf;
10049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
10059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SCS:
10079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
10089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
10099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
10109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask &= WRITEMASK_XY;
10119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
10129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_DST:
10149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_dst(c, inst);
10159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
10169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_LIT:
10189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_lit(c, inst);
10199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
102028c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger
102128c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger      case OPCODE_TEX:
102228c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger	 precalc_tex(c, inst);
102328c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger	 break;
102428c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger
10259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_TXP:
10269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_txp(c, inst);
10279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
10289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1029c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao      case OPCODE_TXB:
1030c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 out = emit_insn(c, inst);
1031c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
1032c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 break;
1033c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao
10349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_XPD:
10359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
10369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
10379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
10389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask &= WRITEMASK_XYZ;
10399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
10409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_KIL:
10429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
10439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
10449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
10459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask = 0;
10469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
1047c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai      case OPCODE_DDX:
1048c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai	 emit_ddx(c, inst);
1049c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai	 break;
1050c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai      case OPCODE_DDY:
1051c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai         emit_ddy(c, inst);
1052c702a7100e2aa83241e89850a97bcc23e1c6fedbZou Nan hai	break;
10539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_END:
1054d19d0596daf004b56d80f78fa1a329b43c2ebf94Zou Nan hai	 emit_fb_write(c);
1055d19d0596daf004b56d80f78fa1a329b43c2ebf94Zou Nan hai	 break;
10569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_PRINT:
10579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
10589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      default:
10609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 emit_insn(c, inst);
10619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
10629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
10639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
10649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (INTEL_DEBUG & DEBUG_WM) {
1066fc3971d80051b34836716579fd060dbb122d036bEric Anholt	   _mesa_printf("pass_fp:\n");
1067d19d0596daf004b56d80f78fa1a329b43c2ebf94Zou Nan hai	   print_insns( c->prog_instructions, c->nr_fp_insns );
1068d19d0596daf004b56d80f78fa1a329b43c2ebf94Zou Nan hai	   _mesa_printf("\n");
10699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
10709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
10719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1072