19f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*
29f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Copyright (C) Intel Corp.  2006.  All Rights Reserved.
39f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
49f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt develop this 3D driver.
59f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
69f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Permission is hereby granted, free of charge, to any person obtaining
79f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt a copy of this software and associated documentation files (the
89f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "Software"), to deal in the Software without restriction, including
99f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt without limitation the rights to use, copy, modify, merge, publish,
109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt distribute, sublicense, and/or sell copies of the Software, and to
119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt permit persons to whom the Software is furnished to do so, subject to
129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt the following conditions:
139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt The above copyright notice and this permission notice (including the
159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt next paragraph) shall be included in all copies or substantial
169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt portions of the Software.
179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt **********************************************************************/
279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /*
289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  * Authors:
299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  *   Keith Whitwell <keith@tungstengraphics.com>
309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  */
319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
33ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/glheader.h"
34ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/macros.h"
35ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/enums.h"
369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_context.h"
379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_wm.h"
389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_util.h"
399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
40ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_parameter.h"
41ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_print.h"
42ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_statevars.h"
43064ae479a770bf434958d673baf6f7530f642697Brian
449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4534da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul/** An invalid texture target */
4634da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul#define TEX_TARGET_NONE NUM_TEXTURE_TARGETS
4734da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul
4834da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul/** An invalid texture unit */
4934da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul#define TEX_UNIT_NONE BRW_MAX_TEX_UNIT
5034da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul
519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS
529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define X    0
549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define Y    1
559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define Z    2
569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#define W    3
579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic const char *wm_opcode_strings[] = {
609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "PIXELXY",
619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "DELTAXY",
629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "PIXELW",
639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "LINTERP",
649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "PINTERP",
659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "CINTERP",
669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "WPOSXY",
67699db6d842c52d0b3b98b320f8ef1104a65fa783Eric Anholt   "FB_WRITE",
68699db6d842c52d0b3b98b320f8ef1104a65fa783Eric Anholt   "FRONTFACING",
699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt};
709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
71e7b0ec9ae79d4ec4aba402b9124fde55d914da92Keith Whitwell#if 0
729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic const char *wm_file_strings[] = {
739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   "PAYLOAD"
749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt};
75e7b0ec9ae79d4ec4aba402b9124fde55d914da92Keith Whitwell#endif
769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Source regs
809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_reg(GLuint file, GLuint idx)
839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register reg;
859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.File = file;
869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Index = idx;
879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Swizzle = SWIZZLE_NOOP;
889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.RelAddr = 0;
897db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   reg.Negate = NEGATE_NONE;
909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Abs = 0;
91b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt   reg.HasIndex2 = 0;
92e7843363a5cb1a7e6c206e2bc79f03bd58312820Vinson Lee   reg.RelAddr2 = 0;
93e7843363a5cb1a7e6c206e2bc79f03bd58312820Vinson Lee   reg.Index2 = 0;
949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_reg_from_dst(struct prog_dst_register dst)
989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(dst.File, dst.Index);
1009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_undef( void )
1039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_UNDEFINED, 0);
1059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1072e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkestatic bool src_is_undef(struct prog_src_register src)
1089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src.File == PROGRAM_UNDEFINED;
1109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_swizzle( struct prog_src_register reg, int x, int y, int z, int w )
1139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Swizzle = MAKE_SWIZZLE4(x,y,z,w);
1159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
1169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register src_swizzle1( struct prog_src_register reg, int x )
1199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_swizzle(reg, x, x, x, x);
1219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
123c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paulstatic struct prog_src_register src_swizzle4( struct prog_src_register reg, uint swizzle )
124c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul{
125c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   reg.Swizzle = swizzle;
126c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   return reg;
127c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul}
128c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul
1299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
1319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Dest regs
1329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
1339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_reg(GLuint file, GLuint idx)
1359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register reg;
1379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.File = file;
1389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.Index = idx;
1399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.WriteMask = WRITEMASK_XYZW;
14095fa98d61a857448e690a0671b2e1e1d2873f0ecBrian Paul   reg.RelAddr = 0;
14120f49252e1fe2e72bb620c26292f33d5315452a1Brian Paul   reg.CondMask = COND_TR;
1429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.CondSwizzle = 0;
1439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.CondSrc = 0;
1449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
1459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_mask( struct prog_dst_register reg, int mask )
1489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   reg.WriteMask &= mask;
1509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return reg;
1519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register dst_undef( void )
1549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return dst_reg(PROGRAM_UNDEFINED, 0);
1569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_dst_register get_temp( struct brw_wm_compile *c )
1619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1629a548c27aa704236cc1d8a5d4ebf68cea9c5c99cBrian Paul   int bit = ffs( ~c->fp_temp );
1639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (!bit) {
165298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("%s: out of temporaries\n", __FILE__);
1669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      exit(1);
1679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
1689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->fp_temp |= 1<<(bit-1);
1709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return dst_reg(PROGRAM_TEMPORARY, FIRST_INTERNAL_TEMP+(bit-1));
1719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void release_temp( struct brw_wm_compile *c, struct prog_dst_register temp )
1759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1763105bc1d885ea8ce083d2be85cbeac46d4d873a1Andrzej Trznadel   c->fp_temp &= ~(1 << (temp.Index - FIRST_INTERNAL_TEMP));
1779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
1819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Instructions
1829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
1839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction *get_fp_inst(struct brw_wm_compile *c)
1859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
186cb132406ded760a622513cd1ab86bf83bb945671Eric Anholt   assert(c->nr_fp_insns < BRW_WM_MAX_INSN);
187c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt   memset(&c->prog_instructions[c->nr_fp_insns], 0,
188c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt	  sizeof(*c->prog_instructions));
1899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return &c->prog_instructions[c->nr_fp_insns++];
1909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_instruction *emit_insn(struct brw_wm_compile *c,
1939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt					const struct prog_instruction *inst0)
1949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_instruction *inst = get_fp_inst(c);
1969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   *inst = *inst0;
1979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return inst;
1989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
1999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
200a79186e29efebed04c927d024b013435e7ff5725Brian Paulstatic struct prog_instruction * emit_tex_op(struct brw_wm_compile *c,
2019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint op,
2029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_dst_register dest,
2039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint saturate,
2049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint tex_src_unit,
2059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       GLuint tex_src_target,
206e0d907308150b4863cc4f24543e70e14207e966aBrian Paul				       GLuint tex_shadow,
2079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src0,
2089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src1,
2099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				       struct prog_src_register src2 )
2109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_instruction *inst = get_fp_inst(c);
2129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
21334da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   assert(tex_src_unit < BRW_MAX_TEX_UNIT ||
21434da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul          tex_src_unit == TEX_UNIT_NONE);
21534da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul   assert(tex_src_target < NUM_TEXTURE_TARGETS ||
21634da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul          tex_src_target == TEX_TARGET_NONE);
21734da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul
2189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   memset(inst, 0, sizeof(*inst));
2199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->Opcode = op;
2219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->DstReg = dest;
2229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SaturateMode = saturate;
2239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->TexSrcUnit = tex_src_unit;
2249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->TexSrcTarget = tex_src_target;
225e0d907308150b4863cc4f24543e70e14207e966aBrian Paul   inst->TexShadow = tex_shadow;
2269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[0] = src0;
2279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[1] = src1;
2289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   inst->SrcReg[2] = src2;
2299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return inst;
2309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
2319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
233a79186e29efebed04c927d024b013435e7ff5725Brian Paulstatic struct prog_instruction * emit_op(struct brw_wm_compile *c,
234a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       GLuint op,
235a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_dst_register dest,
236a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       GLuint saturate,
237a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_src_register src0,
238a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_src_register src1,
239a79186e29efebed04c927d024b013435e7ff5725Brian Paul				       struct prog_src_register src2 )
240a79186e29efebed04c927d024b013435e7ff5725Brian Paul{
241a79186e29efebed04c927d024b013435e7ff5725Brian Paul   return emit_tex_op(c, op, dest, saturate,
24234da6024e3097684110cd1fd4da0f25adc415cd6Brian Paul                      TEX_UNIT_NONE, TEX_TARGET_NONE, 0,  /* unit, tgt, shadow */
243a79186e29efebed04c927d024b013435e7ff5725Brian Paul                      src0, src1, src2);
244a79186e29efebed04c927d024b013435e7ff5725Brian Paul}
245a79186e29efebed04c927d024b013435e7ff5725Brian Paul
2469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
247536476f2432168fb15ac06b52c953a594ad851adEric Anholt/* Many Mesa opcodes produce the same value across all the result channels.
248536476f2432168fb15ac06b52c953a594ad851adEric Anholt * We'd rather not have to support that splatting in the opcode implementations,
249536476f2432168fb15ac06b52c953a594ad851adEric Anholt * and brw_wm_pass*.c wants to optimize them out by shuffling references around
250536476f2432168fb15ac06b52c953a594ad851adEric Anholt * anyway.  We can easily get both by emitting the opcode to one channel, and
251536476f2432168fb15ac06b52c953a594ad851adEric Anholt * then MOVing it to the others, which brw_wm_pass*.c already understands.
252536476f2432168fb15ac06b52c953a594ad851adEric Anholt */
253536476f2432168fb15ac06b52c953a594ad851adEric Anholtstatic struct prog_instruction *emit_scalar_insn(struct brw_wm_compile *c,
254536476f2432168fb15ac06b52c953a594ad851adEric Anholt						 const struct prog_instruction *inst0)
255536476f2432168fb15ac06b52c953a594ad851adEric Anholt{
256536476f2432168fb15ac06b52c953a594ad851adEric Anholt   struct prog_instruction *inst;
257536476f2432168fb15ac06b52c953a594ad851adEric Anholt   unsigned int dst_chan;
258536476f2432168fb15ac06b52c953a594ad851adEric Anholt   unsigned int other_channel_mask;
259536476f2432168fb15ac06b52c953a594ad851adEric Anholt
260536476f2432168fb15ac06b52c953a594ad851adEric Anholt   if (inst0->DstReg.WriteMask == 0)
261536476f2432168fb15ac06b52c953a594ad851adEric Anholt      return NULL;
262536476f2432168fb15ac06b52c953a594ad851adEric Anholt
2639a548c27aa704236cc1d8a5d4ebf68cea9c5c99cBrian Paul   dst_chan = ffs(inst0->DstReg.WriteMask) - 1;
264536476f2432168fb15ac06b52c953a594ad851adEric Anholt   inst = get_fp_inst(c);
265536476f2432168fb15ac06b52c953a594ad851adEric Anholt   *inst = *inst0;
266536476f2432168fb15ac06b52c953a594ad851adEric Anholt   inst->DstReg.WriteMask = 1 << dst_chan;
267536476f2432168fb15ac06b52c953a594ad851adEric Anholt
268536476f2432168fb15ac06b52c953a594ad851adEric Anholt   other_channel_mask = inst0->DstReg.WriteMask & ~(1 << dst_chan);
269536476f2432168fb15ac06b52c953a594ad851adEric Anholt   if (other_channel_mask != 0) {
270536476f2432168fb15ac06b52c953a594ad851adEric Anholt      inst = emit_op(c,
271536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     OPCODE_MOV,
272536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     dst_mask(inst0->DstReg, other_channel_mask),
273536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     0,
274536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     src_swizzle1(src_reg_from_dst(inst0->DstReg), dst_chan),
275536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     src_undef(),
276536476f2432168fb15ac06b52c953a594ad851adEric Anholt		     src_undef());
277536476f2432168fb15ac06b52c953a594ad851adEric Anholt   }
278536476f2432168fb15ac06b52c953a594ad851adEric Anholt   return inst;
279536476f2432168fb15ac06b52c953a594ad851adEric Anholt}
280536476f2432168fb15ac06b52c953a594ad851adEric Anholt
2819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
2839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Special instructions for interpolation and other tasks
2849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
2859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_xy( struct brw_wm_compile *c )
2879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
2889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->pixel_xy)) {
2899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register pixel_xy = get_temp(c);
2909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
2919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Emit the out calculations, and hold onto the results.  Use
2949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       * two instructions as a temporary is required.
2959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
2969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* pixel_xy.xy = PIXELXY payload[0];
2979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
2989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
2999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PIXELXY,
3009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(pixel_xy, WRITEMASK_XY),
301a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      payload_r0_depth,
3039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
3049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->pixel_xy = src_reg_from_dst(pixel_xy);
3079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->pixel_xy;
3109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_delta_xy( struct brw_wm_compile *c )
3139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
3149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (src_is_undef(c->delta_xy)) {
3159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register delta_xy = get_temp(c);
3169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register pixel_xy = get_pixel_xy(c);
3179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
3189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* deltas.xy = DELTAXY pixel_xy, payload[0]
3209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_DELTAXY,
3239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(delta_xy, WRITEMASK_XY),
324a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      pixel_xy,
3269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      payload_r0_depth,
3279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->delta_xy = src_reg_from_dst(delta_xy);
3309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->delta_xy;
3339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
3369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
337ad35528944960f1619e0a9491164c848b333e6cfEric Anholt   /* This is called for producing 1/w in pre-gen6 interp.  for gen6,
338ad35528944960f1619e0a9491164c848b333e6cfEric Anholt    * the interp opcodes don't use this argument.  But to keep the
339ad35528944960f1619e0a9491164c848b333e6cfEric Anholt    * nr_args = 3 expectations of pinterp happy, just stuff delta_xy
340ad35528944960f1619e0a9491164c848b333e6cfEric Anholt    * into the slot.
341a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt    */
342a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   if (c->func.brw->intel.gen >= 6)
343ad35528944960f1619e0a9491164c848b333e6cfEric Anholt      return c->delta_xy;
344a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt
345f1dba030564e66ca52f4ed44172681e7d2e90ad2Eric Anholt   if (src_is_undef(c->pixel_w)) {
3469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register pixel_w = get_temp(c);
3479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register deltas = get_delta_xy(c);
3489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register interp_wpos = src_reg(PROGRAM_PAYLOAD, FRAG_ATTRIB_WPOS);
3499b78d9f65178648b1888f98153a2f738a281cb84Brian Paul
3509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* deltas.xyw = DELTAS2 deltas.xy, payload.interp_wpos.x
3519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PIXELW,
3549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(pixel_w, WRITEMASK_W),
355a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp_wpos,
3579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
3589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      c->pixel_w = src_reg_from_dst(pixel_w);
3629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return c->pixel_w;
3659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void emit_interp( struct brw_wm_compile *c,
3689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 GLuint idx )
3699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
3709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
3719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
372a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   struct prog_src_register deltas;
373a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt
374ad35528944960f1619e0a9491164c848b333e6cfEric Anholt   deltas = get_delta_xy(c);
375b013f945d8514ed827183a4cbfbc4dccc100704fEric Anholt
3769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Need to use PINTERP on attributes which have been
3779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * multiplied by 1/W in the SF program, and LINTERP on those
3789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * which have not:
3799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
3809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   switch (idx) {
3819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_WPOS:
3829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Have to treat wpos.xy specially:
3839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_WPOSXY,
3869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(dst, WRITEMASK_XY),
387a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
3889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      get_pixel_xy(c),
3899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
3909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
3919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      dst = dst_mask(dst, WRITEMASK_ZW);
3939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw
3959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
3969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
3979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_LINTERP,
3989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst,
399a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
4009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp,
4019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
402b013f945d8514ed827183a4cbfbc4dccc100704fEric Anholt	      src_undef());
4039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
4049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_COL0:
4059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case FRAG_ATTRIB_COL1:
4069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (c->key.flat_shade) {
4079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 emit_op(c,
4089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 WM_CINTERP,
4099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 dst,
410a79186e29efebed04c927d024b013435e7ff5725Brian Paul		 0,
4119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 interp,
4129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 src_undef(),
4139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		 src_undef());
4149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
4159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      else {
416f147599ef4b0d14c25a7e0d3f9f1c9b0229bb6fcEric Anholt	 /* perspective-corrected color interpolation */
417f147599ef4b0d14c25a7e0d3f9f1c9b0229bb6fcEric Anholt	 emit_op(c,
418f147599ef4b0d14c25a7e0d3f9f1c9b0229bb6fcEric Anholt		 WM_PINTERP,
419f147599ef4b0d14c25a7e0d3f9f1c9b0229bb6fcEric Anholt		 dst,
420f147599ef4b0d14c25a7e0d3f9f1c9b0229bb6fcEric Anholt		 0,
421f147599ef4b0d14c25a7e0d3f9f1c9b0229bb6fcEric Anholt		 interp,
422f147599ef4b0d14c25a7e0d3f9f1c9b0229bb6fcEric Anholt		 deltas,
423f147599ef4b0d14c25a7e0d3f9f1c9b0229bb6fcEric Anholt		 get_pixel_w(c));
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      emit_op(c,
4519d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              WM_FRONTFACING,
4529d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              dst_mask(dst, WRITEMASK_X),
4539d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              0,
4549d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              src_undef(),
4559d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              src_undef(),
4569d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul              src_undef());
4579d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      break;
4589d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul
4599d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul   case FRAG_ATTRIB_PNTC:
4609d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      /* XXX review/test this case */
4619d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul      emit_op(c,
4629d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      WM_PINTERP,
4639d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      dst_mask(dst, WRITEMASK_XY),
4649d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      0,
4659d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      interp,
4669d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      deltas,
4679d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul	      get_pixel_w(c));
468411d913ccea362dbd75411266d7abb685214ee93Eric Anholt
469411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      emit_op(c,
470411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      OPCODE_MOV,
471411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      dst_mask(dst, WRITEMASK_ZW),
472411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      0,
473411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      src_swizzle(interp,
474411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ZERO,
475411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ZERO,
476411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ZERO,
477411d913ccea362dbd75411266d7abb685214ee93Eric Anholt			  SWIZZLE_ONE),
478411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      src_undef(),
479411d913ccea362dbd75411266d7abb685214ee93Eric Anholt	      src_undef());
480411d913ccea362dbd75411266d7abb685214ee93Eric Anholt      break;
4819d0b8d72d8d704ff4d8e10448b60cbb42f07eecbBrian Paul
4829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   default:
4839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
4849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      WM_PINTERP,
4859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst,
486a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
4879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      interp,
4889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      deltas,
4899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      get_pixel_w(c));
4909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      break;
4919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
4929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->fp_interp_emitted |= 1<<idx;
4949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
4959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
4969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
4979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Hacks to extend the program parameter and constant lists.
4989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
4999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/* Add the fog parameters to the parameter list of the original
5019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * program, rather than creating a new list.  Doesn't really do any
5029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * harm and it's not as if the parameter handling isn't a big hack
5039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * anyway.
5049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
505064ae479a770bf434958d673baf6f7530f642697Brianstatic struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
506064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s0,
507064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s1,
508064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s2,
509064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s3,
510064ae479a770bf434958d673baf6f7530f642697Brian                                                     GLint s4)
5119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
513064ae479a770bf434958d673baf6f7530f642697Brian   gl_state_index tokens[STATE_LENGTH];
5149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint idx;
5159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[0] = s0;
5169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[1] = s1;
5179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[2] = s2;
5189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[3] = s3;
5199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   tokens[4] = s4;
5209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   idx = _mesa_add_state_reference( paramList, tokens );
5229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   return src_reg(PROGRAM_STATE_VAR, idx);
5249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
5259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c,
5289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s0,
5299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s1,
5309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s2,
5319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt						     GLfloat s3)
5329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
534a9e97d022cb68266639eb54947517454c8ffe45eEric Anholt   gl_constant_value values[4];
5359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint idx;
536064ae479a770bf434958d673baf6f7530f642697Brian   GLuint swizzle;
5375b24d69fcd6359dc959ec465c7e77b4626a27e72Eric Anholt   struct prog_src_register reg;
5389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
539a9e97d022cb68266639eb54947517454c8ffe45eEric Anholt   values[0].f = s0;
540a9e97d022cb68266639eb54947517454c8ffe45eEric Anholt   values[1].f = s1;
541a9e97d022cb68266639eb54947517454c8ffe45eEric Anholt   values[2].f = s2;
542a9e97d022cb68266639eb54947517454c8ffe45eEric Anholt   values[3].f = s3;
5439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
544064ae479a770bf434958d673baf6f7530f642697Brian   idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
5455b24d69fcd6359dc959ec465c7e77b4626a27e72Eric Anholt   reg = src_reg(PROGRAM_STATE_VAR, idx);
5465b24d69fcd6359dc959ec465c7e77b4626a27e72Eric Anholt   reg.Swizzle = swizzle;
5475b24d69fcd6359dc959ec465c7e77b4626a27e72Eric Anholt
5485b24d69fcd6359dc959ec465c7e77b4626a27e72Eric Anholt   return reg;
5499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
5509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
5549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Expand various instructions here to simpler forms.
5559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
5569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_dst( struct brw_wm_compile *c,
5579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
5589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
5599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
5609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src1 = inst->SrcReg[1];
5619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = inst->DstReg;
56246a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt   struct prog_dst_register temp = get_temp(c);
56346a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt
5649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_Y) {
5659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.y = mul src0.y, src1.y
5669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
5679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
5689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
56946a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt	      dst_mask(temp, WRITEMASK_Y),
570a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      inst->SaturateMode,
5719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
5729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src1,
5739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
5749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_XZ) {
577b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      struct prog_instruction *swz;
5789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      GLuint z = GET_SWZ(src0.Swizzle, Z);
5799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
5809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.xz = swz src0.1zzz
5819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
582b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz = emit_op(c,
583b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    OPCODE_SWZ,
58446a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt		    dst_mask(temp, WRITEMASK_XZ),
585a79186e29efebed04c927d024b013435e7ff5725Brian Paul		    inst->SaturateMode,
586b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_swizzle(src0, SWIZZLE_ONE, z, z, z),
587b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef(),
588b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef());
589b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      /* Avoid letting negation flag of src0 affect our 1 constant. */
5907db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      swz->SrcReg[0].Negate &= ~NEGATE_X;
5919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
5929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_W) {
5939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.w = mov src1.w
5949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
5959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
5969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MOV,
59746a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt	      dst_mask(temp, WRITEMASK_W),
598a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      inst->SaturateMode,
5999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src1,
6009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
6019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
6029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
60346a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt
60446a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt   /* This will get optimized out in general, but it ensures that we
60546a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt    * don't overwrite src operands in our channel-wise splitting
60646a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt    * above.  See piglit fp-dst-aliasing-[12].
60746a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt    */
60846a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt   emit_op(c,
60946a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt	   OPCODE_MOV,
61046a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt	   dst,
61146a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt	   0,
61246a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt	   src_reg_from_dst(temp),
61346a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt	   src_undef(),
61446a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt	   src_undef());
61546a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt
61646a7639174d2c55c30ec24b179cbef059fb3ca43Eric Anholt   release_temp(c, temp);
6179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
6189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_lit( struct brw_wm_compile *c,
6219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 const struct prog_instruction *inst )
6229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
6239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
6249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_dst_register dst = inst->DstReg;
625e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt
626e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt   if (dst.WriteMask & WRITEMASK_YZ) {
627e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt      emit_op(c,
628e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt	      OPCODE_LIT,
629e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt	      dst_mask(dst, WRITEMASK_YZ),
630e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt	      inst->SaturateMode,
631e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt	      src0,
632e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt	      src_undef(),
633e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt	      src_undef());
634e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt   }
635e3ea5bc08e32119d05bce543c07c61ce93869e60Eric Anholt
6369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (dst.WriteMask & WRITEMASK_XW) {
637b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      struct prog_instruction *swz;
638b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt
6399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst.xw = swz src0.1111
6409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
641b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      swz = emit_op(c,
642b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    OPCODE_SWZ,
643b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    dst_mask(dst, WRITEMASK_XW),
644a79186e29efebed04c927d024b013435e7ff5725Brian Paul		    0,
645b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_swizzle1(src0, SWIZZLE_ONE),
646b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef(),
647b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt		    src_undef());
648b4cbf6983e0e6d6502c1260f60c463841ab74590Eric Anholt      /* Avoid letting the negation flag of src0 affect our 1 constant. */
6497db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      swz->SrcReg[0].Negate = NEGATE_NONE;
6509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
6519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
6529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
6539e7903e492ad842481a166484e0474dd4f3100baBrian Paul
6549e7903e492ad842481a166484e0474dd4f3100baBrian Paul/**
6559e7903e492ad842481a166484e0474dd4f3100baBrian Paul * Some TEX instructions require extra code, cube map coordinate
6569e7903e492ad842481a166484e0474dd4f3100baBrian Paul * normalization, or coordinate scaling for RECT textures, etc.
6579e7903e492ad842481a166484e0474dd4f3100baBrian Paul * This function emits those extra instructions and the TEX
6589e7903e492ad842481a166484e0474dd4f3100baBrian Paul * instruction itself.
6599e7903e492ad842481a166484e0474dd4f3100baBrian Paul */
6609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_tex( struct brw_wm_compile *c,
6619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			 const struct prog_instruction *inst )
6629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
6639d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt   struct brw_compile *p = &c->func;
6649d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt   struct intel_context *intel = &p->brw->intel;
665e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   struct prog_src_register coord;
66603577f8250cc7c8cdbd6ce1e166d9c1315c15280Vinson Lee   struct prog_dst_register tmpcoord = { 0 };
6679e7903e492ad842481a166484e0474dd4f3100baBrian Paul   const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
668f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt   struct prog_dst_register unswizzled_tmp;
669f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt
670f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt   /* If we are doing EXT_texture_swizzle, we need to write our result into a
671f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt    * temporary, otherwise writemasking of the real dst could lose some of our
672f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt    * channels.
673f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt    */
6741b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke   if (c->key.tex.swizzles[unit] != SWIZZLE_NOOP) {
675f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt      unswizzled_tmp = get_temp(c);
676f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt   } else {
677f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt      unswizzled_tmp = inst->DstReg;
678f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt   }
679e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
680b7d2023cf99319c71a929c35478dff07d35df392Brian Paul   assert(unit < BRW_MAX_TEX_UNIT);
681b7d2023cf99319c71a929c35478dff07d35df392Brian Paul
682175db68db59c6b917306adff98442d590df9af06Xiang, Haihao   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
683175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_instruction *out;
684175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_dst_register tmp0 = get_temp(c);
685175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register tmp0src = src_reg_from_dst(tmp0);
686175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_dst_register tmp1 = get_temp(c);
687175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register tmp1src = src_reg_from_dst(tmp1);
688175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       struct prog_src_register src0 = inst->SrcReg[0];
689175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6909e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* find longest component of coord vector and normalize it */
691175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       tmpcoord = get_temp(c);
692175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       coord = src_reg_from_dst(tmpcoord);
693175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
6949e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmpcoord = src0 (i.e.: coord = src0) */
695175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       out = emit_op(c, OPCODE_MOV,
696175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     tmpcoord,
697a79186e29efebed04c927d024b013435e7ff5725Brian Paul                     0,
698175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src0,
699175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src_undef(),
700175db68db59c6b917306adff98442d590df9af06Xiang, Haihao                     src_undef());
7017db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul       out->SrcReg[0].Negate = NEGATE_NONE;
702175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       out->SrcReg[0].Abs = 1;
703175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7049e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp0 = MAX(coord.X, coord.Y) */
705175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MAX,
706175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0,
707a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
708175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, X),
709175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, Y),
710175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
711175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7129e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp1 = MAX(tmp0, coord.Z) */
713175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MAX,
714175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp1,
715a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
716175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp0src,
717175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_swizzle1(coord, Z),
718175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
719175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7209e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmp0 = 1 / tmp1 */
721175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_RCP,
722d64649a316858a390bafe2aa619be3cf2c98ffdeEric Anholt               dst_mask(tmp0, WRITEMASK_X),
723a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
724175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmp1src,
725175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef(),
726175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
727175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
7289e7903e492ad842481a166484e0474dd4f3100baBrian Paul       /* tmpCoord = src0 * tmp0 */
729175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       emit_op(c, OPCODE_MUL,
730175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               tmpcoord,
731a79186e29efebed04c927d024b013435e7ff5725Brian Paul               0,
732175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src0,
733d64649a316858a390bafe2aa619be3cf2c98ffdeEric Anholt               src_swizzle1(tmp0src, SWIZZLE_X),
734175db68db59c6b917306adff98442d590df9af06Xiang, Haihao               src_undef());
735175db68db59c6b917306adff98442d590df9af06Xiang, Haihao
736175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       release_temp(c, tmp0);
737175db68db59c6b917306adff98442d590df9af06Xiang, Haihao       release_temp(c, tmp1);
7389e7903e492ad842481a166484e0474dd4f3100baBrian Paul   }
7399d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt   else if (intel->gen < 6 && inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
740e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      struct prog_src_register scale =
741064ae479a770bf434958d673baf6f7530f642697Brian	 search_or_add_param5( c,
742e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell			       STATE_INTERNAL,
743e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell			       STATE_TEXRECT_SCALE,
744a3024caff1c790cf9f24476926aa62198f1e7b53Xiang, Haihao			       unit,
745064ae479a770bf434958d673baf6f7530f642697Brian			       0,0 );
746e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
747e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      tmpcoord = get_temp(c);
748e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
749e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      /* coord.xy   = MUL inst->SrcReg[0], { 1/width, 1/height }
750e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell       */
751e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      emit_op(c,
752e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      OPCODE_MUL,
753e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      tmpcoord,
754a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
755e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      inst->SrcReg[0],
756191e028de20b2f954621b652aa77b06d0e93652aEric Anholt	      src_swizzle(scale,
757191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_X,
758191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_Y,
759191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_ONE,
760191e028de20b2f954621b652aa77b06d0e93652aEric Anholt			  SWIZZLE_ONE),
761e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell	      src_undef());
762e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
763e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      coord = src_reg_from_dst(tmpcoord);
764e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   }
765e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   else {
766e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      coord = inst->SrcReg[0];
767e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell   }
768e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
7699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Need to emit YUV texture conversions by hand.  Probably need to
7709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * do this here - the alternative is in brw_wm_emit.c, but the
7719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * conversion requires allocating a temporary variable which we
7729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * don't have the facility to do that late in the compilation.
7739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
7741b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke   if (c->key.tex.yuvtex_mask & (1 << unit)) {
7759e7903e492ad842481a166484e0474dd4f3100baBrian Paul      /* convert ycbcr to RGBA */
7761b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke      bool swap_uv = c->key.tex.yuvtex_swap_mask & (1 << unit);
7777676980d38cff417015bca8d23549d567d74228bZou Nan hai
7789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /*
7799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 CONST C0 = { -.5, -.0625,  -.5, 1.164 }
7809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 CONST C1 = { 1.596, -0.813, 2.018, -.391 }
7819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV     = TEX ...
7829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV.xyz = ADD UYV,     C0
7839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 UYV.y   = MUL UYV.y,   C0.w
7847676980d38cff417015bca8d23549d567d74228bZou Nan hai 	 if (UV swaped)
7857676980d38cff417015bca8d23549d567d74228bZou Nan hai	    RGB.xyz = MAD UYV.zzx, C1,   UYV.y
7867676980d38cff417015bca8d23549d567d74228bZou Nan hai	 else
7877676980d38cff417015bca8d23549d567d74228bZou Nan hai	    RGB.xyz = MAD UYV.xxz, C1,   UYV.y
7889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 RGB.y   = MAD UYV.z,   C1.w, RGB.y
7899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      */
7909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register tmp = get_temp(c);
7919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register tmpsrc = src_reg_from_dst(tmp);
7929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register C0 = search_or_add_const4f( c,  -.5, -.0625, -.5, 1.164 );
7939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_src_register C1 = search_or_add_const4f( c, 1.596, -0.813, 2.018, -.391 );
7949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
7959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp     = TEX ...
7969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
797a79186e29efebed04c927d024b013435e7ff5725Brian Paul      emit_tex_op(c,
798a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  OPCODE_TEX,
799a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  tmp,
800a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->SaturateMode,
801a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  unit,
802a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->TexSrcTarget,
803e0d907308150b4863cc4f24543e70e14207e966aBrian Paul                  inst->TexShadow,
804a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  coord,
805a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef(),
806a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef());
8079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp.xyz =  ADD TMP, C0
8099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_ADD,
8129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_XYZ),
813a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      tmpsrc,
8159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      C0,
8169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
8179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* YUV.y   = MUL YUV.y, C0.w
8199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8207676980d38cff417015bca8d23549d567d74228bZou Nan hai
8219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
8239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_Y),
824a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      tmpsrc,
8269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(C0, W),
8279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
8289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8297676980d38cff417015bca8d23549d567d74228bZou Nan hai      /*
8307676980d38cff417015bca8d23549d567d74228bZou Nan hai       * if (UV swaped)
8317676980d38cff417015bca8d23549d567d74228bZou Nan hai       *     RGB.xyz = MAD YUV.zzx, C1, YUV.y
8327676980d38cff417015bca8d23549d567d74228bZou Nan hai       * else
8337676980d38cff417015bca8d23549d567d74228bZou Nan hai       *     RGB.xyz = MAD YUV.xxz, C1, YUV.y
8349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8357676980d38cff417015bca8d23549d567d74228bZou Nan hai
8369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MAD,
838f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt	      dst_mask(unswizzled_tmp, WRITEMASK_XYZ),
839a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8407676980d38cff417015bca8d23549d567d74228bZou Nan hai	      swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),
8419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      C1,
8429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(tmpsrc, Y));
8439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /*  RGB.y   = MAD YUV.z, C1.w, RGB.y
8459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
8469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
8479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MAD,
848f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt	      dst_mask(unswizzled_tmp, WRITEMASK_Y),
849a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
8509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(tmpsrc, Z),
8519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(C1, W),
852f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt	      src_swizzle1(src_reg_from_dst(unswizzled_tmp), Y));
853e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
854e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      release_temp(c, tmp);
8559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
8569e7903e492ad842481a166484e0474dd4f3100baBrian Paul   else {
8579e7903e492ad842481a166484e0474dd4f3100baBrian Paul      /* ordinary RGBA tex instruction */
858a79186e29efebed04c927d024b013435e7ff5725Brian Paul      emit_tex_op(c,
859a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  OPCODE_TEX,
860f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt                  unswizzled_tmp,
861a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->SaturateMode,
862a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  unit,
863a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  inst->TexSrcTarget,
864e0d907308150b4863cc4f24543e70e14207e966aBrian Paul                  inst->TexShadow,
865a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  coord,
866a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef(),
867a79186e29efebed04c927d024b013435e7ff5725Brian Paul                  src_undef());
8689e7903e492ad842481a166484e0474dd4f3100baBrian Paul   }
869e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell
870c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   /* For GL_EXT_texture_swizzle: */
8711b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke   if (c->key.tex.swizzles[unit] != SWIZZLE_NOOP) {
872c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul      /* swizzle the result of the TEX instruction */
873f98bfb5d68423a4e57f78091c70288c0b558b8bdEric Anholt      struct prog_src_register tmpsrc = src_reg_from_dst(unswizzled_tmp);
8743dcc48e6882385f58ec9b19a3a7d5307ef9fc976Brian Paul      emit_op(c, OPCODE_SWZ,
875c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              inst->DstReg,
876c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              SATURATE_OFF, /* saturate already done above */
8771b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke              src_swizzle4(tmpsrc, c->key.tex.swizzles[unit]),
878c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_undef(),
879c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul              src_undef());
880c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul   }
881c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul
88228c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger   if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
88328c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger       (inst->TexSrcTarget == TEXTURE_CUBE_INDEX))
884e38114a5e4492684333251eb22bc60ee1038de55Keith Whitwell      release_temp(c, tmpcoord);
8859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
8869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8886b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul/**
8896b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul * Check if the given TXP instruction really needs the divide-by-W step.
8906b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul */
8912e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkestatic bool
8922e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkeprojtex(struct brw_wm_compile *c, const struct prog_instruction *inst)
8939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
8946b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   const struct prog_src_register src = inst->SrcReg[0];
8952e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   bool retVal;
8966b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul
8976b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   assert(inst->Opcode == OPCODE_TXP);
8989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
8999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Only try to detect the simplest cases.  Could detect (later)
9009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * cases where we are trying to emit code like RCP {1.0}, MUL x,
9019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * {1.0}, and so on.
9029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    *
9039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * More complex cases than this typically only arise from
9049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    * user-provided fragment programs anyway:
9059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
9069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX)
9072e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke      retVal = false;  /* ut2004 gun rendering !?! */
9089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else if (src.File == PROGRAM_INPUT &&
9099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    GET_SWZ(src.Swizzle, W) == W &&
9106b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul            (c->key.proj_attrib_mask & (1 << src.Index)) == 0)
9112e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke      retVal = false;
9129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else
9132e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke      retVal = true;
9146b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul
9156b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   return retVal;
9169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
9179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9196b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul/**
9206b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul * Emit code for TXP.
9216b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul */
9229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void precalc_txp( struct brw_wm_compile *c,
9239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
9249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
9259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register src0 = inst->SrcReg[0];
9269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (projtex(c, inst)) {
9289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_dst_register tmp = get_temp(c);
9299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_instruction tmp_inst;
9309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp0.w = RCP inst.arg[0][3]
9329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
9349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_RCP,
9359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_W),
936a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
9379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),
9389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef(),
9399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
9409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* tmp0.xyz =  MUL inst.arg[0], tmp0.wwww
9429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      emit_op(c,
9449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      OPCODE_MUL,
9459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      dst_mask(tmp, WRITEMASK_XYZ),
946a79186e29efebed04c927d024b013435e7ff5725Brian Paul	      0,
9479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src0,
9489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_swizzle1(src_reg_from_dst(tmp), W),
9499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	      src_undef());
9509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst = precalc(TEX tmp0)
9529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      tmp_inst = *inst;
9549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      tmp_inst.SrcReg[0] = src_reg_from_dst(tmp);
9559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      precalc_tex(c, &tmp_inst);
9569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      release_temp(c, tmp);
9589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
9599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   else
9609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   {
9619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* dst = precalc(TEX src0)
9629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
9639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      precalc_tex(c, inst);
9649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
9659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
9669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
9689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
969cfa927766ab610a9a76730d337d77008d876ebbdEric Anholtstatic void emit_render_target_writes( struct brw_wm_compile *c )
9709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
9719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
9728d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPTH);
973f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   struct prog_src_register outcolor;
974fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   GLuint i;
975fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
97679bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt   struct prog_instruction *inst = NULL;
977fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
9788ae7e7749b708fc5a46180d3de2503ba7e2ab1f3Brian Paul   /* The inst->Aux field is used for FB write target and the EOT marker */
979fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai
98079bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt   for (i = 0; i < c->key.nr_color_regions; i++) {
98179bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt      if (c->fp->program.Base.OutputsWritten & (1 << FRAG_RESULT_COLOR)) {
98279bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt	 outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
98379bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt      } else {
98479bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt	 outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);
9859b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      }
98679bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt      inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0),
98779bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt		     0, outcolor, payload_r0_depth, outdepth);
98879bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt      inst->Aux = INST_AUX_TARGET(i);
989f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul   }
990f68f94c2bc950405d4c91a1e5582a35ff4b15bdfBrian Paul
99179bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt   /* Mark the last FB write as final, or emit a dummy write if we had
99279bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt    * no render targets bound.
99379bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt    */
99479bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt   if (c->key.nr_color_regions != 0) {
99579bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt      inst->Aux |= INST_AUX_EOT;
99679bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt   } else {
99779bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt      inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(), 0),
99879bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt		     0, src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR),
99979bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt		     payload_r0_depth, outdepth);
100079bde19ef9e13d5db30d0516d9e7eae6a3a8d32aEric Anholt      inst->Aux = INST_AUX_TARGET(0) | INST_AUX_EOT;
1001fcb7cb9e72ecac7c165a3a6ed7a033e2e6793a26Zou Nan hai   }
10029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
10039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10059f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/***********************************************************************
10089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt * Emit INTERP instructions ahead of first use of each attrib.
10099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt */
10109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void validate_src_regs( struct brw_wm_compile *c,
10129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			       const struct prog_instruction *inst )
10139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
10149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint nr_args = brw_wm_nr_args( inst->Opcode );
10159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint i;
10169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (i = 0; i < nr_args; i++) {
10189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (inst->SrcReg[i].File == PROGRAM_INPUT) {
10199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 GLuint idx = inst->SrcReg[i].Index;
10209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 if (!(c->fp_interp_emitted & (1<<idx))) {
10219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    emit_interp(c, idx);
10229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 }
10239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
10249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
10259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
10269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1027cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwellstatic void print_insns( const struct prog_instruction *insn,
1028cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell			 GLuint nr )
1029cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell{
1030cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   GLuint i;
1031cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   for (i = 0; i < nr; i++, insn++) {
1032298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("%3d: ", i);
1033cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      if (insn->Opcode < MAX_OPCODE)
103472fd0568db0ce5f25a1eee0266ec1e7cb3dafab0Eric Anholt	 _mesa_fprint_instruction_opt(stdout, insn, 0, PROG_PRINT_DEBUG, NULL);
1035cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      else if (insn->Opcode < MAX_WM_OPCODE) {
1036cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell	 GLuint idx = insn->Opcode - MAX_OPCODE;
1037cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell
103872fd0568db0ce5f25a1eee0266ec1e7cb3dafab0Eric Anholt	 _mesa_fprint_alu_instruction(stdout, insn, wm_opcode_strings[idx],
103972fd0568db0ce5f25a1eee0266ec1e7cb3dafab0Eric Anholt				      3, PROG_PRINT_DEBUG, NULL);
1040cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      }
1041cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell      else
1042298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	 printf("965 Opcode %d\n", insn->Opcode);
1043cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell   }
1044cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell}
1045cb54c056a6d46d03bfa0c4927f5ac8843feab8cdKeith Whitwell
10462f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
10472f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul/**
10482f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * Initial pass for fragment program code generation.
10492f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * This function is used by both the GLSL and non-GLSL paths.
10502f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul */
10519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtvoid brw_wm_pass_fp( struct brw_wm_compile *c )
10529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
1053a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   struct intel_context *intel = &c->func.brw->intel;
10549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct brw_fragment_program *fp = c->fp;
10559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint insn;
10569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1057bb1540835056cdea5db6f55b19c0c87358f14cd1Eric Anholt   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
1058298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("pre-fp:\n");
105972fd0568db0ce5f25a1eee0266ec1e7cb3dafab0Eric Anholt      _mesa_fprint_program_opt(stdout, &fp->program.Base, PROG_PRINT_DEBUG,
10602e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke			       true);
1061298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("\n");
10629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
10639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->pixel_xy = src_undef();
1065a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   if (intel->gen >= 6) {
1066a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt      /* The interpolation deltas come in as the perspective pixel
1067a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt       * location barycentric params.
1068a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt       */
1069a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt      c->delta_xy = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
1070a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   } else {
1071a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt      c->delta_xy = src_undef();
1072a66e9a4d86d227b65874c43fbf9e299c7a26389fEric Anholt   }
10739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->pixel_w = src_undef();
10749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   c->nr_fp_insns = 0;
10759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10762f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Emit preamble instructions.  This is where special instructions such as
10772f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * WM_CINTERP, WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
10782f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * compute shader inputs from varying vars.
10799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
10809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
10819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
10827936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      validate_src_regs(c, inst);
10837936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   }
10842f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
10852f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Loop over all instructions doing assorted simplifications and
10862f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * transformations.
10872f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
10887936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
10897936c614abc165270852bc5e7e316747a9cacdfbZou Nan hai      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
10909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      struct prog_instruction *out;
10919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      /* Check for INPUT values, emit INTERP instructions where
10939f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       * necessary:
10949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt       */
10959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
10969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      switch (inst->Opcode) {
10979f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SWZ:
10989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
10999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_MOV;
11009f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11029f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_ABS:
11039f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11049f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_MOV;
11057db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul	 out->SrcReg[0].Negate = NEGATE_NONE;
11069f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->SrcReg[0].Abs = 1;
11079f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11089f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SUB:
11109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->Opcode = OPCODE_ADD;
11127db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul	 out->SrcReg[1].Negate ^= NEGATE_XYZW;
11139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_SCS:
11169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
11189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
11199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask &= WRITEMASK_XY;
11209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_DST:
11239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_dst(c, inst);
11249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_LIT:
11279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_lit(c, inst);
11289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
112928c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger
1130fa0d5a2c5bfb6109d365a6f0b9bee53dfee50325Eric Anholt      case OPCODE_RSQ:
1131fa0d5a2c5bfb6109d365a6f0b9bee53dfee50325Eric Anholt	 out = emit_scalar_insn(c, inst);
11322e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke	 out->SrcReg[0].Abs = true;
1133fa0d5a2c5bfb6109d365a6f0b9bee53dfee50325Eric Anholt	 break;
1134fa0d5a2c5bfb6109d365a6f0b9bee53dfee50325Eric Anholt
113528c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger      case OPCODE_TEX:
113628c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger	 precalc_tex(c, inst);
113728c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger	 break;
113828c28f72fd9ed192467a3cf913b344951d0bc805Roland Scheidegger
11399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_TXP:
11409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 precalc_txp(c, inst);
11419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1143c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao      case OPCODE_TXB:
1144c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 out = emit_insn(c, inst);
1145c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
1146b7d2023cf99319c71a929c35478dff07d35df392Brian Paul         assert(out->TexSrcUnit < BRW_MAX_TEX_UNIT);
1147c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao	 break;
1148c20a1736566d301f38cc1271284b1fde9adb2741Xiang, Haihao
11499f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_XPD:
11509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
11529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
11539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask &= WRITEMASK_XYZ;
11549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
11569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_KIL:
11579f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out = emit_insn(c, inst);
11589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 /* This should probably be done in the parser.
11599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	  */
11609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 out->DstReg.WriteMask = 0;
11619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11629f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_END:
1163cfa927766ab610a9a76730d337d77008d876ebbdEric Anholt	 emit_render_target_writes(c);
1164d19d0596daf004b56d80f78fa1a329b43c2ebf94Zou Nan hai	 break;
11659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      case OPCODE_PRINT:
11669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      default:
1168536476f2432168fb15ac06b52c953a594ad851adEric Anholt	 if (brw_wm_is_scalar_result(inst->Opcode))
1169536476f2432168fb15ac06b52c953a594ad851adEric Anholt	    emit_scalar_insn(c, inst);
1170536476f2432168fb15ac06b52c953a594ad851adEric Anholt	 else
1171536476f2432168fb15ac06b52c953a594ad851adEric Anholt	    emit_insn(c, inst);
11729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 break;
11739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
11749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
11759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1176bb1540835056cdea5db6f55b19c0c87358f14cd1Eric Anholt   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
1177298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("pass_fp:\n");
11789b78d9f65178648b1888f98153a2f738a281cb84Brian Paul      print_insns( c->prog_instructions, c->nr_fp_insns );
1179298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("\n");
11809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
11819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
11829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
1183