Update DRI drivers for new glsl compiler.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm.c
1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **********************************************************************/
27 /*
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32
33 #include "brw_context.h"
34 #include "brw_util.h"
35 #include "brw_wm.h"
36 #include "brw_state.h"
37 #include "brw_hal.h"
38
39
40 GLuint brw_wm_nr_args( GLuint opcode )
41 {
42 switch (opcode) {
43
44 case WM_PIXELXY:
45 case OPCODE_ABS:
46 case OPCODE_FLR:
47 case OPCODE_FRC:
48 case OPCODE_SWZ:
49 case OPCODE_MOV:
50 case OPCODE_COS:
51 case OPCODE_EX2:
52 case OPCODE_LG2:
53 case OPCODE_RCP:
54 case OPCODE_RSQ:
55 case OPCODE_SIN:
56 case OPCODE_SCS:
57 case OPCODE_TEX:
58 case OPCODE_TXB:
59 case OPCODE_TXP:
60 case OPCODE_KIL:
61 case OPCODE_LIT:
62 case WM_CINTERP:
63 case WM_WPOSXY:
64 return 1;
65
66 case OPCODE_POW:
67 case OPCODE_SUB:
68 case OPCODE_SGE:
69 case OPCODE_SLT:
70 case OPCODE_ADD:
71 case OPCODE_MAX:
72 case OPCODE_MIN:
73 case OPCODE_MUL:
74 case OPCODE_XPD:
75 case OPCODE_DP3:
76 case OPCODE_DP4:
77 case OPCODE_DPH:
78 case OPCODE_DST:
79 case WM_LINTERP:
80 case WM_DELTAXY:
81 case WM_PIXELW:
82 return 2;
83
84 case WM_FB_WRITE:
85 case WM_PINTERP:
86 case OPCODE_MAD:
87 case OPCODE_CMP:
88 case OPCODE_LRP:
89 return 3;
90
91 default:
92 return 0;
93 }
94 }
95
96
97 GLuint brw_wm_is_scalar_result( GLuint opcode )
98 {
99 switch (opcode) {
100 case OPCODE_COS:
101 case OPCODE_EX2:
102 case OPCODE_LG2:
103 case OPCODE_POW:
104 case OPCODE_RCP:
105 case OPCODE_RSQ:
106 case OPCODE_SIN:
107 case OPCODE_DP3:
108 case OPCODE_DP4:
109 case OPCODE_DPH:
110 case OPCODE_DST:
111 return 1;
112
113 default:
114 return 0;
115 }
116 }
117
118
119 static void brw_wm_pass_hal (struct brw_wm_compile *c)
120 {
121 static void (*hal_wm_pass) (struct brw_wm_compile *c);
122 static GLboolean hal_tried;
123
124 if (!hal_tried)
125 {
126 hal_wm_pass = brw_hal_find_symbol ("intel_hal_wm_pass");
127 hal_tried = 1;
128 }
129 if (hal_wm_pass)
130 (*hal_wm_pass) (c);
131 }
132
133 static void do_wm_prog( struct brw_context *brw,
134 struct brw_fragment_program *fp,
135 struct brw_wm_prog_key *key)
136 {
137 struct brw_wm_compile *c;
138 const GLuint *program;
139 GLuint program_size;
140
141 c = brw->wm.compile_data;
142 if (c == NULL) {
143 brw->wm.compile_data = calloc(1, sizeof(*brw->wm.compile_data));
144 c = brw->wm.compile_data;
145 } else {
146 memset(c, 0, sizeof(*brw->wm.compile_data));
147 }
148 memcpy(&c->key, key, sizeof(*key));
149
150 c->fp = fp;
151 c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
152
153
154 /* Augment fragment program. Add instructions for pre- and
155 * post-fragment-program tasks such as interpolation and fogging.
156 */
157 brw_wm_pass_fp(c);
158
159 /* Translate to intermediate representation. Build register usage
160 * chains.
161 */
162 brw_wm_pass0(c);
163
164 /* Dead code removal.
165 */
166 brw_wm_pass1(c);
167
168 /* Hal optimization
169 */
170 brw_wm_pass_hal (c);
171
172 /* Register allocation.
173 */
174 c->grf_limit = BRW_WM_MAX_GRF/2;
175
176 /* This is where we start emitting gen4 code:
177 */
178 brw_init_compile(&c->func);
179
180 brw_wm_pass2(c);
181
182 c->prog_data.total_grf = c->max_wm_grf;
183 if (c->last_scratch) {
184 c->prog_data.total_scratch =
185 c->last_scratch + 0x40;
186 } else {
187 c->prog_data.total_scratch = 0;
188 }
189
190 /* Emit GEN4 code.
191 */
192 brw_wm_emit(c);
193
194 /* get the program
195 */
196 program = brw_get_program(&c->func, &program_size);
197
198 /*
199 */
200 brw->wm.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_WM_PROG],
201 &c->key,
202 sizeof(c->key),
203 program,
204 program_size,
205 &c->prog_data,
206 &brw->wm.prog_data );
207 }
208
209
210
211 static void brw_wm_populate_key( struct brw_context *brw,
212 struct brw_wm_prog_key *key )
213 {
214 /* BRW_NEW_FRAGMENT_PROGRAM */
215 struct brw_fragment_program *fp =
216 (struct brw_fragment_program *)brw->fragment_program;
217 GLuint lookup = 0;
218 GLuint line_aa;
219 GLuint i;
220
221 memset(key, 0, sizeof(*key));
222
223 /* Build the index for table lookup
224 */
225 /* _NEW_COLOR */
226 if (fp->program.UsesKill ||
227 brw->attribs.Color->AlphaEnabled)
228 lookup |= IZ_PS_KILL_ALPHATEST_BIT;
229
230 if (fp->program.Base.OutputsWritten & (1<<FRAG_RESULT_DEPR))
231 lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
232
233 /* _NEW_DEPTH */
234 if (brw->attribs.Depth->Test)
235 lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
236
237 if (brw->attribs.Depth->Test &&
238 brw->attribs.Depth->Mask) /* ?? */
239 lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
240
241 /* _NEW_STENCIL */
242 if (brw->attribs.Stencil->Enabled) {
243 lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
244
245 if (brw->attribs.Stencil->WriteMask[0] ||
246 (brw->attribs.Stencil->TestTwoSide && brw->attribs.Stencil->WriteMask[1]))
247 lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
248 }
249
250 /* XXX: when should this be disabled?
251 */
252 if (1)
253 lookup |= IZ_EARLY_DEPTH_TEST_BIT;
254
255
256 line_aa = AA_NEVER;
257
258 /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */
259 if (brw->attribs.Line->SmoothFlag) {
260 if (brw->intel.reduced_primitive == GL_LINES) {
261 line_aa = AA_ALWAYS;
262 }
263 else if (brw->intel.reduced_primitive == GL_TRIANGLES) {
264 if (brw->attribs.Polygon->FrontMode == GL_LINE) {
265 line_aa = AA_SOMETIMES;
266
267 if (brw->attribs.Polygon->BackMode == GL_LINE ||
268 (brw->attribs.Polygon->CullFlag &&
269 brw->attribs.Polygon->CullFaceMode == GL_BACK))
270 line_aa = AA_ALWAYS;
271 }
272 else if (brw->attribs.Polygon->BackMode == GL_LINE) {
273 line_aa = AA_SOMETIMES;
274
275 if ((brw->attribs.Polygon->CullFlag &&
276 brw->attribs.Polygon->CullFaceMode == GL_FRONT))
277 line_aa = AA_ALWAYS;
278 }
279 }
280 }
281
282 brw_wm_lookup_iz(line_aa,
283 lookup,
284 key);
285
286
287 /* BRW_NEW_WM_INPUT_DIMENSIONS */
288 key->projtex_mask = brw->wm.input_size_masks[4-1];
289
290 /* _NEW_LIGHT */
291 key->flat_shade = (brw->attribs.Light->ShadeModel == GL_FLAT);
292
293 /* _NEW_TEXTURE */
294 for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
295 const struct gl_texture_unit *unit = &brw->attribs.Texture->Unit[i];
296 const struct gl_texture_object *t = unit->_Current;
297
298 if (unit->_ReallyEnabled) {
299
300 if (t->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB &&
301 t->Image[0][t->BaseLevel]->_BaseFormat == GL_DEPTH_COMPONENT) {
302 key->shadowtex_mask |= 1<<i;
303 }
304
305 if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA)
306 key->yuvtex_mask |= 1<<i;
307 }
308 }
309
310
311 /* Extra info:
312 */
313 key->program_string_id = fp->id;
314
315 }
316
317
318 static void brw_upload_wm_prog( struct brw_context *brw )
319 {
320 struct brw_wm_prog_key key;
321 struct brw_fragment_program *fp = (struct brw_fragment_program *)
322 brw->fragment_program;
323
324 brw_wm_populate_key(brw, &key);
325
326 /* Make an early check for the key.
327 */
328 if (brw_search_cache(&brw->cache[BRW_WM_PROG],
329 &key, sizeof(key),
330 &brw->wm.prog_data,
331 &brw->wm.prog_gs_offset))
332 return;
333
334 do_wm_prog(brw, fp, &key);
335 }
336
337
338 /* See brw_wm.c:
339 */
340 const struct brw_tracked_state brw_wm_prog = {
341 .dirty = {
342 .mesa = (_NEW_COLOR |
343 _NEW_DEPTH |
344 _NEW_STENCIL |
345 _NEW_POLYGON |
346 _NEW_LINE |
347 _NEW_LIGHT |
348 _NEW_TEXTURE),
349 .brw = (BRW_NEW_FRAGMENT_PROGRAM |
350 BRW_NEW_WM_INPUT_DIMENSIONS |
351 BRW_NEW_REDUCED_PRIMITIVE),
352 .cache = 0
353 },
354 .update = brw_upload_wm_prog
355 };
356