brw_wm_fp.c revision f1dba030564e66ca52f4ed44172681e7d2e90ad2
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
40ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_parameter.h"
41ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_print.h"
42ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_statevars.h"
43064ae479a770bf434958d673baf6f7530f642697Brian
449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4534da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul/** An invalid texture target */
4634da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul#define TEX_TARGET_NONE NUM_TEXTURE_TARGETS
4734da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul
4834da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul/** An invalid texture unit */
4934da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul#define TEX_UNIT_NONE BRW_MAX_TEX_UNIT
5034da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul
519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS
529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define X    0
549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define Y    1
559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define Z    2
569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define W    3
579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic const char *wm_opcode_strings[] = {
609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "PIXELXY",
619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "DELTAXY",
629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "PIXELW",
639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "LINTERP",
649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "PINTERP",
659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "CINTERP",
669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "WPOSXY",
67699db6d842c52d0b3b98b320f8ef1104a65fa783Eric Anholt   "FB_WRITE",
68699db6d842c52d0b3b98b320f8ef1104a65fa783Eric Anholt   "FRONTFACING",
699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt};
709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
71e7b0ec9ae79d4ec4aba402b9124fde55d914da92Keith Whitwell#if 0
729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic const char *wm_file_strings[] = {
739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "PAYLOAD"
749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt};
75e7b0ec9ae79d4ec4aba402b9124fde55d914da92Keith Whitwell#endif
769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Source regs
809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_reg(GLuint file, GLuint idx)
839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register reg;
859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.File = file;
869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Index = idx;
879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Swizzle = SWIZZLE_NOOP;
889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.RelAddr = 0;
897db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   reg.Negate = NEGATE_NONE;
909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Abs = 0;
91b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt   reg.HasIndex2 = 0;
929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_reg_from_dst(struct prog_dst_register dst)
969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(dst.File, dst.Index);
989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_undef( void )
1019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_UNDEFINED, 0);
1039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic GLboolean src_is_undef(struct prog_src_register src)
1069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src.File == PROGRAM_UNDEFINED;
1089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_swizzle( struct prog_src_register reg, int x, int y, int z, int w )
1119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Swizzle = MAKE_SWIZZLE4(x,y,z,w);
1139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
1149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_swizzle1( struct prog_src_register reg, int x )
1179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_swizzle(reg, x, x, x, x);
1199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
121c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paulstatic struct prog_src_register src_swizzle4( struct prog_src_register reg, uint swizzle )
122c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul{
123c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   reg.Swizzle = swizzle;
124c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   return reg;
125c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul}
126c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul
1279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
1299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Dest regs
1309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
1319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_reg(GLuint file, GLuint idx)
1339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register reg;
1359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.File = file;
1369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Index = idx;
1379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.WriteMask = WRITEMASK_XYZW;
13895fa98d61a857448e690a0671b2e1e1d2873f0ecBrian Paul   reg.RelAddr = 0;
13920f49252e1fe2e72bb620c26292f33d5315452a1Brian Paul   reg.CondMask = COND_TR;
1409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.CondSwizzle = 0;
1419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.CondSrc = 0;
1429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
1439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_mask( struct prog_dst_register reg, int mask )
1469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.WriteMask &= mask;
1489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
1499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_undef( void )
1529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return dst_reg(PROGRAM_UNDEFINED, 0);
1549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register get_temp( struct brw_wm_compile *c )
1599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1603105bc1d885ea8ce083d2be85cbeac46d4d873a1Andrzej Trznadel   int bit = _mesa_ffs( ~c->fp_temp );
1619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (!bit) {
163298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("%s: out of temporaries\n", __FILE__);
1649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      exit(1);
1659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
1669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->fp_temp |= 1<<(bit-1);
1689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return dst_reg(PROGRAM_TEMPORARY, FIRST_INTERNAL_TEMP+(bit-1));
1699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void release_temp( struct brw_wm_compile *c, struct prog_dst_register temp )
1739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1743105bc1d885ea8ce083d2be85cbeac46d4d873a1Andrzej Trznadel   c->fp_temp &= ~(1 << (temp.Index - FIRST_INTERNAL_TEMP));
1759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
1799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Instructions
1809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
1819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction *get_fp_inst(struct brw_wm_compile *c)
1839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
184cb132406ded760a622513cd1ab86bf83bb945671Eric Anholt   assert(c->nr_fp_insns < BRW_WM_MAX_INSN);
185c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt   memset(&c->prog_instructions[c->nr_fp_insns], 0,
186c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt	  sizeof(*c->prog_instructions));
1879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return &c->prog_instructions[c->nr_fp_insns++];
1889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction *emit_insn(struct brw_wm_compile *c,
1919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt					const struct prog_instruction *inst0)
1929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_instruction *inst = get_fp_inst(c);
1949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   *inst = *inst0;
1959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return inst;
1969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
198a79186e29efebed04c927d024b013435e7ff5725Brian Paulstatic struct prog_instruction * emit_tex_op(struct brw_wm_compile *c,
1999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint op,
2009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_dst_register dest,
2019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint saturate,
2029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint tex_src_unit,
2039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint tex_src_target,
204e0d907308150b4863cc4f24543e70e14207e966aBrian Paul				       GLuint tex_shadow,
2059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src0,
2069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src1,
2079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src2 )
2089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_instruction *inst = get_fp_inst(c);
2109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
21134da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   assert(tex_src_unit < BRW_MAX_TEX_UNIT ||
21234da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul          tex_src_unit == TEX_UNIT_NONE);
21334da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   assert(tex_src_target < NUM_TEXTURE_TARGETS ||
21434da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul          tex_src_target == TEX_TARGET_NONE);
21534da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul
21634da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   /* update mask of which texture units are referenced by this program */
21734da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   if (tex_src_unit != TEX_UNIT_NONE)
21834da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul      c->fp->tex_units_used |= (1 << tex_src_unit);
219b7d2023cf99319c71a929c35478dff07d35df392Brian Paul
2209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   memset(inst, 0, sizeof(*inst));
2219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->Opcode = op;
2239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->DstReg = dest;
2249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SaturateMode = saturate;
2259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->TexSrcUnit = tex_src_unit;
2269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->TexSrcTarget = tex_src_target;
227e0d907308150b4863cc4f24543e70e14207e966aBrian Paul   inst->TexShadow = tex_shadow;
2289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[0] = src0;
2299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[1] = src1;
2309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[2] = src2;
2319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return inst;
2329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
2339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
235a79186e29efebed04c927d024b013435e7ff5725Brian Paulstatic struct prog_instruction * emit_op(struct brw_wm_compile *c,
236a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       GLuint op,
237a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_dst_register dest,
238a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       GLuint saturate,
239a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_src_register src0,
240a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_src_register src1,
241a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_src_register src2 )
242a79186e29efebed04c927d024b013435e7ff5725Brian Paul{
243a79186e29efebed04c927d024b013435e7ff5725Brian Paul   return emit_tex_op(c, op, dest, saturate,
24434da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul                      TEX_UNIT_NONE, TEX_TARGET_NONE, 0,  /* unit, tgt, shadow */
245a79186e29efebed04c927d024b013435e7ff5725Brian Paul                      src0, src1, src2);
246a79186e29efebed04c927d024b013435e7ff5725Brian Paul}
247a79186e29efebed04c927d024b013435e7ff5725Brian Paul
2489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
249536476f2432168fb15ac06b52c953a594ad851adEric Anholt/* Many Mesa opcodes produce the same value across all the result channels.
250536476f2432168fb15ac06b52c953a594ad851adEric Anholt * We'd rather not have to support that splatting in the opcode implementations,
251536476f2432168fb15ac06b52c953a594ad851adEric Anholt * and brw_wm_pass*.c wants to optimize them out by shuffling references around
252536476f2432168fb15ac06b52c953a594ad851adEric Anholt * anyway.  We can easily get both by emitting the opcode to one channel, and
253536476f2432168fb15ac06b52c953a594ad851adEric Anholt * then MOVing it to the others, which brw_wm_pass*.c already understands.
254536476f2432168fb15ac06b52c953a594ad851adEric Anholt */
255536476f2432168fb15ac06b52c953a594ad851adEric Anholtstatic struct prog_instruction *emit_scalar_insn(struct brw_wm_compile *c,
256536476f2432168fb15ac06b52c953a594ad851adEric Anholt						 const struct prog_instruction *inst0)
257536476f2432168fb15ac06b52c953a594ad851adEric Anholt{
258536476f2432168fb15ac06b52c953a594ad851adEric Anholt   struct prog_instruction *inst;
259536476f2432168fb15ac06b52c953a594ad851adEric Anholt   unsigned int dst_chan;
260536476f2432168fb15ac06b52c953a594ad851adEric Anholt   unsigned int other_channel_mask;
261536476f2432168fb15ac06b52c953a594ad851adEric Anholt
262536476f2432168fb15ac06b52c953a594ad851adEric Anholt   if (inst0->DstReg.WriteMask == 0)
263536476f2432168fb15ac06b52c953a594ad851adEric Anholt      return NULL;
264536476f2432168fb15ac06b52c953a594ad851adEric Anholt
265536476f2432168fb15ac06b52c953a594ad851adEric Anholt   dst_chan = _mesa_ffs(inst0->DstReg.WriteMask) - 1;
266536476f2432168fb15ac06b52c953a594ad851adEric Anholt   inst = get_fp_inst(c);
267536476f2432168fb15ac06b52c953a594ad851adEric Anholt   *inst = *inst0;
268536476f2432168fb15ac06b52c953a594ad851adEric Anholt   inst->DstReg.WriteMask = 1 << dst_chan;
269536476f2432168fb15ac06b52c953a594ad851adEric Anholt
270536476f2432168fb15ac06b52c953a594ad851adEric Anholt   other_channel_mask = inst0->DstReg.WriteMask & ~(1 << dst_chan);
271536476f2432168fb15ac06b52c953a594ad851adEric Anholt   if (other_channel_mask != 0) {
272536476f2432168fb15ac06b52c953a594ad851adEric Anholt      inst = emit_op(c,
273536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     OPCODE_MOV,
274536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     dst_mask(inst0->DstReg, other_channel_mask),
275536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     0,
276536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     src_swizzle1(src_reg_from_dst(inst0->DstReg), dst_chan),
277536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     src_undef(),
278536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     src_undef());
279536476f2432168fb15ac06b52c953a594ad851adEric Anholt   }
280536476f2432168fb15ac06b52c953a594ad851adEric Anholt   return inst;
281536476f2432168fb15ac06b52c953a594ad851adEric Anholt}
282536476f2432168fb15ac06b52c953a594ad851adEric Anholt
2839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
2859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Special instructions for interpolation and other tasks
2869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
2879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_xy( struct brw_wm_compile *c )
2899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->pixel_xy)) {
2919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register pixel_xy = get_temp(c);
2929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
2939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Emit the out calculations, and hold onto the results.  Use
2969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       * two instructions as a temporary is required.
2979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
2989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* pixel_xy.xy = PIXELXY payload[0];
2999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PIXELXY,
3029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(pixel_xy, WRITEMASK_XY),
303a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      payload_r0_depth,
3059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
3069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->pixel_xy = src_reg_from_dst(pixel_xy);
3099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->pixel_xy;
3129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_delta_xy( struct brw_wm_compile *c )
3159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
3169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->delta_xy)) {
3179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register delta_xy = get_temp(c);
3189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register pixel_xy = get_pixel_xy(c);
3199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
3209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* deltas.xy = DELTAXY pixel_xy, payload[0]
3229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_DELTAXY,
3259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(delta_xy, WRITEMASK_XY),
326a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      pixel_xy,
3289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      payload_r0_depth,
3299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->delta_xy = src_reg_from_dst(delta_xy);
3329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->delta_xy;
3359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
3389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
339a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   /* This is only called for producing 1/w in pre-gen6 interp.  for
340a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt    * gen6, the interp opcodes don't use this argument.
341a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt    */
342a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   if (c->func.brw->intel.gen >= 6)
343a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt      return src_undef();
344a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt
345f1dba030564e66ca52f4ed44172681e7d2e90ad2Eric Anholt   if (src_is_undef(c->pixel_w)) {
3469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register pixel_w = get_temp(c);
3479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register deltas = get_delta_xy(c);
3489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register interp_wpos = src_reg(PROGRAM_PAYLOAD, FRAG_ATTRIB_WPOS);
3499b78d9f65178648b1888f98153a2f738a281cb84Brian Paul
3509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* deltas.xyw = DELTAS2 deltas.xy, payload.interp_wpos.x
3519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PIXELW,
3549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(pixel_w, WRITEMASK_W),
355a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp_wpos,
3579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
3589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->pixel_w = src_reg_from_dst(pixel_w);
3629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->pixel_w;
3659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void emit_interp( struct brw_wm_compile *c,
3689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 GLuint idx )
3699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
3709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
3719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
372a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   struct prog_src_register deltas;
373a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt
374a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   if (c->func.brw->intel.gen < 6) {
375a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt      deltas = get_delta_xy(c);
376a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   } else {
377a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt      deltas = src_undef();
378a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   }
379b013f945d8514ed827183a4cbfbc4dccc100704fEric Anholt
3809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Need to use PINTERP on attributes which have been
3819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * multiplied by 1/W in the SF program, and LINTERP on those
3829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * which have not:
3839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
3849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   switch (idx) {
3859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_WPOS:
3869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Have to treat wpos.xy specially:
3879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_WPOSXY,
3909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_XY),
391a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      get_pixel_xy(c),
3939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
3949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      dst = dst_mask(dst, WRITEMASK_ZW);
3979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw
3999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
4009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
4019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_LINTERP,
4029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst,
403a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
4049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp,
4059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
406b013f945d8514ed827183a4cbfbc4dccc100704fEric Anholt	      src_undef());
4079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
4089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_COL0:
4099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_COL1:
4109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (c->key.flat_shade) {
4119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 emit_op(c,
4129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 WM_CINTERP,
4139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 dst,
414a79186e29efebed04c927d024b013435e7ff5725Brian Paul		 0,
4159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 interp,
4169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 src_undef(),
4179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 src_undef());
4189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
4199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      else {
42018af7c384cf663533f210d95d074c244d4214f29Brian Paul         if (c->key.linear_color) {
42118af7c384cf663533f210d95d074c244d4214f29Brian Paul            emit_op(c,
42218af7c384cf663533f210d95d074c244d4214f29Brian Paul                    WM_LINTERP,
42318af7c384cf663533f210d95d074c244d4214f29Brian Paul                    dst,
42418af7c384cf663533f210d95d074c244d4214f29Brian Paul                    0,
42518af7c384cf663533f210d95d074c244d4214f29Brian Paul                    interp,
42618af7c384cf663533f210d95d074c244d4214f29Brian Paul                    deltas,
42718af7c384cf663533f210d95d074c244d4214f29Brian Paul                    src_undef());
42818af7c384cf663533f210d95d074c244d4214f29Brian Paul         }
42918af7c384cf663533f210d95d074c244d4214f29Brian Paul         else {
43018af7c384cf663533f210d95d074c244d4214f29Brian Paul            /* perspective-corrected color interpolation */
43118af7c384cf663533f210d95d074c244d4214f29Brian Paul            emit_op(c,
43218af7c384cf663533f210d95d074c244d4214f29Brian Paul                    WM_PINTERP,
43318af7c384cf663533f210d95d074c244d4214f29Brian Paul                    dst,
43418af7c384cf663533f210d95d074c244d4214f29Brian Paul                    0,
43518af7c384cf663533f210d95d074c244d4214f29Brian Paul                    interp,
43618af7c384cf663533f210d95d074c244d4214f29Brian Paul                    deltas,
43718af7c384cf663533f210d95d074c244d4214f29Brian Paul                    get_pixel_w(c));
43818af7c384cf663533f210d95d074c244d4214f29Brian Paul         }
4399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
4409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
441411d913ccea362dbd75411266d7abb685214ee93Eric Anholt   case FRAG_ATTRIB_FOGC:
442411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      /* Interpolate the fog coordinate */
443411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      emit_op(c,
444411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      WM_PINTERP,
445411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      dst_mask(dst, WRITEMASK_X),
446411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      0,
447411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      interp,
448411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      deltas,
449411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      get_pixel_w(c));
450411d913ccea362dbd75411266d7abb685214ee93Eric Anholt
4519d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      emit_op(c,
4529d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      OPCODE_MOV,
4539d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      dst_mask(dst, WRITEMASK_YZW),
4549d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      0,
4559d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      src_swizzle(interp,
4569d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul			  SWIZZLE_ZERO,
4579d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul			  SWIZZLE_ZERO,
4589d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul			  SWIZZLE_ZERO,
4599d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul			  SWIZZLE_ONE),
4609d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      src_undef(),
4619d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      src_undef());
4629d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      break;
4639d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul
4649d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul   case FRAG_ATTRIB_FACE:
4659d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      emit_op(c,
4669d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              WM_FRONTFACING,
4679d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              dst_mask(dst, WRITEMASK_X),
4689d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              0,
4699d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              src_undef(),
4709d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              src_undef(),
4719d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              src_undef());
4729d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      break;
4739d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul
4749d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul   case FRAG_ATTRIB_PNTC:
4759d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      /* XXX review/test this case */
4769d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      emit_op(c,
4779d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      WM_PINTERP,
4789d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      dst_mask(dst, WRITEMASK_XY),
4799d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      0,
4809d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      interp,
4819d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      deltas,
4829d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      get_pixel_w(c));
483411d913ccea362dbd75411266d7abb685214ee93Eric Anholt
484411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      emit_op(c,
485411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      OPCODE_MOV,
486411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      dst_mask(dst, WRITEMASK_ZW),
487411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      0,
488411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      src_swizzle(interp,
489411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ZERO,
490411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ZERO,
491411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ZERO,
492411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ONE),
493411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      src_undef(),
494411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      src_undef());
495411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      break;
4969d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul
4979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   default:
4989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
4999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PINTERP,
5009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst,
501a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
5029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp,
5039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
5049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      get_pixel_w(c));
5059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
5069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->fp_interp_emitted |= 1<<idx;
5099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
5109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
5129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Hacks to extend the program parameter and constant lists.
5139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
5149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/* Add the fog parameters to the parameter list of the original
5169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * program, rather than creating a new list.  Doesn't really do any
5179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * harm and it's not as if the parameter handling isn't a big hack
5189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * anyway.
5199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
520064ae479a770bf434958d673baf6f7530f642697Brianstatic struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
521064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s0,
522064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s1,
523064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s2,
524064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s3,
525064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s4)
5269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
528064ae479a770bf434958d673baf6f7530f642697Brian   gl_state_index tokens[STATE_LENGTH];
5299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint idx;
5309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[0] = s0;
5319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[1] = s1;
5329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[2] = s2;
5339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[3] = s3;
5349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[4] = s4;
5359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (idx = 0; idx < paramList->NumParameters; idx++) {
5379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (paramList->Parameters[idx].Type == PROGRAM_STATE_VAR &&
5389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  memcmp(paramList->Parameters[idx].StateIndexes, tokens, sizeof(tokens)) == 0)
5399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 return src_reg(PROGRAM_STATE_VAR, idx);
5409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   idx = _mesa_add_state_reference( paramList, tokens );
5439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_STATE_VAR, idx);
5459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
5469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c,
5499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s0,
5509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s1,
5519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s2,
5529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s3)
5539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
5559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLfloat values[4];
5569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint idx;
557064ae479a770bf434958d673baf6f7530f642697Brian   GLuint swizzle;
5589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[0] = s0;
5609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[1] = s1;
5619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[2] = s2;
5629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[3] = s3;
5639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Have to search, otherwise multiple compilations will each grow
5659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * the parameter list.
5669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
5679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (idx = 0; idx < paramList->NumParameters; idx++) {
5689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (paramList->Parameters[idx].Type == PROGRAM_CONSTANT &&
5699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  memcmp(paramList->ParameterValues[idx], values, sizeof(values)) == 0)
5709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* XXX: this mimics the mesa bug which puts all constants and
5729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  * parameters into the "PROGRAM_STATE_VAR" category:
5739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
5749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 return src_reg(PROGRAM_STATE_VAR, idx);
5759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
577064ae479a770bf434958d673baf6f7530f642697Brian   idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
5787eca6be25f31cbbe5b72a70bf6b1e17c0e6df34dEric Anholt   assert(swizzle == SWIZZLE_NOOP); /* Need to handle swizzle in reg setup */
5799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_STATE_VAR, idx);
5809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
5819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
5859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Expand various instructions here to simpler forms.
5869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
5879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_dst( struct brw_wm_compile *c,
5889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
5899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
5919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src1 = inst->SrcReg[1];
5929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = inst->DstReg;
5939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_Y) {
5959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.y = mul src0.y, src1.y
5969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
5979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
5989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
5999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_Y),
600a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      inst->SaturateMode,
6019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
6029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src1,
6039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
6049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_XZ) {
607b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      struct prog_instruction *swz;
6089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      GLuint z = GET_SWZ(src0.Swizzle, Z);
6099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.xz = swz src0.1zzz
6119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
612b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz = emit_op(c,
613b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    OPCODE_SWZ,
614b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    dst_mask(dst, WRITEMASK_XZ),
615a79186e29efebed04c927d024b013435e7ff5725Brian Paul		    inst->SaturateMode,
616b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_swizzle(src0, SWIZZLE_ONE, z, z, z),
617b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef(),
618b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef());
619b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      /* Avoid letting negation flag of src0 affect our 1 constant. */
6207db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      swz->SrcReg[0].Negate &= ~NEGATE_X;
6219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_W) {
6239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.w = mov src1.w
6249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
6259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
6269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MOV,
6279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_W),
628a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      inst->SaturateMode,
6299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src1,
6309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
6319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
6329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
6349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_lit( struct brw_wm_compile *c,
6379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 const struct prog_instruction *inst )
6389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
6399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
6409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = inst->DstReg;
6419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_XW) {
643b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      struct prog_instruction *swz;
644b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt
6459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.xw = swz src0.1111
6469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
647b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz = emit_op(c,
648b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    OPCODE_SWZ,
649b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    dst_mask(dst, WRITEMASK_XW),
650a79186e29efebed04c927d024b013435e7ff5725Brian Paul		    0,
651b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_swizzle1(src0, SWIZZLE_ONE),
652b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef(),
653b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef());
654b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      /* Avoid letting the negation flag of src0 affect our 1 constant. */
6557db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      swz->SrcReg[0].Negate = NEGATE_NONE;
6569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_YZ) {
6599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
6609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_LIT,
6619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_YZ),
662a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      inst->SaturateMode,
6639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
6649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
6659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
6669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
6689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6699e7903e492ad842481a166484e0474dd4f3100baBrian Paul
6709e7903e492ad842481a166484e0474dd4f3100baBrian Paul/**
6719e7903e492ad842481a166484e0474dd4f3100baBrian Paul * Some TEX instructions require extra code, cube map coordinate
6729e7903e492ad842481a166484e0474dd4f3100baBrian Paul * normalization, or coordinate scaling for RECT textures, etc.
6739e7903e492ad842481a166484e0474dd4f3100baBrian Paul * This function emits those extra instructions and the TEX
6749e7903e492ad842481a166484e0474dd4f3100baBrian Paul * instruction itself.
6759e7903e492ad842481a166484e0474dd4f3100baBrian Paul */
6769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_tex( struct brw_wm_compile *c,
6779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 const struct prog_instruction *inst )
6789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
679e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   struct prog_src_register coord;
680e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   struct prog_dst_register tmpcoord;
6819e7903e492ad842481a166484e0474dd4f3100baBrian Paul   const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
682e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
683b7d2023cf99319c71a929c35478dff07d35df392Brian Paul   assert(unit < BRW_MAX_TEX_UNIT);
684b7d2023cf99319c71a929c35478dff07d35df392Brian Paul
685175db68db59c6b917306adff98442d590df9af06Xiang, Haihao   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
686175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_instruction *out;
687175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_dst_register tmp0 = get_temp(c);
688175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register tmp0src = src_reg_from_dst(tmp0);
689175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_dst_register tmp1 = get_temp(c);
690175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register tmp1src = src_reg_from_dst(tmp1);
691175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register src0 = inst->SrcReg[0];
692175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6939e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* find longest component of coord vector and normalize it */
694175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       tmpcoord = get_temp(c);
695175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       coord = src_reg_from_dst(tmpcoord);
696175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6979e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmpcoord = src0 (i.e.: coord = src0) */
698175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       out = emit_op(c, OPCODE_MOV,
699175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     tmpcoord,
700a79186e29efebed04c927d024b013435e7ff5725Brian Paul                     0,
701175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src0,
702175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src_undef(),
703175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src_undef());
7047db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul       out->SrcReg[0].Negate = NEGATE_NONE;
705175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       out->SrcReg[0].Abs = 1;
706175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7079e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp0 = MAX(coord.X, coord.Y) */
708175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MAX,
709175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0,
710a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
711175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, X),
712175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, Y),
713175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
714175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7159e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp1 = MAX(tmp0, coord.Z) */
716175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MAX,
717175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp1,
718a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
719175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0src,
720175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, Z),
721175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
722175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7239e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp0 = 1 / tmp1 */
724175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_RCP,
725d64649a316858a390bafe2aa619be3cf2c98ffdeEric Anholt               dst_mask(tmp0, WRITEMASK_X),
726a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
727175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp1src,
728175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef(),
729175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
730175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7319e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmpCoord = src0 * tmp0 */
732175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MUL,
733175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmpcoord,
734a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
735175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src0,
736d64649a316858a390bafe2aa619be3cf2c98ffdeEric Anholt               src_swizzle1(tmp0src, SWIZZLE_X),
737175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
738175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
739175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       release_temp(c, tmp0);
740175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       release_temp(c, tmp1);
7419e7903e492ad842481a166484e0474dd4f3100baBrian Paul   }
7429e7903e492ad842481a166484e0474dd4f3100baBrian Paul   else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
743e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      struct prog_src_register scale =
744064ae479a770bf434958d673baf6f7530f642697Brian	 search_or_add_param5( c,
745e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell			       STATE_INTERNAL,
746e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell			       STATE_TEXRECT_SCALE,
747a3024caff1c790cf9f24476926aa62198f1e7b53Xiang, Haihao			       unit,
748064ae479a770bf434958d673baf6f7530f642697Brian			       0,0 );
749e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
750e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      tmpcoord = get_temp(c);
751e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
752e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      /* coord.xy   = MUL inst->SrcReg[0], { 1/width, 1/height }
753e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell       */
754e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      emit_op(c,
755e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      OPCODE_MUL,
756e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      tmpcoord,
757a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
758e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      inst->SrcReg[0],
759191e028de20b2f954621b652aa77b06d0e93652aEric Anholt	      src_swizzle(scale,
760191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_X,
761191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_Y,
762191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_ONE,
763191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_ONE),
764e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      src_undef());
765e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
766e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      coord = src_reg_from_dst(tmpcoord);
767e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   }
768e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   else {
769e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      coord = inst->SrcReg[0];
770e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   }
771e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
7729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Need to emit YUV texture conversions by hand.  Probably need to
7739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * do this here - the alternative is in brw_wm_emit.c, but the
7749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * conversion requires allocating a temporary variable which we
7759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * don't have the facility to do that late in the compilation.
7769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
7779e7903e492ad842481a166484e0474dd4f3100baBrian Paul   if (c->key.yuvtex_mask & (1 << unit)) {
7789e7903e492ad842481a166484e0474dd4f3100baBrian Paul      /* convert ycbcr to RGBA */
7799e7903e492ad842481a166484e0474dd4f3100baBrian Paul      GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
7807676980d38cff417015bca8d23549d567d74228bZou Nan hai
7819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /*
7829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 CONST C0 = { -.5, -.0625,  -.5, 1.164 }
7839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 CONST C1 = { 1.596, -0.813, 2.018, -.391 }
7849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV     = TEX ...
7859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV.xyz = ADD UYV,     C0
7869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV.y   = MUL UYV.y,   C0.w
7877676980d38cff417015bca8d23549d567d74228bZou Nan hai 	 if (UV swaped)
7887676980d38cff417015bca8d23549d567d74228bZou Nan hai	    RGB.xyz = MAD UYV.zzx, C1,   UYV.y
7897676980d38cff417015bca8d23549d567d74228bZou Nan hai	 else
7907676980d38cff417015bca8d23549d567d74228bZou Nan hai	    RGB.xyz = MAD UYV.xxz, C1,   UYV.y
7919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 RGB.y   = MAD UYV.z,   C1.w, RGB.y
7929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      */
7939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register dst = inst->DstReg;
7949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register tmp = get_temp(c);
7959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register tmpsrc = src_reg_from_dst(tmp);
7969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register C0 = search_or_add_const4f( c,  -.5, -.0625, -.5, 1.164 );
7979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register C1 = search_or_add_const4f( c, 1.596, -0.813, 2.018, -.391 );
7989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp     = TEX ...
8009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
801a79186e29efebed04c927d024b013435e7ff5725Brian Paul      emit_tex_op(c,
802a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  OPCODE_TEX,
803a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  tmp,
804a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->SaturateMode,
805a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  unit,
806a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->TexSrcTarget,
807e0d907308150b4863cc4f24543e70e14207e966aBrian Paul                  inst->TexShadow,
808a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  coord,
809a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef(),
810a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef());
8119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp.xyz =  ADD TMP, C0
8139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_ADD,
8169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_XYZ),
817a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      tmpsrc,
8199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      C0,
8209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
8219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* YUV.y   = MUL YUV.y, C0.w
8239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8247676980d38cff417015bca8d23549d567d74228bZou Nan hai
8259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
8279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_Y),
828a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      tmpsrc,
8309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(C0, W),
8319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
8329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8337676980d38cff417015bca8d23549d567d74228bZou Nan hai      /*
8347676980d38cff417015bca8d23549d567d74228bZou Nan hai       * if (UV swaped)
8357676980d38cff417015bca8d23549d567d74228bZou Nan hai       *     RGB.xyz = MAD YUV.zzx, C1, YUV.y
8367676980d38cff417015bca8d23549d567d74228bZou Nan hai       * else
8377676980d38cff417015bca8d23549d567d74228bZou Nan hai       *     RGB.xyz = MAD YUV.xxz, C1, YUV.y
8389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8397676980d38cff417015bca8d23549d567d74228bZou Nan hai
8409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MAD,
8429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_XYZ),
843a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8447676980d38cff417015bca8d23549d567d74228bZou Nan hai	      swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),
8459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      C1,
8469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(tmpsrc, Y));
8479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /*  RGB.y   = MAD YUV.z, C1.w, RGB.y
8499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MAD,
8529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_Y),
853a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(tmpsrc, Z),
8559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(C1, W),
8569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src_reg_from_dst(dst), Y));
857e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
858e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      release_temp(c, tmp);
8599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
8609e7903e492ad842481a166484e0474dd4f3100baBrian Paul   else {
8619e7903e492ad842481a166484e0474dd4f3100baBrian Paul      /* ordinary RGBA tex instruction */
862a79186e29efebed04c927d024b013435e7ff5725Brian Paul      emit_tex_op(c,
863a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  OPCODE_TEX,
864a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->DstReg,
865a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->SaturateMode,
866a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  unit,
867a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->TexSrcTarget,
868e0d907308150b4863cc4f24543e70e14207e966aBrian Paul                  inst->TexShadow,
869a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  coord,
870a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef(),
871a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef());
8729e7903e492ad842481a166484e0474dd4f3100baBrian Paul   }
873e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
874c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   /* For GL_EXT_texture_swizzle: */
875c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) {
876c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul      /* swizzle the result of the TEX instruction */
877c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul      struct prog_src_register tmpsrc = src_reg_from_dst(inst->DstReg);
8783dcc48e6882385f58ec9b19a3a7d5307ef9fc976Brian Paul      emit_op(c, OPCODE_SWZ,
879c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              inst->DstReg,
880c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              SATURATE_OFF, /* saturate already done above */
881c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]),
882c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_undef(),
883c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_undef());
884c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   }
885c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul
88628c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger   if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
88728c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger       (inst->TexSrcTarget == TEXTURE_CUBE_INDEX))
888e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      release_temp(c, tmpcoord);
8899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
8909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8926b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul/**
8936b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul * Check if the given TXP instruction really needs the divide-by-W step.
8946b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul */
8959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic GLboolean projtex( struct brw_wm_compile *c,
8969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			  const struct prog_instruction *inst )
8979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
8986b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   const struct prog_src_register src = inst->SrcReg[0];
8996b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   GLboolean retVal;
9006b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul
9016b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   assert(inst->Opcode == OPCODE_TXP);
9029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Only try to detect the simplest cases.  Could detect (later)
9049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * cases where we are trying to emit code like RCP {1.0}, MUL x,
9059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * {1.0}, and so on.
9069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    *
9079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * More complex cases than this typically only arise from
9089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * user-provided fragment programs anyway:
9099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
9109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX)
9116b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul      retVal = GL_FALSE;  /* ut2004 gun rendering !?! */
9129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else if (src.File == PROGRAM_INPUT &&
9139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    GET_SWZ(src.Swizzle, W) == W &&
9146b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul            (c->key.proj_attrib_mask & (1 << src.Index)) == 0)
9156b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul      retVal = GL_FALSE;
9169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else
9176b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul      retVal = GL_TRUE;
9186b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul
9196b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   return retVal;
9209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
9219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9236b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul/**
9246b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul * Emit code for TXP.
9256b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul */
9269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_txp( struct brw_wm_compile *c,
9279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
9289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
9299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
9309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (projtex(c, inst)) {
9329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register tmp = get_temp(c);
9339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_instruction tmp_inst;
9349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp0.w = RCP inst.arg[0][3]
9369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
9389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_RCP,
9399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_W),
940a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
9419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),
9429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
9439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
9449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp0.xyz =  MUL inst.arg[0], tmp0.wwww
9469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
9489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
9499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_XYZ),
950a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
9519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
9529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src_reg_from_dst(tmp), W),
9539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
9549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst = precalc(TEX tmp0)
9569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      tmp_inst = *inst;
9589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      tmp_inst.SrcReg[0] = src_reg_from_dst(tmp);
9599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      precalc_tex(c, &tmp_inst);
9609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      release_temp(c, tmp);
9629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
9639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else
9649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   {
9659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst = precalc(TEX src0)
9669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      precalc_tex(c, inst);
9689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
9699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
9709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
973cfa927766ab610a9a76730d337d77008d876ebbdEric Anholtstatic void emit_render_target_writes( struct brw_wm_compile *c )
9749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
9759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
9768d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPTH);
977f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   struct prog_src_register outcolor;
978fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   GLuint i;
979fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
9807936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   struct prog_instruction *inst, *last_inst;
981fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
9828ae7e7749b708fc5a46180d3de2503ba7e2ab1f3Brian Paul   /* The inst->Aux field is used for FB write target and the EOT marker */
983fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
9849ef33b86855c4d000271774030bd1b19b6d79687Brian Paul   if (c->key.nr_color_regions > 1) {
9859ef33b86855c4d000271774030bd1b19b6d79687Brian Paul      for (i = 0 ; i < c->key.nr_color_regions; i++) {
9869b78d9f65178648b1888f98153a2f738a281cb84Brian Paul         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);
987a0959bcee5df4272db40a56c468f8c7cc299d5efBrian Paul         last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0),
988a0959bcee5df4272db40a56c468f8c7cc299d5efBrian Paul                                    0, outcolor, payload_r0_depth, outdepth);
989a8d233e509a2c1aada7cd4e83b126ba06cb90565Brian Paul         inst->Aux = INST_AUX_TARGET(i);
9909b78d9f65178648b1888f98153a2f738a281cb84Brian Paul         if (c->fp_fragcolor_emitted) {
9918d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul            outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
992a0959bcee5df4272db40a56c468f8c7cc299d5efBrian Paul            last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0),
9939b78d9f65178648b1888f98153a2f738a281cb84Brian Paul                                       0, outcolor, payload_r0_depth, outdepth);
994a8d233e509a2c1aada7cd4e83b126ba06cb90565Brian Paul            inst->Aux = INST_AUX_TARGET(i);
9959b78d9f65178648b1888f98153a2f738a281cb84Brian Paul         }
9969b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      }
997a8d233e509a2c1aada7cd4e83b126ba06cb90565Brian Paul      last_inst->Aux |= INST_AUX_EOT;
998f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   }
999f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   else {
1000f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul      /* if gl_FragData[0] is written, use it, else use gl_FragColor */
10015606dfb572bf4b89b4882265924705bacc8c182bIan Romanick      if (c->fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0))
1002f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0);
1003f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul      else
10048d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
1005f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul
10069b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
10079b78d9f65178648b1888f98153a2f738a281cb84Brian Paul                     0, outcolor, payload_r0_depth, outdepth);
1008a8d233e509a2c1aada7cd4e83b126ba06cb90565Brian Paul      inst->Aux = INST_AUX_EOT | INST_AUX_TARGET(0);
1009fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   }
10109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
10119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
10169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Emit INTERP instructions ahead of first use of each attrib.
10179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
10189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void validate_src_regs( struct brw_wm_compile *c,
10209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
10219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
10229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint nr_args = brw_wm_nr_args( inst->Opcode );
10239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint i;
10249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (i = 0; i < nr_args; i++) {
10269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (inst->SrcReg[i].File == PROGRAM_INPUT) {
10279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 GLuint idx = inst->SrcReg[i].Index;
10289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 if (!(c->fp_interp_emitted & (1<<idx))) {
10299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    emit_interp(c, idx);
10309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 }
10319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
10329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
10339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
10349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10357936c614abc165270852bc5e7e316747a9cacdfbZou Nan haistatic void validate_dst_regs( struct brw_wm_compile *c,
10367936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai			       const struct prog_instruction *inst )
10377936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai{
10387936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   if (inst->DstReg.File == PROGRAM_OUTPUT) {
10399b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      GLuint idx = inst->DstReg.Index;
10408d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      if (idx == FRAG_RESULT_COLOR)
10419b78d9f65178648b1888f98153a2f738a281cb84Brian Paul         c->fp_fragcolor_emitted = 1;
10427936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   }
10437936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai}
10449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1045cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwellstatic void print_insns( const struct prog_instruction *insn,
1046cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell			 GLuint nr )
1047cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell{
1048cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   GLuint i;
1049cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   for (i = 0; i < nr; i++, insn++) {
1050298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("%3d: ", i);
1051cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      if (insn->Opcode < MAX_OPCODE)
105272fd0568db0ce5f25a1eee0266ec1e7cb3dafab0Eric Anholt	 _mesa_fprint_instruction_opt(stdout, insn, 0, PROG_PRINT_DEBUG, NULL);
1053cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      else if (insn->Opcode < MAX_WM_OPCODE) {
1054cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell	 GLuint idx = insn->Opcode - MAX_OPCODE;
1055cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell
105672fd0568db0ce5f25a1eee0266ec1e7cb3dafab0Eric Anholt	 _mesa_fprint_alu_instruction(stdout, insn, wm_opcode_strings[idx],
105772fd0568db0ce5f25a1eee0266ec1e7cb3dafab0Eric Anholt				      3, PROG_PRINT_DEBUG, NULL);
1058cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      }
1059cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      else
1060298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	 printf("965 Opcode %d\n", insn->Opcode);
1061cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   }
1062cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell}
1063cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell
10642f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
10652f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul/**
10662f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * Initial pass for fragment program code generation.
10672f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * This function is used by both the GLSL and non-GLSL paths.
10682f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul */
10699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_wm_pass_fp( struct brw_wm_compile *c )
10709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1071a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   struct intel_context *intel = &c->func.brw->intel;
10729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct brw_fragment_program *fp = c->fp;
10739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint insn;
10749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (INTEL_DEBUG & DEBUG_WM) {
1076298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("pre-fp:\n");
107772fd0568db0ce5f25a1eee0266ec1e7cb3dafab0Eric Anholt      _mesa_fprint_program_opt(stdout, &fp->program.Base, PROG_PRINT_DEBUG,
107872fd0568db0ce5f25a1eee0266ec1e7cb3dafab0Eric Anholt			       GL_TRUE);
1079298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("\n");
10809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
10819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->pixel_xy = src_undef();
1083a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   if (intel->gen >= 6) {
1084a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt      /* The interpolation deltas come in as the perspective pixel
1085a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt       * location barycentric params.
1086a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt       */
1087a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt      c->delta_xy = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
1088a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   } else {
1089a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt      c->delta_xy = src_undef();
1090a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   }
10919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->pixel_w = src_undef();
10929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->nr_fp_insns = 0;
1093b2b220e6225fdd673ea7b9fdda00e98423263fc3Brian Paul   c->fp->tex_units_used = 0x0;
10949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10952f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Emit preamble instructions.  This is where special instructions such as
10962f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * WM_CINTERP, WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
10972f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * compute shader inputs from varying vars.
10989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
10999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
11009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
11017936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      validate_src_regs(c, inst);
11027936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      validate_dst_regs(c, inst);
11037936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   }
11042f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
11052f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Loop over all instructions doing assorted simplifications and
11062f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * transformations.
11072f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
11087936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
11097936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
11109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_instruction *out;
11119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Check for INPUT values, emit INTERP instructions where
11139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       * necessary:
11149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
11159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      switch (inst->Opcode) {
11179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SWZ:
11189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_MOV;
11209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_ABS:
11239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_MOV;
11257db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul	 out->SrcReg[0].Negate = NEGATE_NONE;
11269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->SrcReg[0].Abs = 1;
11279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SUB:
11309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_ADD;
11327db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul	 out->SrcReg[1].Negate ^= NEGATE_XYZW;
11339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SCS:
11369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
11389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
11399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask &= WRITEMASK_XY;
11409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_DST:
11439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_dst(c, inst);
11449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_LIT:
11479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_lit(c, inst);
11489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
114928c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger
115028c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger      case OPCODE_TEX:
115128c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger	 precalc_tex(c, inst);
115228c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger	 break;
115328c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger
11549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_TXP:
11559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_txp(c, inst);
11569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1158c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao      case OPCODE_TXB:
1159c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 out = emit_insn(c, inst);
1160c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
1161b7d2023cf99319c71a929c35478dff07d35df392Brian Paul         assert(out->TexSrcUnit < BRW_MAX_TEX_UNIT);
1162c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 break;
1163c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao
11649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_XPD:
11659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
11679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
11689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask &= WRITEMASK_XYZ;
11699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_KIL:
11729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
11749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
11759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask = 0;
11769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_END:
1178cfa927766ab610a9a76730d337d77008d876ebbdEric Anholt	 emit_render_target_writes(c);
1179d19d0596daf004b56d80f78fa1a329b43c2ebf94Zou Nan hai	 break;
11809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_PRINT:
11819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      default:
1183536476f2432168fb15ac06b52c953a594ad851adEric Anholt	 if (brw_wm_is_scalar_result(inst->Opcode))
1184536476f2432168fb15ac06b52c953a594ad851adEric Anholt	    emit_scalar_insn(c, inst);
1185536476f2432168fb15ac06b52c953a594ad851adEric Anholt	 else
1186536476f2432168fb15ac06b52c953a594ad851adEric Anholt	    emit_insn(c, inst);
11879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
11899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
11909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (INTEL_DEBUG & DEBUG_WM) {
1192298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("pass_fp:\n");
11939b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      print_insns( c->prog_instructions, c->nr_fp_insns );
1194298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("\n");
11959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
11969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
11979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1198