brw_wm_fp.c revision 9ef33b86855c4d000271774030bd1b19b6d79687
19f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*
29f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Copyright (C) Intel Corp.  2006.  All Rights Reserved.
39f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
49f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt develop this 3D driver.
59f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
69f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Permission is hereby granted, free of charge, to any person obtaining
79f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt a copy of this software and associated documentation files (the
89f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "Software"), to deal in the Software without restriction, including
99f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt without limitation the rights to use, copy, modify, merge, publish,
109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt distribute, sublicense, and/or sell copies of the Software, and to
119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt permit persons to whom the Software is furnished to do so, subject to
129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt the following conditions:
139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt The above copyright notice and this permission notice (including the
159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt next paragraph) shall be included in all copies or substantial
169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt portions of the Software.
179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt **********************************************************************/
279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /*
289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  * Authors:
299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  *   Keith Whitwell <keith@tungstengraphics.com>
309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  */
319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
33ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/glheader.h"
34ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/macros.h"
35ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/enums.h"
369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_context.h"
379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_wm.h"
389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_util.h"
399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
40064ae479a770bf434958d673baf6f7530f642697Brian#include "shader/prog_parameter.h"
41064ae479a770bf434958d673baf6f7530f642697Brian#include "shader/prog_print.h"
42064ae479a770bf434958d673baf6f7530f642697Brian#include "shader/prog_statevars.h"
43064ae479a770bf434958d673baf6f7530f642697Brian
449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
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;
919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_reg_from_dst(struct prog_dst_register dst)
959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(dst.File, dst.Index);
979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_undef( void )
1009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_UNDEFINED, 0);
1029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic GLboolean src_is_undef(struct prog_src_register src)
1059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src.File == PROGRAM_UNDEFINED;
1079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_swizzle( struct prog_src_register reg, int x, int y, int z, int w )
1109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Swizzle = MAKE_SWIZZLE4(x,y,z,w);
1129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
1139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_swizzle1( struct prog_src_register reg, int x )
1169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_swizzle(reg, x, x, x, x);
1189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
120c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paulstatic struct prog_src_register src_swizzle4( struct prog_src_register reg, uint swizzle )
121c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul{
122c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   reg.Swizzle = swizzle;
123c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   return reg;
124c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul}
125c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul
1269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
1289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Dest regs
1299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
1309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_reg(GLuint file, GLuint idx)
1329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register reg;
1349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.File = file;
1359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Index = idx;
1369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.WriteMask = WRITEMASK_XYZW;
13795fa98d61a857448e690a0671b2e1e1d2873f0ecBrian Paul   reg.RelAddr = 0;
13820f49252e1fe2e72bb620c26292f33d5315452a1Brian Paul   reg.CondMask = COND_TR;
1399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.CondSwizzle = 0;
1409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.CondSrc = 0;
14195fa98d61a857448e690a0671b2e1e1d2873f0ecBrian Paul   reg.pad = 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) {
1639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      _mesa_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{
1849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return &c->prog_instructions[c->nr_fp_insns++];
1859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction *emit_insn(struct brw_wm_compile *c,
1889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt					const struct prog_instruction *inst0)
1899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_instruction *inst = get_fp_inst(c);
1919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   *inst = *inst0;
1929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return inst;
1939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
195a79186e29efebed04c927d024b013435e7ff5725Brian Paulstatic struct prog_instruction * emit_tex_op(struct brw_wm_compile *c,
1969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint op,
1979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_dst_register dest,
1989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint saturate,
1999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint tex_src_unit,
2009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint tex_src_target,
201e0d907308150b4863cc4f24543e70e14207e966aBrian Paul				       GLuint tex_shadow,
2029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src0,
2039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src1,
2049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src2 )
2059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_instruction *inst = get_fp_inst(c);
2079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
20834da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   assert(tex_src_unit < BRW_MAX_TEX_UNIT ||
20934da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul          tex_src_unit == TEX_UNIT_NONE);
21034da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   assert(tex_src_target < NUM_TEXTURE_TARGETS ||
21134da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul          tex_src_target == TEX_TARGET_NONE);
21234da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul
21334da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   /* update mask of which texture units are referenced by this program */
21434da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   if (tex_src_unit != TEX_UNIT_NONE)
21534da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul      c->fp->tex_units_used |= (1 << tex_src_unit);
216b7d2023cf99319c71a929c35478dff07d35df392Brian Paul
2179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   memset(inst, 0, sizeof(*inst));
2189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->Opcode = op;
2209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->DstReg = dest;
2219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SaturateMode = saturate;
2229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->TexSrcUnit = tex_src_unit;
2239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->TexSrcTarget = tex_src_target;
224e0d907308150b4863cc4f24543e70e14207e966aBrian Paul   inst->TexShadow = tex_shadow;
2259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[0] = src0;
2269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[1] = src1;
2279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[2] = src2;
2289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return inst;
2299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
2309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
232a79186e29efebed04c927d024b013435e7ff5725Brian Paulstatic struct prog_instruction * emit_op(struct brw_wm_compile *c,
233a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       GLuint op,
234a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_dst_register dest,
235a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       GLuint saturate,
236a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_src_register src0,
237a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_src_register src1,
238a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_src_register src2 )
239a79186e29efebed04c927d024b013435e7ff5725Brian Paul{
240a79186e29efebed04c927d024b013435e7ff5725Brian Paul   return emit_tex_op(c, op, dest, saturate,
24134da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul                      TEX_UNIT_NONE, TEX_TARGET_NONE, 0,  /* unit, tgt, shadow */
242a79186e29efebed04c927d024b013435e7ff5725Brian Paul                      src0, src1, src2);
243a79186e29efebed04c927d024b013435e7ff5725Brian Paul}
244a79186e29efebed04c927d024b013435e7ff5725Brian Paul
2459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
246536476f2432168fb15ac06b52c953a594ad851adEric Anholt/* Many Mesa opcodes produce the same value across all the result channels.
247536476f2432168fb15ac06b52c953a594ad851adEric Anholt * We'd rather not have to support that splatting in the opcode implementations,
248536476f2432168fb15ac06b52c953a594ad851adEric Anholt * and brw_wm_pass*.c wants to optimize them out by shuffling references around
249536476f2432168fb15ac06b52c953a594ad851adEric Anholt * anyway.  We can easily get both by emitting the opcode to one channel, and
250536476f2432168fb15ac06b52c953a594ad851adEric Anholt * then MOVing it to the others, which brw_wm_pass*.c already understands.
251536476f2432168fb15ac06b52c953a594ad851adEric Anholt */
252536476f2432168fb15ac06b52c953a594ad851adEric Anholtstatic struct prog_instruction *emit_scalar_insn(struct brw_wm_compile *c,
253536476f2432168fb15ac06b52c953a594ad851adEric Anholt						 const struct prog_instruction *inst0)
254536476f2432168fb15ac06b52c953a594ad851adEric Anholt{
255536476f2432168fb15ac06b52c953a594ad851adEric Anholt   struct prog_instruction *inst;
256536476f2432168fb15ac06b52c953a594ad851adEric Anholt   unsigned int dst_chan;
257536476f2432168fb15ac06b52c953a594ad851adEric Anholt   unsigned int other_channel_mask;
258536476f2432168fb15ac06b52c953a594ad851adEric Anholt
259536476f2432168fb15ac06b52c953a594ad851adEric Anholt   if (inst0->DstReg.WriteMask == 0)
260536476f2432168fb15ac06b52c953a594ad851adEric Anholt      return NULL;
261536476f2432168fb15ac06b52c953a594ad851adEric Anholt
262536476f2432168fb15ac06b52c953a594ad851adEric Anholt   dst_chan = _mesa_ffs(inst0->DstReg.WriteMask) - 1;
263536476f2432168fb15ac06b52c953a594ad851adEric Anholt   inst = get_fp_inst(c);
264536476f2432168fb15ac06b52c953a594ad851adEric Anholt   *inst = *inst0;
265536476f2432168fb15ac06b52c953a594ad851adEric Anholt   inst->DstReg.WriteMask = 1 << dst_chan;
266536476f2432168fb15ac06b52c953a594ad851adEric Anholt
267536476f2432168fb15ac06b52c953a594ad851adEric Anholt   other_channel_mask = inst0->DstReg.WriteMask & ~(1 << dst_chan);
268536476f2432168fb15ac06b52c953a594ad851adEric Anholt   if (other_channel_mask != 0) {
269536476f2432168fb15ac06b52c953a594ad851adEric Anholt      inst = emit_op(c,
270536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     OPCODE_MOV,
271536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     dst_mask(inst0->DstReg, other_channel_mask),
272536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     0,
273536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     src_swizzle1(src_reg_from_dst(inst0->DstReg), dst_chan),
274536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     src_undef(),
275536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     src_undef());
276536476f2432168fb15ac06b52c953a594ad851adEric Anholt   }
277536476f2432168fb15ac06b52c953a594ad851adEric Anholt   return inst;
278536476f2432168fb15ac06b52c953a594ad851adEric Anholt}
279536476f2432168fb15ac06b52c953a594ad851adEric Anholt
2809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
2829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Special instructions for interpolation and other tasks
2839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
2849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_xy( struct brw_wm_compile *c )
2869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->pixel_xy)) {
2889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register pixel_xy = get_temp(c);
2899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
2909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Emit the out calculations, and hold onto the results.  Use
2939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       * two instructions as a temporary is required.
2949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
2959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* pixel_xy.xy = PIXELXY payload[0];
2969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
2979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
2989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PIXELXY,
2999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(pixel_xy, WRITEMASK_XY),
300a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      payload_r0_depth,
3029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
3039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->pixel_xy = src_reg_from_dst(pixel_xy);
3069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->pixel_xy;
3099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_delta_xy( struct brw_wm_compile *c )
3129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
3139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->delta_xy)) {
3149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register delta_xy = get_temp(c);
3159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register pixel_xy = get_pixel_xy(c);
3169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
3179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* deltas.xy = DELTAXY pixel_xy, payload[0]
3199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_DELTAXY,
3229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(delta_xy, WRITEMASK_XY),
323a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      pixel_xy,
3259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      payload_r0_depth,
3269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->delta_xy = src_reg_from_dst(delta_xy);
3299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->delta_xy;
3329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
3359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
3369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->pixel_w)) {
3379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register pixel_w = get_temp(c);
3389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register deltas = get_delta_xy(c);
3399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register interp_wpos = src_reg(PROGRAM_PAYLOAD, FRAG_ATTRIB_WPOS);
3409b78d9f65178648b1888f98153a2f738a281cb84Brian Paul
3419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* deltas.xyw = DELTAS2 deltas.xy, payload.interp_wpos.x
3429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PIXELW,
3459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(pixel_w, WRITEMASK_W),
346a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp_wpos,
3489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
3499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->pixel_w = src_reg_from_dst(pixel_w);
3539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->pixel_w;
3569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void emit_interp( struct brw_wm_compile *c,
3599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 GLuint idx )
3609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
3619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
3629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
3639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register deltas = get_delta_xy(c);
364b013f945d8514ed827183a4cbfbc4dccc100704fEric Anholt
3659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Need to use PINTERP on attributes which have been
3669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * multiplied by 1/W in the SF program, and LINTERP on those
3679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * which have not:
3689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
3699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   switch (idx) {
3709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_WPOS:
3719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Have to treat wpos.xy specially:
3729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_WPOSXY,
3759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_XY),
376a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      get_pixel_xy(c),
3789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
3799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      dst = dst_mask(dst, WRITEMASK_ZW);
3829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw
3849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_LINTERP,
3879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst,
388a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp,
3909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
391b013f945d8514ed827183a4cbfbc4dccc100704fEric Anholt	      src_undef());
3929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
3939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_COL0:
3949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_COL1:
3959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (c->key.flat_shade) {
3969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 emit_op(c,
3979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 WM_CINTERP,
3989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 dst,
399a79186e29efebed04c927d024b013435e7ff5725Brian Paul		 0,
4009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 interp,
4019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 src_undef(),
4029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 src_undef());
4039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
4049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      else {
40518af7c384cf663533f210d95d074c244d4214f29Brian Paul         if (c->key.linear_color) {
40618af7c384cf663533f210d95d074c244d4214f29Brian Paul            emit_op(c,
40718af7c384cf663533f210d95d074c244d4214f29Brian Paul                    WM_LINTERP,
40818af7c384cf663533f210d95d074c244d4214f29Brian Paul                    dst,
40918af7c384cf663533f210d95d074c244d4214f29Brian Paul                    0,
41018af7c384cf663533f210d95d074c244d4214f29Brian Paul                    interp,
41118af7c384cf663533f210d95d074c244d4214f29Brian Paul                    deltas,
41218af7c384cf663533f210d95d074c244d4214f29Brian Paul                    src_undef());
41318af7c384cf663533f210d95d074c244d4214f29Brian Paul         }
41418af7c384cf663533f210d95d074c244d4214f29Brian Paul         else {
41518af7c384cf663533f210d95d074c244d4214f29Brian Paul            /* perspective-corrected color interpolation */
41618af7c384cf663533f210d95d074c244d4214f29Brian Paul            emit_op(c,
41718af7c384cf663533f210d95d074c244d4214f29Brian Paul                    WM_PINTERP,
41818af7c384cf663533f210d95d074c244d4214f29Brian Paul                    dst,
41918af7c384cf663533f210d95d074c244d4214f29Brian Paul                    0,
42018af7c384cf663533f210d95d074c244d4214f29Brian Paul                    interp,
42118af7c384cf663533f210d95d074c244d4214f29Brian Paul                    deltas,
42218af7c384cf663533f210d95d074c244d4214f29Brian Paul                    get_pixel_w(c));
42318af7c384cf663533f210d95d074c244d4214f29Brian Paul         }
4249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
4259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
426411d913ccea362dbd75411266d7abb685214ee93Eric Anholt   case FRAG_ATTRIB_FOGC:
427411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      /* Interpolate the fog coordinate */
428411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      emit_op(c,
429411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      WM_PINTERP,
430411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      dst_mask(dst, WRITEMASK_X),
431411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      0,
432411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      interp,
433411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      deltas,
434411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      get_pixel_w(c));
435411d913ccea362dbd75411266d7abb685214ee93Eric Anholt
4369d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      emit_op(c,
4379d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      OPCODE_MOV,
4389d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      dst_mask(dst, WRITEMASK_YZW),
4399d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      0,
4409d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      src_swizzle(interp,
4419d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul			  SWIZZLE_ZERO,
4429d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul			  SWIZZLE_ZERO,
4439d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul			  SWIZZLE_ZERO,
4449d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul			  SWIZZLE_ONE),
4459d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      src_undef(),
4469d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      src_undef());
4479d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      break;
4489d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul
4499d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul   case FRAG_ATTRIB_FACE:
4509d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      /* XXX review/test this case */
4519d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      emit_op(c,
4529d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              WM_FRONTFACING,
4539d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              dst_mask(dst, WRITEMASK_X),
4549d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              0,
4559d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              src_undef(),
4569d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              src_undef(),
4579d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              src_undef());
4589d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      break;
4599d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul
4609d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul   case FRAG_ATTRIB_PNTC:
4619d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      /* XXX review/test this case */
4629d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      emit_op(c,
4639d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      WM_PINTERP,
4649d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      dst_mask(dst, WRITEMASK_XY),
4659d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      0,
4669d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      interp,
4679d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      deltas,
4689d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      get_pixel_w(c));
469411d913ccea362dbd75411266d7abb685214ee93Eric Anholt
470411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      emit_op(c,
471411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      OPCODE_MOV,
472411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      dst_mask(dst, WRITEMASK_ZW),
473411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      0,
474411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      src_swizzle(interp,
475411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ZERO,
476411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ZERO,
477411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ZERO,
478411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ONE),
479411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      src_undef(),
480411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      src_undef());
481411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      break;
4829d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul
4839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   default:
4849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
4859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PINTERP,
4869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst,
487a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
4889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp,
4899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
4909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      get_pixel_w(c));
4919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
4929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
4939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->fp_interp_emitted |= 1<<idx;
4959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
4969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
4989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Hacks to extend the program parameter and constant lists.
4999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
5009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/* Add the fog parameters to the parameter list of the original
5029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * program, rather than creating a new list.  Doesn't really do any
5039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * harm and it's not as if the parameter handling isn't a big hack
5049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * anyway.
5059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
506064ae479a770bf434958d673baf6f7530f642697Brianstatic struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
507064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s0,
508064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s1,
509064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s2,
510064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s3,
511064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s4)
5129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
514064ae479a770bf434958d673baf6f7530f642697Brian   gl_state_index tokens[STATE_LENGTH];
5159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint idx;
5169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[0] = s0;
5179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[1] = s1;
5189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[2] = s2;
5199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[3] = s3;
5209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[4] = s4;
5219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (idx = 0; idx < paramList->NumParameters; idx++) {
5239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (paramList->Parameters[idx].Type == PROGRAM_STATE_VAR &&
5249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  memcmp(paramList->Parameters[idx].StateIndexes, tokens, sizeof(tokens)) == 0)
5259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 return src_reg(PROGRAM_STATE_VAR, idx);
5269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   idx = _mesa_add_state_reference( paramList, tokens );
5299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_STATE_VAR, idx);
5319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
5329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c,
5359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s0,
5369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s1,
5379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s2,
5389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s3)
5399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
5419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLfloat values[4];
5429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint idx;
543064ae479a770bf434958d673baf6f7530f642697Brian   GLuint swizzle;
5449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[0] = s0;
5469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[1] = s1;
5479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[2] = s2;
5489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   values[3] = s3;
5499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Have to search, otherwise multiple compilations will each grow
5519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * the parameter list.
5529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
5539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (idx = 0; idx < paramList->NumParameters; idx++) {
5549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (paramList->Parameters[idx].Type == PROGRAM_CONSTANT &&
5559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  memcmp(paramList->ParameterValues[idx], values, sizeof(values)) == 0)
5569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* XXX: this mimics the mesa bug which puts all constants and
5589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  * parameters into the "PROGRAM_STATE_VAR" category:
5599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
5609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 return src_reg(PROGRAM_STATE_VAR, idx);
5619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
563064ae479a770bf434958d673baf6f7530f642697Brian   idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
5647eca6be25f31cbbe5b72a70bf6b1e17c0e6df34dEric Anholt   assert(swizzle == SWIZZLE_NOOP); /* Need to handle swizzle in reg setup */
5659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_STATE_VAR, idx);
5669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
5679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
5719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Expand various instructions here to simpler forms.
5729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
5739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_dst( struct brw_wm_compile *c,
5749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
5759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
5779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src1 = inst->SrcReg[1];
5789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = inst->DstReg;
5799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_Y) {
5819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.y = mul src0.y, src1.y
5829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
5839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
5849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
5859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_Y),
586a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      inst->SaturateMode,
5879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
5889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src1,
5899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
5909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_XZ) {
593b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      struct prog_instruction *swz;
5949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      GLuint z = GET_SWZ(src0.Swizzle, Z);
5959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.xz = swz src0.1zzz
5979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
598b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz = emit_op(c,
599b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    OPCODE_SWZ,
600b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    dst_mask(dst, WRITEMASK_XZ),
601a79186e29efebed04c927d024b013435e7ff5725Brian Paul		    inst->SaturateMode,
602b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_swizzle(src0, SWIZZLE_ONE, z, z, z),
603b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef(),
604b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef());
605b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      /* Avoid letting negation flag of src0 affect our 1 constant. */
6067db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      swz->SrcReg[0].Negate &= ~NEGATE_X;
6079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_W) {
6099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.w = mov src1.w
6109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
6119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
6129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MOV,
6139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_W),
614a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      inst->SaturateMode,
6159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src1,
6169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
6179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
6189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
6209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_lit( struct brw_wm_compile *c,
6239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 const struct prog_instruction *inst )
6249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
6259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
6269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = inst->DstReg;
6279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_XW) {
629b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      struct prog_instruction *swz;
630b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt
6319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.xw = swz src0.1111
6329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
633b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz = emit_op(c,
634b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    OPCODE_SWZ,
635b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    dst_mask(dst, WRITEMASK_XW),
636a79186e29efebed04c927d024b013435e7ff5725Brian Paul		    0,
637b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_swizzle1(src0, SWIZZLE_ONE),
638b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef(),
639b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef());
640b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      /* Avoid letting the negation flag of src0 affect our 1 constant. */
6417db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      swz->SrcReg[0].Negate = NEGATE_NONE;
6429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_YZ) {
6459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
6469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_LIT,
6479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_YZ),
648a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      inst->SaturateMode,
6499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
6509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
6519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
6529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
6549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6559e7903e492ad842481a166484e0474dd4f3100baBrian Paul
6569e7903e492ad842481a166484e0474dd4f3100baBrian Paul/**
6579e7903e492ad842481a166484e0474dd4f3100baBrian Paul * Some TEX instructions require extra code, cube map coordinate
6589e7903e492ad842481a166484e0474dd4f3100baBrian Paul * normalization, or coordinate scaling for RECT textures, etc.
6599e7903e492ad842481a166484e0474dd4f3100baBrian Paul * This function emits those extra instructions and the TEX
6609e7903e492ad842481a166484e0474dd4f3100baBrian Paul * instruction itself.
6619e7903e492ad842481a166484e0474dd4f3100baBrian Paul */
6629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_tex( struct brw_wm_compile *c,
6639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 const struct prog_instruction *inst )
6649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
665e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   struct prog_src_register coord;
666e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   struct prog_dst_register tmpcoord;
6679e7903e492ad842481a166484e0474dd4f3100baBrian Paul   const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
668e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
669b7d2023cf99319c71a929c35478dff07d35df392Brian Paul   assert(unit < BRW_MAX_TEX_UNIT);
670b7d2023cf99319c71a929c35478dff07d35df392Brian Paul
671175db68db59c6b917306adff98442d590df9af06Xiang, Haihao   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
672175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_instruction *out;
673175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_dst_register tmp0 = get_temp(c);
674175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register tmp0src = src_reg_from_dst(tmp0);
675175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_dst_register tmp1 = get_temp(c);
676175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register tmp1src = src_reg_from_dst(tmp1);
677175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register src0 = inst->SrcReg[0];
678175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6799e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* find longest component of coord vector and normalize it */
680175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       tmpcoord = get_temp(c);
681175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       coord = src_reg_from_dst(tmpcoord);
682175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6839e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmpcoord = src0 (i.e.: coord = src0) */
684175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       out = emit_op(c, OPCODE_MOV,
685175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     tmpcoord,
686a79186e29efebed04c927d024b013435e7ff5725Brian Paul                     0,
687175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src0,
688175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src_undef(),
689175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src_undef());
6907db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul       out->SrcReg[0].Negate = NEGATE_NONE;
691175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       out->SrcReg[0].Abs = 1;
692175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6939e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp0 = MAX(coord.X, coord.Y) */
694175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MAX,
695175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0,
696a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
697175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, X),
698175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, Y),
699175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
700175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7019e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp1 = MAX(tmp0, coord.Z) */
702175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MAX,
703175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp1,
704a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
705175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0src,
706175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, Z),
707175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
708175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7099e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp0 = 1 / tmp1 */
710175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_RCP,
711d64649a316858a390bafe2aa619be3cf2c98ffdeEric Anholt               dst_mask(tmp0, WRITEMASK_X),
712a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
713175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp1src,
714175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef(),
715175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
716175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7179e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmpCoord = src0 * tmp0 */
718175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MUL,
719175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmpcoord,
720a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
721175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src0,
722d64649a316858a390bafe2aa619be3cf2c98ffdeEric Anholt               src_swizzle1(tmp0src, SWIZZLE_X),
723175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
724175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
725175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       release_temp(c, tmp0);
726175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       release_temp(c, tmp1);
7279e7903e492ad842481a166484e0474dd4f3100baBrian Paul   }
7289e7903e492ad842481a166484e0474dd4f3100baBrian Paul   else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
729e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      struct prog_src_register scale =
730064ae479a770bf434958d673baf6f7530f642697Brian	 search_or_add_param5( c,
731e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell			       STATE_INTERNAL,
732e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell			       STATE_TEXRECT_SCALE,
733a3024caff1c790cf9f24476926aa62198f1e7b53Xiang, Haihao			       unit,
734064ae479a770bf434958d673baf6f7530f642697Brian			       0,0 );
735e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
736e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      tmpcoord = get_temp(c);
737e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
738e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      /* coord.xy   = MUL inst->SrcReg[0], { 1/width, 1/height }
739e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell       */
740e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      emit_op(c,
741e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      OPCODE_MUL,
742e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      tmpcoord,
743a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
744e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      inst->SrcReg[0],
745191e028de20b2f954621b652aa77b06d0e93652aEric Anholt	      src_swizzle(scale,
746191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_X,
747191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_Y,
748191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_ONE,
749191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_ONE),
750e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      src_undef());
751e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
752e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      coord = src_reg_from_dst(tmpcoord);
753e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   }
754e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   else {
755e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      coord = inst->SrcReg[0];
756e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   }
757e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
7589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Need to emit YUV texture conversions by hand.  Probably need to
7599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * do this here - the alternative is in brw_wm_emit.c, but the
7609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * conversion requires allocating a temporary variable which we
7619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * don't have the facility to do that late in the compilation.
7629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
7639e7903e492ad842481a166484e0474dd4f3100baBrian Paul   if (c->key.yuvtex_mask & (1 << unit)) {
7649e7903e492ad842481a166484e0474dd4f3100baBrian Paul      /* convert ycbcr to RGBA */
7659e7903e492ad842481a166484e0474dd4f3100baBrian Paul      GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
7667676980d38cff417015bca8d23549d567d74228bZou Nan hai
7679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /*
7689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 CONST C0 = { -.5, -.0625,  -.5, 1.164 }
7699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 CONST C1 = { 1.596, -0.813, 2.018, -.391 }
7709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV     = TEX ...
7719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV.xyz = ADD UYV,     C0
7729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV.y   = MUL UYV.y,   C0.w
7737676980d38cff417015bca8d23549d567d74228bZou Nan hai 	 if (UV swaped)
7747676980d38cff417015bca8d23549d567d74228bZou Nan hai	    RGB.xyz = MAD UYV.zzx, C1,   UYV.y
7757676980d38cff417015bca8d23549d567d74228bZou Nan hai	 else
7767676980d38cff417015bca8d23549d567d74228bZou Nan hai	    RGB.xyz = MAD UYV.xxz, C1,   UYV.y
7779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 RGB.y   = MAD UYV.z,   C1.w, RGB.y
7789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      */
7799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register dst = inst->DstReg;
7809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register tmp = get_temp(c);
7819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register tmpsrc = src_reg_from_dst(tmp);
7829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register C0 = search_or_add_const4f( c,  -.5, -.0625, -.5, 1.164 );
7839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register C1 = search_or_add_const4f( c, 1.596, -0.813, 2.018, -.391 );
7849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp     = TEX ...
7869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
787a79186e29efebed04c927d024b013435e7ff5725Brian Paul      emit_tex_op(c,
788a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  OPCODE_TEX,
789a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  tmp,
790a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->SaturateMode,
791a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  unit,
792a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->TexSrcTarget,
793e0d907308150b4863cc4f24543e70e14207e966aBrian Paul                  inst->TexShadow,
794a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  coord,
795a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef(),
796a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef());
7979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp.xyz =  ADD TMP, C0
7999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_ADD,
8029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_XYZ),
803a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      tmpsrc,
8059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      C0,
8069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
8079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* YUV.y   = MUL YUV.y, C0.w
8099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8107676980d38cff417015bca8d23549d567d74228bZou Nan hai
8119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
8139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_Y),
814a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      tmpsrc,
8169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(C0, W),
8179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
8189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8197676980d38cff417015bca8d23549d567d74228bZou Nan hai      /*
8207676980d38cff417015bca8d23549d567d74228bZou Nan hai       * if (UV swaped)
8217676980d38cff417015bca8d23549d567d74228bZou Nan hai       *     RGB.xyz = MAD YUV.zzx, C1, YUV.y
8227676980d38cff417015bca8d23549d567d74228bZou Nan hai       * else
8237676980d38cff417015bca8d23549d567d74228bZou Nan hai       *     RGB.xyz = MAD YUV.xxz, C1, YUV.y
8249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8257676980d38cff417015bca8d23549d567d74228bZou Nan hai
8269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MAD,
8289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_XYZ),
829a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8307676980d38cff417015bca8d23549d567d74228bZou Nan hai	      swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),
8319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      C1,
8329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(tmpsrc, Y));
8339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /*  RGB.y   = MAD YUV.z, C1.w, RGB.y
8359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MAD,
8389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_Y),
839a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(tmpsrc, Z),
8419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(C1, W),
8429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src_reg_from_dst(dst), Y));
843e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
844e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      release_temp(c, tmp);
8459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
8469e7903e492ad842481a166484e0474dd4f3100baBrian Paul   else {
8479e7903e492ad842481a166484e0474dd4f3100baBrian Paul      /* ordinary RGBA tex instruction */
848a79186e29efebed04c927d024b013435e7ff5725Brian Paul      emit_tex_op(c,
849a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  OPCODE_TEX,
850a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->DstReg,
851a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->SaturateMode,
852a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  unit,
853a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->TexSrcTarget,
854e0d907308150b4863cc4f24543e70e14207e966aBrian Paul                  inst->TexShadow,
855a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  coord,
856a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef(),
857a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef());
8589e7903e492ad842481a166484e0474dd4f3100baBrian Paul   }
859e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
860c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   /* For GL_EXT_texture_swizzle: */
861c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) {
862c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul      /* swizzle the result of the TEX instruction */
863c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul      struct prog_src_register tmpsrc = src_reg_from_dst(inst->DstReg);
8643dcc48e6882385f58ec9b19a3a7d5307ef9fc976Brian Paul      emit_op(c, OPCODE_SWZ,
865c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              inst->DstReg,
866c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              SATURATE_OFF, /* saturate already done above */
867c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]),
868c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_undef(),
869c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_undef());
870c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   }
871c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul
87228c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger   if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
87328c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger       (inst->TexSrcTarget == TEXTURE_CUBE_INDEX))
874e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      release_temp(c, tmpcoord);
8759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
8769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8786b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul/**
8796b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul * Check if the given TXP instruction really needs the divide-by-W step.
8806b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul */
8819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic GLboolean projtex( struct brw_wm_compile *c,
8829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			  const struct prog_instruction *inst )
8839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
8846b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   const struct prog_src_register src = inst->SrcReg[0];
8856b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   GLboolean retVal;
8866b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul
8876b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   assert(inst->Opcode == OPCODE_TXP);
8889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Only try to detect the simplest cases.  Could detect (later)
8909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * cases where we are trying to emit code like RCP {1.0}, MUL x,
8919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * {1.0}, and so on.
8929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    *
8939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * More complex cases than this typically only arise from
8949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * user-provided fragment programs anyway:
8959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
8969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX)
8976b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul      retVal = GL_FALSE;  /* ut2004 gun rendering !?! */
8989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else if (src.File == PROGRAM_INPUT &&
8999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    GET_SWZ(src.Swizzle, W) == W &&
9006b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul            (c->key.proj_attrib_mask & (1 << src.Index)) == 0)
9016b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul      retVal = GL_FALSE;
9029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else
9036b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul      retVal = GL_TRUE;
9046b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul
9056b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   return retVal;
9069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
9079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9096b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul/**
9106b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul * Emit code for TXP.
9116b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul */
9129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_txp( struct brw_wm_compile *c,
9139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
9149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
9159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
9169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (projtex(c, inst)) {
9189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register tmp = get_temp(c);
9199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_instruction tmp_inst;
9209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp0.w = RCP inst.arg[0][3]
9229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
9249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_RCP,
9259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_W),
926a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
9279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),
9289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
9299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
9309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp0.xyz =  MUL inst.arg[0], tmp0.wwww
9329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
9349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
9359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_XYZ),
936a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
9379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
9389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src_reg_from_dst(tmp), W),
9399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
9409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst = precalc(TEX tmp0)
9429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      tmp_inst = *inst;
9449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      tmp_inst.SrcReg[0] = src_reg_from_dst(tmp);
9459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      precalc_tex(c, &tmp_inst);
9469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      release_temp(c, tmp);
9489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
9499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else
9509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   {
9519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst = precalc(TEX src0)
9529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      precalc_tex(c, inst);
9549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
9559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
9569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void emit_fb_write( struct brw_wm_compile *c )
9609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
9619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
9628d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPTH);
963f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   struct prog_src_register outcolor;
964fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   GLuint i;
965fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
9667936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   struct prog_instruction *inst, *last_inst;
967fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   struct brw_context *brw = c->func.brw;
968fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
9698ae7e7749b708fc5a46180d3de2503ba7e2ab1f3Brian Paul   /* The inst->Aux field is used for FB write target and the EOT marker */
970fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
9719ef33b86855c4d000271774030bd1b19b6d79687Brian Paul   if (c->key.nr_color_regions > 1) {
9729ef33b86855c4d000271774030bd1b19b6d79687Brian Paul      for (i = 0 ; i < c->key.nr_color_regions; i++) {
9739b78d9f65178648b1888f98153a2f738a281cb84Brian Paul         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);
974a0959bcee5df4272db40a56c468f8c7cc299d5efBrian Paul         last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0),
975a0959bcee5df4272db40a56c468f8c7cc299d5efBrian Paul                                    0, outcolor, payload_r0_depth, outdepth);
976a8d233e509a2c1aada7cd4e83b126ba06cb90565Brian Paul         inst->Aux = INST_AUX_TARGET(i);
9779b78d9f65178648b1888f98153a2f738a281cb84Brian Paul         if (c->fp_fragcolor_emitted) {
9788d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul            outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
979a0959bcee5df4272db40a56c468f8c7cc299d5efBrian Paul            last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0),
9809b78d9f65178648b1888f98153a2f738a281cb84Brian Paul                                       0, outcolor, payload_r0_depth, outdepth);
981a8d233e509a2c1aada7cd4e83b126ba06cb90565Brian Paul            inst->Aux = INST_AUX_TARGET(i);
9829b78d9f65178648b1888f98153a2f738a281cb84Brian Paul         }
9839b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      }
984a8d233e509a2c1aada7cd4e83b126ba06cb90565Brian Paul      last_inst->Aux |= INST_AUX_EOT;
985f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   }
986f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   else {
987f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul      /* if gl_FragData[0] is written, use it, else use gl_FragColor */
988f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul      if (c->fp->program.Base.OutputsWritten & (1 << FRAG_RESULT_DATA0))
989f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0);
990f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul      else
9918d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
992f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul
9939b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
9949b78d9f65178648b1888f98153a2f738a281cb84Brian Paul                     0, outcolor, payload_r0_depth, outdepth);
995a8d233e509a2c1aada7cd4e83b126ba06cb90565Brian Paul      inst->Aux = INST_AUX_EOT | INST_AUX_TARGET(0);
996fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   }
9979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
9989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
10039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Emit INTERP instructions ahead of first use of each attrib.
10049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
10059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void validate_src_regs( struct brw_wm_compile *c,
10079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
10089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
10099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint nr_args = brw_wm_nr_args( inst->Opcode );
10109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint i;
10119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (i = 0; i < nr_args; i++) {
10139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (inst->SrcReg[i].File == PROGRAM_INPUT) {
10149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 GLuint idx = inst->SrcReg[i].Index;
10159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 if (!(c->fp_interp_emitted & (1<<idx))) {
10169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    emit_interp(c, idx);
10179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 }
10189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
10199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
10209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
10219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10227936c614abc165270852bc5e7e316747a9cacdfbZou Nan haistatic void validate_dst_regs( struct brw_wm_compile *c,
10237936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai			       const struct prog_instruction *inst )
10247936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai{
10257936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   if (inst->DstReg.File == PROGRAM_OUTPUT) {
10269b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      GLuint idx = inst->DstReg.Index;
10278d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      if (idx == FRAG_RESULT_COLOR)
10289b78d9f65178648b1888f98153a2f738a281cb84Brian Paul         c->fp_fragcolor_emitted = 1;
10297936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   }
10307936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai}
10319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1032cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwellstatic void print_insns( const struct prog_instruction *insn,
1033cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell			 GLuint nr )
1034cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell{
1035cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   GLuint i;
1036cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   for (i = 0; i < nr; i++, insn++) {
1037cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      _mesa_printf("%3d: ", i);
1038cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      if (insn->Opcode < MAX_OPCODE)
1039cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell	 _mesa_print_instruction(insn);
1040cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      else if (insn->Opcode < MAX_WM_OPCODE) {
1041cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell	 GLuint idx = insn->Opcode - MAX_OPCODE;
1042cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell
1043cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell	 _mesa_print_alu_instruction(insn,
1044cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell				     wm_opcode_strings[idx],
1045cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell				     3);
1046cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      }
1047cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      else
104820f49252e1fe2e72bb620c26292f33d5315452a1Brian Paul	 _mesa_printf("965 Opcode %d\n", insn->Opcode);
1049cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   }
1050cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell}
1051cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell
10522f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
10532f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul/**
10542f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * Initial pass for fragment program code generation.
10552f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * This function is used by both the GLSL and non-GLSL paths.
10562f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul */
10579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_wm_pass_fp( struct brw_wm_compile *c )
10589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
10599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct brw_fragment_program *fp = c->fp;
10609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint insn;
10619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (INTEL_DEBUG & DEBUG_WM) {
1063fc3971d80051b34836716579fd060dbb122d036bEric Anholt      _mesa_printf("pre-fp:\n");
1064133f14168009393c5f396d218521625cb79b653fKeith Whitwell      _mesa_print_program(&fp->program.Base);
10659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      _mesa_printf("\n");
10669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
10679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->pixel_xy = src_undef();
10699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->delta_xy = src_undef();
10709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->pixel_w = src_undef();
10719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->nr_fp_insns = 0;
1072b2b220e6225fdd673ea7b9fdda00e98423263fc3Brian Paul   c->fp->tex_units_used = 0x0;
10739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10742f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Emit preamble instructions.  This is where special instructions such as
10752f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * WM_CINTERP, WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
10762f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * compute shader inputs from varying vars.
10779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
10789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
10799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
10807936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      validate_src_regs(c, inst);
10817936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      validate_dst_regs(c, inst);
10827936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   }
10832f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
10842f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Loop over all instructions doing assorted simplifications and
10852f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * transformations.
10862f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
10877936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
10887936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
10899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_instruction *out;
10909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Check for INPUT values, emit INTERP instructions where
10929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       * necessary:
10939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
10949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      switch (inst->Opcode) {
10969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SWZ:
10979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
10989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_MOV;
10999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_ABS:
11029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_MOV;
11047db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul	 out->SrcReg[0].Negate = NEGATE_NONE;
11059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->SrcReg[0].Abs = 1;
11069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SUB:
11099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_ADD;
11117db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul	 out->SrcReg[1].Negate ^= NEGATE_XYZW;
11129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SCS:
11159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
11179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
11189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask &= WRITEMASK_XY;
11199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_DST:
11229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_dst(c, inst);
11239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_LIT:
11269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_lit(c, inst);
11279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
112828c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger
112928c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger      case OPCODE_TEX:
113028c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger	 precalc_tex(c, inst);
113128c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger	 break;
113228c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger
11339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_TXP:
11349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_txp(c, inst);
11359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1137c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao      case OPCODE_TXB:
1138c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 out = emit_insn(c, inst);
1139c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
1140b7d2023cf99319c71a929c35478dff07d35df392Brian Paul         assert(out->TexSrcUnit < BRW_MAX_TEX_UNIT);
1141c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 break;
1142c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao
11439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_XPD:
11449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
11469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
11479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask &= WRITEMASK_XYZ;
11489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_KIL:
11519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
11539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
11549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask = 0;
11559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_END:
1157d19d0596daf004b56d80f78fa1a329b43c2ebf94Zou Nan hai	 emit_fb_write(c);
1158d19d0596daf004b56d80f78fa1a329b43c2ebf94Zou Nan hai	 break;
11599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_PRINT:
11609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      default:
1162536476f2432168fb15ac06b52c953a594ad851adEric Anholt	 if (brw_wm_is_scalar_result(inst->Opcode))
1163536476f2432168fb15ac06b52c953a594ad851adEric Anholt	    emit_scalar_insn(c, inst);
1164536476f2432168fb15ac06b52c953a594ad851adEric Anholt	 else
1165536476f2432168fb15ac06b52c953a594ad851adEric Anholt	    emit_insn(c, inst);
11669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
11689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
11699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (INTEL_DEBUG & DEBUG_WM) {
11719b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      _mesa_printf("pass_fp:\n");
11729b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      print_insns( c->prog_instructions, c->nr_fp_insns );
11739b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      _mesa_printf("\n");
11749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
11759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
11769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1177