1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org develop this 3D driver.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Permission is hereby granted, free of charge, to any person obtaining
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org distribute, sublicense, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next paragraph) shall be included in all copies or substantial
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org portions of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **********************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  * Authors:
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  *   Keith Whitwell <keith@tungstengraphics.com>
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  */
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "brw_context.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "brw_wm.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcan_do_pln(struct intel_context *intel, const struct brw_reg *deltas)
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_context *brw = brw_context(&intel->ctx);
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!brw->has_pln)
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (deltas[1].nr != deltas[0].nr + 1)
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen < 6 && ((deltas[0].nr & 1) != 0))
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Return the SrcReg index of the channels that can be immediate float operands
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instead of usage of PROGRAM_CONSTANT values through push/pull.
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbrw_wm_arg_can_be_immediate(enum prog_opcode opcode, int arg)
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int opcode_array[] = {
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_ADD] = 2,
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_CMP] = 3,
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_DP3] = 2,
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_DP4] = 2,
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_DPH] = 2,
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_MAX] = 2,
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_MIN] = 2,
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_MOV] = 1,
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_MUL] = 2,
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_SEQ] = 2,
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_SGE] = 2,
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_SGT] = 2,
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_SLE] = 2,
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_SLT] = 2,
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_SNE] = 2,
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_SWZ] = 1,
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      [OPCODE_XPD] = 2,
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* These opcodes get broken down in a way that allow two
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * args to be immediates.
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (opcode == OPCODE_MAD || opcode == OPCODE_LRP) {
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (arg == 1 || arg == 2)
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return true;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (opcode > ARRAY_SIZE(opcode_array))
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return arg == opcode_array[opcode] - 1;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Computes the screen-space x,y position of the pixels.
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This will be used by emit_delta_xy() or emit_wpos_xy() for
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * interpolation of attributes..
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Payload R0:
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R0.0 -- pixel mask, one bit for each of 4 pixels in 4 tiles,
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *         corresponding to each of the 16 execution channels.
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R0.1..8 -- ?
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R1.0 -- triangle vertex 0.X
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R1.1 -- triangle vertex 0.Y
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R1.2 -- tile 0 x,y coords (2 packed uwords)
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R1.3 -- tile 1 x,y coords (2 packed uwords)
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R1.4 -- tile 2 x,y coords (2 packed uwords)
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R1.5 -- tile 3 x,y coords (2 packed uwords)
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R1.6 -- ?
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R1.7 -- ?
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * R1.8 -- ?
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_pixel_xy(struct brw_wm_compile *c,
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const struct brw_reg *dst,
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   GLuint mask)
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg r1 = brw_vec1_grf(1, 0);
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg dst0_uw, dst1_uw;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_push_insn_state(p);
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->dispatch_width == 16) {
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst0_uw = vec16(retype(dst[0], BRW_REGISTER_TYPE_UW));
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst1_uw = vec16(retype(dst[1], BRW_REGISTER_TYPE_UW));
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst0_uw = vec8(retype(dst[0], BRW_REGISTER_TYPE_UW));
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst1_uw = vec8(retype(dst[1], BRW_REGISTER_TYPE_UW));
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Calculate pixel centers by adding 1 or 0 to each of the
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * micro-tile coordinates passed in r1.
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & WRITEMASK_X) {
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_ADD(p,
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      dst0_uw,
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      stride(suboffset(r1_uw, 4), 2, 4, 0),
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      brw_imm_v(0x10101010));
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & WRITEMASK_Y) {
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_ADD(p,
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      dst1_uw,
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      stride(suboffset(r1_uw,5), 2, 4, 0),
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      brw_imm_v(0x11001100));
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_pop_insn_state(p);
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Computes the screen-space x,y distance of the pixels from the start
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vertex.
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This will be used in linterp or pinterp with the start vertex value
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and the Cx, Cy, and C0 coefficients passed in from the setup engine
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to produce interpolated attribute values.
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_delta_xy(struct brw_compile *p,
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const struct brw_reg *dst,
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   GLuint mask,
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const struct brw_reg *arg0)
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg r1 = brw_vec1_grf(1, 0);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask == 0)
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(mask == WRITEMASK_XY);
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 6) {
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       /* XXX Gen6 WM doesn't have Xstart/Ystart in payload r1.0/r1.1.
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  Just add them with 0.0 for dst reg.. */
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       r1 = brw_imm_v(0x00000000);
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       brw_ADD(p,
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       dst[0],
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       retype(arg0[0], BRW_REGISTER_TYPE_UW),
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       r1);
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       brw_ADD(p,
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       dst[1],
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       retype(arg0[1], BRW_REGISTER_TYPE_UW),
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       r1);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Calc delta X,Y by subtracting origin in r1 from the pixel
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * centers produced by emit_pixel_xy().
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_ADD(p,
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   dst[0],
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   retype(arg0[0], BRW_REGISTER_TYPE_UW),
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   negate(r1));
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_ADD(p,
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   dst[1],
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   retype(arg0[1], BRW_REGISTER_TYPE_UW),
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   negate(suboffset(r1,1)));
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Computes the pixel offset from the window origin for gl_FragCoord().
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_wpos_xy(struct brw_wm_compile *c,
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *dst,
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  GLuint mask,
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *arg0)
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg delta_x = retype(arg0[0], BRW_REGISTER_TYPE_W);
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg delta_y = retype(arg0[1], BRW_REGISTER_TYPE_W);
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & WRITEMASK_X) {
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (intel->gen >= 6) {
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 struct brw_reg delta_x_f = retype(delta_x, BRW_REGISTER_TYPE_F);
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, delta_x_f, delta_x);
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 delta_x = delta_x_f;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->fp->program.PixelCenterInteger) {
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* X' = X */
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[0], delta_x);
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* X' = X + 0.5 */
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_ADD(p, dst[0], delta_x, brw_imm_f(0.5));
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & WRITEMASK_Y) {
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (intel->gen >= 6) {
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 struct brw_reg delta_y_f = retype(delta_y, BRW_REGISTER_TYPE_F);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, delta_y_f, delta_y);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 delta_y = delta_y_f;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->fp->program.OriginUpperLeft) {
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (c->fp->program.PixelCenterInteger) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* Y' = Y */
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_MOV(p, dst[1], delta_y);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_ADD(p, dst[1], delta_y, brw_imm_f(0.5));
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 float center_offset = c->fp->program.PixelCenterInteger ? 0.0 : 0.5;
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Y' = (height - 1) - Y + center */
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_ADD(p, dst[1], negate(delta_y),
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 brw_imm_f(c->key.drawable_height - 1 + center_offset));
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_pixel_w(struct brw_wm_compile *c,
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *dst,
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  GLuint mask,
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *arg0,
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *deltas)
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg src;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg temp_dst;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 6)
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	temp_dst = dst[3];
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	temp_dst = brw_message_reg(2);
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(intel->gen < 6);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Don't need this if all you are doing is interpolating color, for
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * instance.
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & WRITEMASK_W) {
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct brw_reg interp3 = brw_vec1_grf(arg0[0].nr+1, 4);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Calc 1/w - just linterp wpos[3] optimized by putting the
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * result straight into a message reg.
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (can_do_pln(intel, deltas)) {
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_PLN(p, temp_dst, interp3, deltas[0]);
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_LINE(p, brw_null_reg(), interp3, deltas[0]);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MAC(p, temp_dst, suboffset(interp3, 1), deltas[1]);
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Calc w */
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (intel->gen >= 6)
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 src = temp_dst;
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 src = brw_null_reg();
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->dispatch_width == 16) {
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_math_16(p, dst[3],
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     BRW_MATH_FUNCTION_INV,
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     2, src,
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     BRW_MATH_PRECISION_FULL);
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_math(p, dst[3],
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  BRW_MATH_FUNCTION_INV,
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  2, src,
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  BRW_MATH_DATA_VECTOR,
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  BRW_MATH_PRECISION_FULL);
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_linterp(struct brw_compile *p,
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *dst,
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  GLuint mask,
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *arg0,
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *deltas)
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg interp[4];
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint nr = arg0[0].nr;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[0] = brw_vec1_grf(nr, 0);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[1] = brw_vec1_grf(nr, 4);
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[2] = brw_vec1_grf(nr+1, 0);
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[3] = brw_vec1_grf(nr+1, 4);
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (intel->gen >= 6) {
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_PLN(p, dst[i], interp[i], brw_vec8_grf(2, 0));
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else if (can_do_pln(intel, deltas)) {
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_PLN(p, dst[i], interp[i], deltas[0]);
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_LINE(p, brw_null_reg(), interp[i], deltas[0]);
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_MAC(p, dst[i], suboffset(interp[i],1), deltas[1]);
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_pinterp(struct brw_compile *p,
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *dst,
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  GLuint mask,
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *arg0,
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *deltas,
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *w)
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg interp[4];
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint nr = arg0[0].nr;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 6) {
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_linterp(p, dst, mask, arg0, interp);
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[0] = brw_vec1_grf(nr, 0);
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[1] = brw_vec1_grf(nr, 4);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[2] = brw_vec1_grf(nr+1, 0);
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[3] = brw_vec1_grf(nr+1, 4);
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (can_do_pln(intel, deltas)) {
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_PLN(p, dst[i], interp[i], deltas[0]);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_LINE(p, brw_null_reg(), interp[i], deltas[0]);
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_MAC(p, dst[i], suboffset(interp[i],1), deltas[1]);
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MUL(p, dst[i], dst[i], w[3]);
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_cinterp(struct brw_compile *p,
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *dst,
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  GLuint mask,
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct brw_reg *arg0)
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg interp[4];
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint nr = arg0[0].nr;
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[0] = brw_vec1_grf(nr, 0);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[1] = brw_vec1_grf(nr, 4);
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[2] = brw_vec1_grf(nr+1, 0);
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   interp[3] = brw_vec1_grf(nr+1, 4);
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         brw_MOV(p, dst[i], suboffset(interp[i],3));	/* TODO: optimize away like other moves */
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Sets the destination channels to 1.0 or 0.0 according to glFrontFacing. */
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_frontfacing(struct brw_compile *p,
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *dst,
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint mask)
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(mask & WRITEMASK_XYZW))
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[i], brw_imm_f(0.0));
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* bit 31 is "primitive is back face", so checking < (1 << 31) gives
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * us front face
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, r1_6ud, brw_imm_ud(1 << 31));
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[i], brw_imm_f(1.0));
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_predicate_control_flag_value(p, 0xff);
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* For OPCODE_DDX and OPCODE_DDY, per channel of output we've got input
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * looking like:
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * arg0: ss0.tl ss0.tr ss0.bl ss0.br ss1.tl ss1.tr ss1.bl ss1.br
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and we're trying to produce:
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *           DDX                     DDY
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * dst: (ss0.tr - ss0.tl)     (ss0.tl - ss0.bl)
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      (ss0.tr - ss0.tl)     (ss0.tr - ss0.br)
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      (ss0.br - ss0.bl)     (ss0.tl - ss0.bl)
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      (ss0.br - ss0.bl)     (ss0.tr - ss0.br)
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      (ss1.tr - ss1.tl)     (ss1.tl - ss1.bl)
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      (ss1.tr - ss1.tl)     (ss1.tr - ss1.br)
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      (ss1.br - ss1.bl)     (ss1.tl - ss1.bl)
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      (ss1.br - ss1.bl)     (ss1.tr - ss1.br)
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and add another set of two more subspans if in 16-pixel dispatch mode.
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For DDX, it ends up being easy: width = 2, horiz=0 gets us the same result
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for each pair, and vertstride = 2 jumps us 2 elements after processing a
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pair. But for DDY, it's harder, as we want to produce the pairs swizzled
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * between each other.  We could probably do it like ddx and swizzle the right
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * order later, but bail for now and just produce
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ((ss0.tl - ss0.bl)x4 (ss1.tl - ss1.bl)x4)
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The negate_value boolean is used to negate the d/dy computation for FBOs,
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * since they place the origin at the upper left instead of the lower left.
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_ddxy(struct brw_compile *p,
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       const struct brw_reg *dst,
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       GLuint mask,
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       bool is_ddx,
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       const struct brw_reg *arg0,
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               bool negate_value)
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg src0, src1;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & SATURATE)
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, 1);
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++ ) {
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (is_ddx) {
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src0 = brw_reg(arg0[i].file, arg0[i].nr, 1,
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_REGISTER_TYPE_F,
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_VERTICAL_STRIDE_2,
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_WIDTH_2,
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_HORIZONTAL_STRIDE_0,
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src1 = brw_reg(arg0[i].file, arg0[i].nr, 0,
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_REGISTER_TYPE_F,
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_VERTICAL_STRIDE_2,
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_WIDTH_2,
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_HORIZONTAL_STRIDE_0,
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src0 = brw_reg(arg0[i].file, arg0[i].nr, 0,
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_REGISTER_TYPE_F,
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_VERTICAL_STRIDE_4,
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_WIDTH_4,
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_HORIZONTAL_STRIDE_0,
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src1 = brw_reg(arg0[i].file, arg0[i].nr, 2,
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_REGISTER_TYPE_F,
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_VERTICAL_STRIDE_4,
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_WIDTH_4,
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_HORIZONTAL_STRIDE_0,
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (negate_value)
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            brw_ADD(p, dst[i], src1, negate(src0));
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            brw_ADD(p, dst[i], src0, negate(src1));
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & SATURATE)
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, 0);
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_alu1(struct brw_compile *p,
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       struct brw_instruction *(*func)(struct brw_compile *,
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       struct brw_reg,
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       struct brw_reg),
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       const struct brw_reg *dst,
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       GLuint mask,
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       const struct brw_reg *arg0)
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & SATURATE)
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, 1);
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 func(p, dst[i], arg0[i]);
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & SATURATE)
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, 0);
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_alu2(struct brw_compile *p,
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       struct brw_instruction *(*func)(struct brw_compile *,
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       struct brw_reg,
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       struct brw_reg,
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       struct brw_reg),
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       const struct brw_reg *dst,
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       GLuint mask,
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       const struct brw_reg *arg0,
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       const struct brw_reg *arg1)
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & SATURATE)
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, 1);
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 func(p, dst[i], arg0[i], arg1[i]);
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & SATURATE)
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, 0);
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_mad(struct brw_compile *p,
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1,
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg2)
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MUL(p, dst[i], arg0[i], arg1[i]);
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_ADD(p, dst[i], dst[i], arg2[i]);
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, 0);
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_lrp(struct brw_compile *p,
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1,
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg2)
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Uses dst as a temporary:
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Can I use the LINE instruction for this?
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_ADD(p, dst[i], negate(arg0[i]), brw_imm_f(1.0));
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MUL(p, brw_null_reg(), dst[i], arg2[i]);
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MAC(p, dst[i], arg0[i], arg1[i]);
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, 0);
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_sop(struct brw_compile *p,
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint cond,
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1)
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_push_insn_state(p);
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_CMP(p, brw_null_reg(), cond, arg0[i], arg1[i]);
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[i], brw_imm_f(0));
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[i], brw_imm_f(1.0));
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_pop_insn_state(p);
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_slt( struct brw_compile *p,
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *dst,
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint mask,
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg0,
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg1 )
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_sop(p, dst, mask, BRW_CONDITIONAL_L, arg0, arg1);
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_sle( struct brw_compile *p,
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *dst,
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint mask,
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg0,
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg1 )
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_sop(p, dst, mask, BRW_CONDITIONAL_LE, arg0, arg1);
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_sgt( struct brw_compile *p,
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *dst,
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint mask,
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg0,
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg1 )
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_sop(p, dst, mask, BRW_CONDITIONAL_G, arg0, arg1);
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_sge( struct brw_compile *p,
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *dst,
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint mask,
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg0,
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg1 )
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_sop(p, dst, mask, BRW_CONDITIONAL_GE, arg0, arg1);
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_seq( struct brw_compile *p,
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *dst,
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint mask,
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg0,
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg1 )
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_sop(p, dst, mask, BRW_CONDITIONAL_EQ, arg0, arg1);
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_sne( struct brw_compile *p,
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *dst,
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint mask,
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg0,
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct brw_reg *arg1 )
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_sop(p, dst, mask, BRW_CONDITIONAL_NEQ, arg0, arg1);
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_cmp(struct brw_compile *p,
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1,
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg2)
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], brw_imm_f(0));
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_SEL(p, dst[i], arg1[i], arg2[i]);
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, 0);
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_predicate_control_flag_value(p, 0xff);
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_sign(struct brw_compile *p,
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       const struct brw_reg *dst,
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       GLuint mask,
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       const struct brw_reg *arg0)
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[i], brw_imm_f(0.0));
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], brw_imm_f(0));
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[i], brw_imm_f(-1.0));
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, arg0[i], brw_imm_f(0));
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[i], brw_imm_f(1.0));
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_max(struct brw_compile *p,
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1)
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], arg1[i]);
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_SEL(p, dst[i], arg0[i], arg1[i]);
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, 0);
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_predicate_control_flag_value(p, 0xff);
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_min(struct brw_compile *p,
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1)
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], arg1[i]);
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_SEL(p, dst[i], arg0[i], arg1[i]);
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, 0);
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_predicate_control_flag_value(p, 0xff);
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_dp2(struct brw_compile *p,
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1)
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(mask & WRITEMASK_XYZW))
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; /* Do not emit dead code */
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(is_power_of_two(mask & WRITEMASK_XYZW));
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MAC(p, dst[dst_chan], arg0[1], arg1[1]);
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, 0);
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_dp3(struct brw_compile *p,
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1)
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(mask & WRITEMASK_XYZW))
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; /* Do not emit dead code */
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(is_power_of_two(mask & WRITEMASK_XYZW));
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MAC(p, dst[dst_chan], arg0[2], arg1[2]);
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, 0);
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_dp4(struct brw_compile *p,
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1)
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(mask & WRITEMASK_XYZW))
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; /* Do not emit dead code */
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(is_power_of_two(mask & WRITEMASK_XYZW));
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MAC(p, brw_null_reg(), arg0[2], arg1[2]);
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MAC(p, dst[dst_chan], arg0[3], arg1[3]);
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, 0);
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_dph(struct brw_compile *p,
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1)
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(mask & WRITEMASK_XYZW))
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; /* Do not emit dead code */
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(is_power_of_two(mask & WRITEMASK_XYZW));
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MAC(p, dst[dst_chan], arg0[2], arg1[2]);
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_ADD(p, dst[dst_chan], dst[dst_chan], arg1[3]);
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, 0);
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_xpd(struct brw_compile *p,
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *dst,
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint mask,
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg0,
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct brw_reg *arg1)
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert((mask & WRITEMASK_W) != WRITEMASK_W);
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0 ; i < 3; i++) {
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & (1<<i)) {
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 GLuint i2 = (i+2)%3;
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 GLuint i1 = (i+1)%3;
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MUL(p, brw_null_reg(), negate(arg0[i2]), arg1[i1]);
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MAC(p, dst[i], arg0[i1], arg1[i2]);
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, 0);
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_math1(struct brw_wm_compile *c,
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GLuint function,
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct brw_reg *dst,
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GLuint mask,
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct brw_reg *arg0)
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg src;
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(mask & WRITEMASK_XYZW))
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; /* Do not emit dead code */
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(is_power_of_two(mask & WRITEMASK_XYZW));
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 6 && ((arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0 ||
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    arg0[0].file != BRW_GENERAL_REGISTER_FILE) ||
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   arg0[0].negate || arg0[0].abs)) {
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Gen6 math requires that source and dst horizontal stride be 1,
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * and that the argument be in the GRF.
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * The hardware ignores source modifiers (negate and abs) on math
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * instructions, so we also move to a temp to set those up.
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src = dst[dst_chan];
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, src, arg0[0]);
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src = arg0[0];
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Send two messages to perform all 16 operations:
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_push_insn_state(p);
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_math(p,
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    dst[dst_chan],
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    function,
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    2,
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src,
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    BRW_MATH_DATA_VECTOR,
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    BRW_MATH_PRECISION_FULL);
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->dispatch_width == 16) {
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_math(p,
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       offset(dst[dst_chan],1),
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       function,
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       3,
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       sechalf(src),
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       BRW_MATH_DATA_VECTOR,
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       BRW_MATH_PRECISION_FULL);
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_pop_insn_state(p);
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_math2(struct brw_wm_compile *c,
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GLuint function,
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct brw_reg *dst,
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GLuint mask,
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct brw_reg *arg0,
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct brw_reg *arg1)
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(mask & WRITEMASK_XYZW))
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; /* Do not emit dead code */
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(is_power_of_two(mask & WRITEMASK_XYZW));
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_push_insn_state(p);
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* math can only operate on up to a vec8 at a time, so in
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * dispatch_width==16 we have to do the second half manually.
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 6) {
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct brw_reg src0 = arg0[0];
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct brw_reg src1 = arg1[0];
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct brw_reg temp_dst = dst[dst_chan];
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0) {
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, temp_dst, src0);
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 src0 = temp_dst;
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (arg1[0].hstride == BRW_HORIZONTAL_STRIDE_0) {
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* This is a heinous hack to get a temporary register for use
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * in case both arg0 and arg1 are constants.  Why you're
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * doing exponentiation on constant values in the shader, we
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * don't know.
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * max_wm_grf is almost surely less than the maximum GRF, and
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * gen6 doesn't care about the number of GRFs used in a
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * shader like pre-gen6 did.
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 struct brw_reg temp = brw_vec8_grf(c->max_wm_grf, 0);
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, temp, src1);
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 src1 = temp;
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_math2(p,
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		temp_dst,
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		function,
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		src0,
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		src1);
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->dispatch_width == 16) {
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_math2(p,
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   sechalf(temp_dst),
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   function,
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   sechalf(src0),
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   sechalf(src1));
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(3), arg1[0]);
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->dispatch_width == 16) {
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, brw_message_reg(5), sechalf(arg1[0]));
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_math(p,
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       dst[dst_chan],
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       function,
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       2,
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       arg0[0],
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       BRW_MATH_DATA_VECTOR,
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       BRW_MATH_PRECISION_FULL);
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Send two messages to perform all 16 operations:
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->dispatch_width == 16) {
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_math(p,
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  offset(dst[dst_chan],1),
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  function,
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  4,
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  sechalf(arg0[0]),
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  BRW_MATH_DATA_VECTOR,
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  BRW_MATH_PRECISION_FULL);
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_pop_insn_state(p);
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_tex(struct brw_wm_compile *c,
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      struct brw_reg *dst,
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint dst_flags,
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      struct brw_reg *arg,
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      struct brw_reg depth_payload,
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint tex_idx,
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint sampler,
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      bool shadow)
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg dst_retyped;
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint cur_mrf = 2, response_length;
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i, nr_texcoords;
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint emit;
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint msg_type;
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint mrf_per_channel;
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint simd_mode;
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->dispatch_width == 16) {
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mrf_per_channel = 2;
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      response_length = 8;
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst_retyped = retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW);
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mrf_per_channel = 1;
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      response_length = 4;
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst_retyped = retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW);
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD8;
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* How many input regs are there?
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (tex_idx) {
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_1D_INDEX:
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit = WRITEMASK_X;
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr_texcoords = 1;
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_2D_INDEX:
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_1D_ARRAY_INDEX:
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_RECT_INDEX:
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_EXTERNAL_INDEX:
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit = WRITEMASK_XY;
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr_texcoords = 2;
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_3D_INDEX:
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_2D_ARRAY_INDEX:
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_CUBE_INDEX:
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit = WRITEMASK_XYZ;
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr_texcoords = 3;
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* unexpected target */
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Pre-Ironlake, the 8-wide sampler always took u,v,r. */
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen < 5 && c->dispatch_width == 8)
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr_texcoords = 3;
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shadow) {
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (intel->gen < 7) {
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* For shadow comparisons, we have to supply u,v,r. */
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 nr_texcoords = 3;
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* On Ivybridge, the shadow comparitor comes first. Just load it. */
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, brw_message_reg(cur_mrf), arg[2]);
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 cur_mrf += mrf_per_channel;
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Emit the texcoords. */
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < nr_texcoords; i++) {
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->key.tex.gl_clamp_mask[i] & (1 << sampler))
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_saturate(p, true);
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit & (1<<i))
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, brw_message_reg(cur_mrf), arg[i]);
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, brw_message_reg(cur_mrf), brw_imm_f(0));
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cur_mrf += mrf_per_channel;
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, false);
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Fill in the shadow comparison reference value. */
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shadow && intel->gen < 7) {
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (intel->gen >= 5) {
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Fill in the cube map array index value. */
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, brw_message_reg(cur_mrf), brw_imm_f(0));
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 cur_mrf += mrf_per_channel;
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (c->dispatch_width == 8) {
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Fill in the LOD bias value. */
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, brw_message_reg(cur_mrf), brw_imm_f(0));
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 cur_mrf += mrf_per_channel;
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(cur_mrf), arg[2]);
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cur_mrf += mrf_per_channel;
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 5) {
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shadow)
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_COMPARE;
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE;
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Note that G45 and older determines shadow compare and dispatch width
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * from message length for most messages.
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->dispatch_width == 16 && shadow)
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_SAMPLE(p,
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      dst_retyped,
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      1,
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      retype(depth_payload, BRW_REGISTER_TYPE_UW),
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              SURF_INDEX_TEXTURE(sampler),
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      sampler,
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      dst_flags & WRITEMASK_XYZW,
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      msg_type,
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      response_length,
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      cur_mrf - 1,
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      1,
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      simd_mode,
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      BRW_SAMPLER_RETURN_FORMAT_FLOAT32);
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_txb(struct brw_wm_compile *c,
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      struct brw_reg *dst,
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint dst_flags,
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      struct brw_reg *arg,
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      struct brw_reg depth_payload,
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint tex_idx,
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      GLuint sampler)
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint msgLength;
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint msg_type;
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint mrf_per_channel;
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint response_length;
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg dst_retyped;
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* The G45 and older chipsets don't support 8-wide dispatch for LOD biased
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * samples, so we'll use the 16-wide instruction, leave the second halves
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * undefined, and trust the execution mask to keep the undefined pixels
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * from mattering.
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->dispatch_width == 16 || intel->gen < 5) {
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (intel->gen >= 5)
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS;
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mrf_per_channel = 2;
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst_retyped = retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW);
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      response_length = 8;
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS;
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mrf_per_channel = 1;
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst_retyped = retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW);
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      response_length = 4;
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Shadow ignored for txb. */
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (tex_idx) {
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_1D_INDEX:
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(2 + 0 * mrf_per_channel), arg[0]);
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(2 + 1 * mrf_per_channel), brw_imm_f(0));
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(2 + 2 * mrf_per_channel), brw_imm_f(0));
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_2D_INDEX:
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_RECT_INDEX:
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_EXTERNAL_INDEX:
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(2 + 0 * mrf_per_channel), arg[0]);
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(2 + 1 * mrf_per_channel), arg[1]);
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(2 + 2 * mrf_per_channel), brw_imm_f(0));
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_3D_INDEX:
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TEXTURE_CUBE_INDEX:
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(2 + 0 * mrf_per_channel), arg[0]);
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(2 + 1 * mrf_per_channel), arg[1]);
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, brw_message_reg(2 + 2 * mrf_per_channel), arg[2]);
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* unexpected target */
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MOV(p, brw_message_reg(2 + 3 * mrf_per_channel), arg[3]);
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   msgLength = 2 + 4 * mrf_per_channel - 1;
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_SAMPLE(p,
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      dst_retyped,
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      1,
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      retype(depth_payload, BRW_REGISTER_TYPE_UW),
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              SURF_INDEX_TEXTURE(sampler),
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      sampler,
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      dst_flags & WRITEMASK_XYZW,
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      msg_type,
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      response_length,
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      msgLength,
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      1,
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      BRW_SAMPLER_SIMD_MODE_SIMD16,
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      BRW_SAMPLER_RETURN_FORMAT_FLOAT32);
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_lit(struct brw_wm_compile *c,
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     const struct brw_reg *dst,
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     GLuint mask,
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     const struct brw_reg *arg0)
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert((mask & WRITEMASK_XW) == 0);
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & WRITEMASK_Y) {
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, dst[1], arg0[0]);
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, 0);
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask & WRITEMASK_Z) {
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_math2(c, BRW_MATH_FUNCTION_POW,
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 &dst[2],
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 WRITEMASK_X | (mask & SATURATE),
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 &arg0[1],
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 &arg0[3]);
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Ordinarily you'd use an iff statement to skip or shortcircuit
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * some of the POW calculations above, but 16-wide iff statements
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * seem to lock c1 hardware, so this is a nasty workaround:
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_LE, arg0[0], brw_imm_f(0));
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & WRITEMASK_Y)
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[1], brw_imm_f(0));
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask & WRITEMASK_Z)
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, dst[2], brw_imm_f(0));
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Kill pixel - set execution mask to zero for those pixels which
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * fail.
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_kil( struct brw_wm_compile *c,
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      struct brw_reg *arg0)
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg pixelmask;
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i, j;
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 6)
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pixelmask = retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UW);
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pixelmask = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Check if we've already done the comparison for this reg
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * -- common when someone does KIL TEMP.wwww.
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j = 0; j < i; j++) {
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (memcmp(&arg0[j], &arg0[i], sizeof(arg0[0])) == 0)
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (j != i)
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 continue;
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_push_insn_state(p);
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], brw_imm_f(0));
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_predicate_control_flag_value(p, 0xff);
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_AND(p, pixelmask, brw_flag_reg(), pixelmask);
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_pop_insn_state(p);
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void fire_fb_write( struct brw_wm_compile *c,
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   GLuint base_reg,
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   GLuint nr,
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   GLuint target,
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   GLuint eot )
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t msg_control;
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Pass through control information:
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Gen6 has done m1 mov in emit_fb_write() for current SIMD16 case.
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*  mov (8) m1.0<1>:ud   r1.0<8;8,1>:ud   { Align1 NoMask } */
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen < 6)
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_push_insn_state(p);
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p,
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       brw_message_reg(base_reg + 1),
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       brw_vec8_grf(1, 0));
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_pop_insn_state(p);
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->dispatch_width == 16)
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE;
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01;
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Send framebuffer write message: */
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*  send (16) null.0<1>:uw m0               r0.0<8;8,1>:uw   0x85a04000:ud    { Align1 EOT } */
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_fb_WRITE(p,
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		c->dispatch_width,
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		base_reg,
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		msg_control,
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		target,
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		nr,
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		0,
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		eot,
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		true);
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_aa( struct brw_wm_compile *c,
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     struct brw_reg *arg1,
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     GLuint reg )
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint comp = c->aa_dest_stencil_reg / 2;
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint off = c->aa_dest_stencil_reg % 2;
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_reg aa = offset(arg1[comp], off);
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_push_insn_state(p);
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_compression_control(p, BRW_COMPRESSION_NONE); /* ?? */
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MOV(p, brw_message_reg(reg), aa);
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_pop_insn_state(p);
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Post-fragment-program processing.  Send the results to the
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * framebuffer.
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param arg0  the fragment color
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param arg1  the pass-through depth value
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param arg2  the shader-computed depth value
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid emit_fb_write(struct brw_wm_compile *c,
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   struct brw_reg *arg0,
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   struct brw_reg *arg1,
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   struct brw_reg *arg2,
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   GLuint target,
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   GLuint eot)
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_context *brw = p->brw;
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &brw->intel;
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint nr = 2;
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint channel;
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Reserve a space for AA - may not be needed:
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->aa_dest_stencil_reg)
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr += 1;
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* I don't really understand how this achieves the color interleave
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * (ie RGBARGBA) in the result:  [Do the saturation here]
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_push_insn_state(p);
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->key.clamp_fragment_color)
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_saturate(p, 1);
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (channel = 0; channel < 4; channel++) {
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (intel->gen >= 6) {
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* gen6 SIMD16 single source DP write looks like:
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 0: r0
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 1: r1
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 2: g0
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 3: g1
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 4: b0
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 5: b1
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 6: a0
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 7: a1
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (c->dispatch_width == 16) {
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_MOV(p, brw_message_reg(nr + channel * 2), arg0[channel]);
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_MOV(p, brw_message_reg(nr + channel), arg0[channel]);
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (c->dispatch_width == 16 && brw->has_compr4) {
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* pre-gen6 SIMD16 single source DP write looks like:
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 0: r0
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 1: g0
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 2: b0
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 3: a0
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 4: r1
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 5: g1
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 6: b1
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * m + 7: a1
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * By setting the high bit of the MRF register number, we indicate
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * that we want COMPR4 mode - instead of doing the usual destination
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * + 1 for the second half we get destination + 4.
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p,
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 brw_message_reg(nr + channel + BRW_MRF_COMPR4),
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 arg0[channel]);
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /*  mov (8) m2.0<1>:ud   r28.0<8;8,1>:ud  { Align1 } */
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /*  mov (8) m6.0<1>:ud   r29.0<8;8,1>:ud  { Align1 SecHalf } */
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p,
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 brw_message_reg(nr + channel),
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 arg0[channel]);
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (c->dispatch_width == 16) {
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    brw_MOV(p,
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    brw_message_reg(nr + channel + 4),
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    sechalf(arg0[channel]));
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_saturate(p, 0);
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* skip over the regs populated above:
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->dispatch_width == 16)
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr += 8;
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr += 4;
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_pop_insn_state(p);
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->source_depth_to_render_target)
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->computes_depth)
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, brw_message_reg(nr), arg2[2]);
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, brw_message_reg(nr), arg1[1]); /* ? */
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr += 2;
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (c->dest_depth_reg)
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint comp = c->dest_depth_reg / 2;
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint off = c->dest_depth_reg % 2;
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (off != 0) {
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         brw_push_insn_state(p);
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         brw_MOV(p, brw_message_reg(nr), offset(arg1[comp],1));
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* 2nd half? */
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         brw_MOV(p, brw_message_reg(nr+1), arg1[comp+1]);
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         brw_pop_insn_state(p);
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         brw_MOV(p, brw_message_reg(nr), arg1[comp]);
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr += 2;
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 6) {
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Load the message header.  There's no implied move from src0
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * to the base mrf on gen6.
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_push_insn_state(p);
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_mask_control(p, BRW_MASK_DISABLE);
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, retype(brw_message_reg(0), BRW_REGISTER_TYPE_UD),
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_pop_insn_state(p);
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (target != 0) {
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_MOV(p, retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE,
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					0,
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					2), BRW_REGISTER_TYPE_UD),
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 brw_imm_ud(target));
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!c->runtime_check_aads_emit) {
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (c->aa_dest_stencil_reg)
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_aa(c, arg1, 2);
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fire_fb_write(c, 0, nr, target, eot);
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct brw_reg ip = brw_ip_reg();
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int jmp;
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_AND(p,
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      v1_null_ud,
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      get_element_ud(brw_vec8_grf(1,0), 6),
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      brw_imm_ud(1<<26));
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)) - p->store;
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_aa(c, arg1, 2);
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 fire_fb_write(c, 0, nr, target, eot);
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* note - thread killed in subroutine */
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_land_fwd_jump(p, jmp);
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* ELSE: Shuffle up one register to fill in the hole left for AA:
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fire_fb_write(c, 1, nr-1, target, eot);
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Move a GPR to scratch memory.
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_spill( struct brw_wm_compile *c,
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct brw_reg reg,
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			GLuint slot )
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mov (16) m2.0<1>:ud   r2.0<8;8,1>:ud   { Align1 Compr }
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   */
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_MOV(p, brw_message_reg(2), reg);
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mov (1) r0.2<1>:d    0x00000080:d     { Align1 NoMask }
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     send (16) null.0<1>:uw m1               r0.0<8;8,1>:uw   0x053003ff:ud    { Align1 }
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   */
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_oword_block_write_scratch(p, brw_message_reg(1), 2, slot);
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Load a GPR from scratch memory.
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_unspill( struct brw_wm_compile *c,
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct brw_reg reg,
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  GLuint slot )
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Slot 0 is the undef value.
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (slot == 0) {
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      brw_MOV(p, reg, brw_imm_f(0));
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     mov (1) r0.2<1>:d    0x000000c0:d     { Align1 NoMask }
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     send (16) r110.0<1>:uw m1               r0.0<8;8,1>:uw   0x041243ff:ud    { Align1 }
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   */
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_oword_block_read(p, vec16(reg), brw_message_reg(1), 2, slot);
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Retrieve up to 4 GEN4 register pairs for the given wm reg:
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Args with unspill_reg != 0 will be loaded from scratch memory.
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void get_argument_regs( struct brw_wm_compile *c,
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       struct brw_wm_ref *arg[],
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       struct brw_reg *regs )
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (arg[i]) {
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (arg[i]->unspill_reg)
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    emit_unspill(c,
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 brw_vec8_grf(arg[i]->unspill_reg, 0),
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 arg[i]->value->spill_slot);
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 regs[i] = arg[i]->hw_reg;
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 regs[i] = brw_null_reg();
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For values that have a spill_slot!=0, write those regs to scratch memory.
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void spill_values( struct brw_wm_compile *c,
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct brw_wm_value *values,
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  GLuint nr )
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < nr; i++)
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (values[i].spill_slot)
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_spill(c, values[i].hw_reg, values[i].spill_slot);
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Emit the fragment program instructions here.
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid brw_wm_emit( struct brw_wm_compile *c )
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct brw_compile *p = &c->func;
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = &p->brw->intel;
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint insn;
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 6)
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	brw_set_acc_write_control(p, 1);
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Check if any of the payload regs need to be spilled:
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spill_values(c, c->payload.depth, 4);
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spill_values(c, c->creg, c->nr_creg);
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   spill_values(c, c->payload.input_interp, FRAG_ATTRIB_MAX);
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (insn = 0; insn < c->nr_insns; insn++) {
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct brw_wm_instruction *inst = &c->instruction[insn];
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct brw_reg args[3][4], dst[4];
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint i, dst_flags;
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Get argument regs:
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < 3; i++)
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 get_argument_regs(c, inst->src[i], args[i]);
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Get dest regs:
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < 4; i++)
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (inst->dst[i])
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    dst[i] = inst->dst[i]->hw_reg;
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 else
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    dst[i] = brw_null_reg();
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Flags
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst_flags = inst->writemask;
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->saturate)
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 dst_flags |= SATURATE;
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (inst->opcode) {
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Generated instructions for calculating triangle interpolants:
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case WM_PIXELXY:
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_pixel_xy(c, dst, dst_flags);
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case WM_DELTAXY:
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_delta_xy(p, dst, dst_flags, args[0]);
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case WM_WPOSXY:
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_wpos_xy(c, dst, dst_flags, args[0]);
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case WM_PIXELW:
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_pixel_w(c, dst, dst_flags, args[0], args[1]);
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case WM_LINTERP:
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_linterp(p, dst, dst_flags, args[0], args[1]);
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case WM_PINTERP:
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_pinterp(p, dst, dst_flags, args[0], args[1], args[2]);
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case WM_CINTERP:
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_cinterp(p, dst, dst_flags, args[0]);
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case WM_FB_WRITE:
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_fb_write(c, args[0], args[1], args[2], inst->target, inst->eot);
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case WM_FRONTFACING:
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_frontfacing(p, dst, dst_flags);
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Straightforward arithmetic:
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_ADD:
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_alu2(p, brw_ADD, dst, dst_flags, args[0], args[1]);
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_FRC:
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_alu1(p, brw_FRC, dst, dst_flags, args[0]);
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_FLR:
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]);
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DDX:
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_ddxy(p, dst, dst_flags, true, args[0], false);
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DDY:
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Make sure fp->program.UsesDFdy flag got set (otherwise there's no
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * guarantee that c->key.render_to_fbo is set).
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(c->fp->program.UsesDFdy);
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_ddxy(p, dst, dst_flags, false, args[0], c->key.render_to_fbo);
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DP2:
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_dp2(p, dst, dst_flags, args[0], args[1]);
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DP3:
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_dp3(p, dst, dst_flags, args[0], args[1]);
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DP4:
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_dp4(p, dst, dst_flags, args[0], args[1]);
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DPH:
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_dph(p, dst, dst_flags, args[0], args[1]);
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TRUNC:
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (i = 0; i < 4; i++) {
1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (dst_flags & (1<<i)) {
1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       brw_RNDZ(p, dst[i], args[0][i]);
1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_LRP:
1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_lrp(p, dst, dst_flags, args[0], args[1], args[2]);
1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MAD:
1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_mad(p, dst, dst_flags, args[0], args[1], args[2]);
1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MOV:
1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SWZ:
1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_alu1(p, brw_MOV, dst, dst_flags, args[0]);
1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MUL:
1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_alu2(p, brw_MUL, dst, dst_flags, args[0], args[1]);
1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_XPD:
1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_xpd(p, dst, dst_flags, args[0], args[1]);
1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Higher math functions:
1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_RCP:
1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_math1(c, BRW_MATH_FUNCTION_INV, dst, dst_flags, args[0]);
1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_RSQ:
1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, dst_flags, args[0]);
1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SIN:
1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_math1(c, BRW_MATH_FUNCTION_SIN, dst, dst_flags, args[0]);
1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_COS:
1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_math1(c, BRW_MATH_FUNCTION_COS, dst, dst_flags, args[0]);
1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_EX2:
1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, dst_flags, args[0]);
1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_LG2:
1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]);
1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SCS:
1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* There is an scs math function, but it would need some
1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * fixup for 16-element execution.
1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (dst_flags & WRITEMASK_X)
1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    emit_math1(c, BRW_MATH_FUNCTION_COS, dst, (dst_flags&SATURATE)|WRITEMASK_X, args[0]);
1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (dst_flags & WRITEMASK_Y)
1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    emit_math1(c, BRW_MATH_FUNCTION_SIN, dst+1, (dst_flags&SATURATE)|WRITEMASK_X, args[0]);
1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_POW:
1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_math2(c, BRW_MATH_FUNCTION_POW, dst, dst_flags, args[0], args[1]);
1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Comparisons:
1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_CMP:
1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_cmp(p, dst, dst_flags, args[0], args[1], args[2]);
1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MAX:
1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_max(p, dst, dst_flags, args[0], args[1]);
1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MIN:
1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_min(p, dst, dst_flags, args[0], args[1]);
1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SLT:
1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_slt(p, dst, dst_flags, args[0], args[1]);
1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SLE:
1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_sle(p, dst, dst_flags, args[0], args[1]);
1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SGT:
1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_sgt(p, dst, dst_flags, args[0], args[1]);
1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SGE:
1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_sge(p, dst, dst_flags, args[0], args[1]);
1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SEQ:
1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_seq(p, dst, dst_flags, args[0], args[1]);
1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SNE:
1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_sne(p, dst, dst_flags, args[0], args[1]);
1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SSG:
1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_sign(p, dst, dst_flags, args[0]);
1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_LIT:
1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_lit(c, dst, dst_flags, args[0]);
1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Texturing operations:
1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TEX:
1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_tex(c, dst, dst_flags, args[0], c->payload.depth[0].hw_reg,
1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  inst->tex_idx, inst->tex_unit,
1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  inst->tex_shadow);
1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TXB:
1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_txb(c, dst, dst_flags, args[0], c->payload.depth[0].hw_reg,
1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  inst->tex_idx, inst->tex_unit);
1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_KIL:
1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 emit_kil(c, args[0]);
1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("Unsupported opcode %i (%s) in fragment shader\n",
1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		inst->opcode, inst->opcode < MAX_OPCODE ?
1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_mesa_opcode_string(inst->opcode) :
1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"unknown");
1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < 4; i++)
1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (inst->dst[i] && inst->dst[i]->spill_slot)
1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   emit_spill(c,
1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      inst->dst[i]->hw_reg,
1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      inst->dst[i]->spill_slot);
1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Only properly tested on ILK */
1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (p->brw->intel.gen == 5) {
1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     brw_remove_duplicate_mrf_moves(p);
1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     if (c->dispatch_width == 16)
1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	brw_remove_grf_to_mrf_moves(p);
1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int i;
1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     printf("wm-native:\n");
1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     for (i = 0; i < p->nr_insn; i++)
1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 brw_disasm(stdout, &p->store[i], p->brw->intel.gen);
1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("\n");
1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1931