intel: silence uninitialized var warning
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_state.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/simple_list.h"
43 #include "main/state.h"
44
45 #include "vbo/vbo.h"
46 #include "tnl/tnl.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "drivers/common/meta.h"
50
51 #include "radeon_context.h"
52 #include "radeon_mipmap_tree.h"
53 #include "radeon_ioctl.h"
54 #include "radeon_state.h"
55 #include "radeon_tcl.h"
56 #include "radeon_tex.h"
57 #include "radeon_swtcl.h"
58
59 static void radeonUpdateSpecular( struct gl_context *ctx );
60
61 /* =============================================================
62 * Alpha blending
63 */
64
65 static void radeonAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
66 {
67 r100ContextPtr rmesa = R100_CONTEXT(ctx);
68 int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC];
69 GLubyte refByte;
70
71 CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
72
73 RADEON_STATECHANGE( rmesa, ctx );
74
75 pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK);
76 pp_misc |= (refByte & RADEON_REF_ALPHA_MASK);
77
78 switch ( func ) {
79 case GL_NEVER:
80 pp_misc |= RADEON_ALPHA_TEST_FAIL;
81 break;
82 case GL_LESS:
83 pp_misc |= RADEON_ALPHA_TEST_LESS;
84 break;
85 case GL_EQUAL:
86 pp_misc |= RADEON_ALPHA_TEST_EQUAL;
87 break;
88 case GL_LEQUAL:
89 pp_misc |= RADEON_ALPHA_TEST_LEQUAL;
90 break;
91 case GL_GREATER:
92 pp_misc |= RADEON_ALPHA_TEST_GREATER;
93 break;
94 case GL_NOTEQUAL:
95 pp_misc |= RADEON_ALPHA_TEST_NEQUAL;
96 break;
97 case GL_GEQUAL:
98 pp_misc |= RADEON_ALPHA_TEST_GEQUAL;
99 break;
100 case GL_ALWAYS:
101 pp_misc |= RADEON_ALPHA_TEST_PASS;
102 break;
103 }
104
105 rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
106 }
107
108 static void radeonBlendEquationSeparate( struct gl_context *ctx,
109 GLenum modeRGB, GLenum modeA )
110 {
111 r100ContextPtr rmesa = R100_CONTEXT(ctx);
112 GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK;
113 GLboolean fallback = GL_FALSE;
114
115 assert( modeRGB == modeA );
116
117 switch ( modeRGB ) {
118 case GL_FUNC_ADD:
119 case GL_LOGIC_OP:
120 b |= RADEON_COMB_FCN_ADD_CLAMP;
121 break;
122
123 case GL_FUNC_SUBTRACT:
124 b |= RADEON_COMB_FCN_SUB_CLAMP;
125 break;
126
127 default:
128 if (ctx->Color.BlendEnabled)
129 fallback = GL_TRUE;
130 else
131 b |= RADEON_COMB_FCN_ADD_CLAMP;
132 break;
133 }
134
135 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, fallback );
136 if ( !fallback ) {
137 RADEON_STATECHANGE( rmesa, ctx );
138 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
139 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
140 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
141 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
142 } else {
143 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
144 }
145 }
146 }
147
148 static void radeonBlendFuncSeparate( struct gl_context *ctx,
149 GLenum sfactorRGB, GLenum dfactorRGB,
150 GLenum sfactorA, GLenum dfactorA )
151 {
152 r100ContextPtr rmesa = R100_CONTEXT(ctx);
153 GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] &
154 ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
155 GLboolean fallback = GL_FALSE;
156
157 switch ( ctx->Color.Blend[0].SrcRGB ) {
158 case GL_ZERO:
159 b |= RADEON_SRC_BLEND_GL_ZERO;
160 break;
161 case GL_ONE:
162 b |= RADEON_SRC_BLEND_GL_ONE;
163 break;
164 case GL_DST_COLOR:
165 b |= RADEON_SRC_BLEND_GL_DST_COLOR;
166 break;
167 case GL_ONE_MINUS_DST_COLOR:
168 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
169 break;
170 case GL_SRC_COLOR:
171 b |= RADEON_SRC_BLEND_GL_SRC_COLOR;
172 break;
173 case GL_ONE_MINUS_SRC_COLOR:
174 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR;
175 break;
176 case GL_SRC_ALPHA:
177 b |= RADEON_SRC_BLEND_GL_SRC_ALPHA;
178 break;
179 case GL_ONE_MINUS_SRC_ALPHA:
180 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
181 break;
182 case GL_DST_ALPHA:
183 b |= RADEON_SRC_BLEND_GL_DST_ALPHA;
184 break;
185 case GL_ONE_MINUS_DST_ALPHA:
186 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
187 break;
188 case GL_SRC_ALPHA_SATURATE:
189 b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
190 break;
191 case GL_CONSTANT_COLOR:
192 case GL_ONE_MINUS_CONSTANT_COLOR:
193 case GL_CONSTANT_ALPHA:
194 case GL_ONE_MINUS_CONSTANT_ALPHA:
195 if (ctx->Color.BlendEnabled)
196 fallback = GL_TRUE;
197 else
198 b |= RADEON_SRC_BLEND_GL_ONE;
199 break;
200 default:
201 break;
202 }
203
204 switch ( ctx->Color.Blend[0].DstRGB ) {
205 case GL_ZERO:
206 b |= RADEON_DST_BLEND_GL_ZERO;
207 break;
208 case GL_ONE:
209 b |= RADEON_DST_BLEND_GL_ONE;
210 break;
211 case GL_SRC_COLOR:
212 b |= RADEON_DST_BLEND_GL_SRC_COLOR;
213 break;
214 case GL_ONE_MINUS_SRC_COLOR:
215 b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR;
216 break;
217 case GL_SRC_ALPHA:
218 b |= RADEON_DST_BLEND_GL_SRC_ALPHA;
219 break;
220 case GL_ONE_MINUS_SRC_ALPHA:
221 b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
222 break;
223 case GL_DST_COLOR:
224 b |= RADEON_DST_BLEND_GL_DST_COLOR;
225 break;
226 case GL_ONE_MINUS_DST_COLOR:
227 b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR;
228 break;
229 case GL_DST_ALPHA:
230 b |= RADEON_DST_BLEND_GL_DST_ALPHA;
231 break;
232 case GL_ONE_MINUS_DST_ALPHA:
233 b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA;
234 break;
235 case GL_CONSTANT_COLOR:
236 case GL_ONE_MINUS_CONSTANT_COLOR:
237 case GL_CONSTANT_ALPHA:
238 case GL_ONE_MINUS_CONSTANT_ALPHA:
239 if (ctx->Color.BlendEnabled)
240 fallback = GL_TRUE;
241 else
242 b |= RADEON_DST_BLEND_GL_ZERO;
243 break;
244 default:
245 break;
246 }
247
248 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback );
249 if ( !fallback ) {
250 RADEON_STATECHANGE( rmesa, ctx );
251 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
252 }
253 }
254
255
256 /* =============================================================
257 * Depth testing
258 */
259
260 static void radeonDepthFunc( struct gl_context *ctx, GLenum func )
261 {
262 r100ContextPtr rmesa = R100_CONTEXT(ctx);
263
264 RADEON_STATECHANGE( rmesa, ctx );
265 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK;
266
267 switch ( ctx->Depth.Func ) {
268 case GL_NEVER:
269 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEVER;
270 break;
271 case GL_LESS:
272 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LESS;
273 break;
274 case GL_EQUAL:
275 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_EQUAL;
276 break;
277 case GL_LEQUAL:
278 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LEQUAL;
279 break;
280 case GL_GREATER:
281 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GREATER;
282 break;
283 case GL_NOTEQUAL:
284 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEQUAL;
285 break;
286 case GL_GEQUAL:
287 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GEQUAL;
288 break;
289 case GL_ALWAYS:
290 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_ALWAYS;
291 break;
292 }
293 }
294
295
296 static void radeonDepthMask( struct gl_context *ctx, GLboolean flag )
297 {
298 r100ContextPtr rmesa = R100_CONTEXT(ctx);
299 RADEON_STATECHANGE( rmesa, ctx );
300
301 if ( ctx->Depth.Mask ) {
302 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_WRITE_ENABLE;
303 } else {
304 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_WRITE_ENABLE;
305 }
306 }
307
308 static void radeonClearDepth( struct gl_context *ctx, GLclampd d )
309 {
310 r100ContextPtr rmesa = R100_CONTEXT(ctx);
311 GLuint format = (rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &
312 RADEON_DEPTH_FORMAT_MASK);
313
314 switch ( format ) {
315 case RADEON_DEPTH_FORMAT_16BIT_INT_Z:
316 rmesa->radeon.state.depth.clear = d * 0x0000ffff;
317 break;
318 case RADEON_DEPTH_FORMAT_24BIT_INT_Z:
319 rmesa->radeon.state.depth.clear = d * 0x00ffffff;
320 break;
321 }
322 }
323
324
325 /* =============================================================
326 * Fog
327 */
328
329
330 static void radeonFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
331 {
332 r100ContextPtr rmesa = R100_CONTEXT(ctx);
333 union { int i; float f; } c, d;
334 GLubyte col[4];
335
336 switch (pname) {
337 case GL_FOG_MODE:
338 if (!ctx->Fog.Enabled)
339 return;
340 RADEON_STATECHANGE(rmesa, tcl);
341 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
342 switch (ctx->Fog.Mode) {
343 case GL_LINEAR:
344 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
345 break;
346 case GL_EXP:
347 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
348 break;
349 case GL_EXP2:
350 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
351 break;
352 default:
353 return;
354 }
355 /* fallthrough */
356 case GL_FOG_DENSITY:
357 case GL_FOG_START:
358 case GL_FOG_END:
359 if (!ctx->Fog.Enabled)
360 return;
361 c.i = rmesa->hw.fog.cmd[FOG_C];
362 d.i = rmesa->hw.fog.cmd[FOG_D];
363 switch (ctx->Fog.Mode) {
364 case GL_EXP:
365 c.f = 0.0;
366 /* While this is the opposite sign from the DDK, it makes the fog test
367 * pass, and matches r200.
368 */
369 d.f = -ctx->Fog.Density;
370 break;
371 case GL_EXP2:
372 c.f = 0.0;
373 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
374 break;
375 case GL_LINEAR:
376 if (ctx->Fog.Start == ctx->Fog.End) {
377 c.f = 1.0F;
378 d.f = 1.0F;
379 } else {
380 c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
381 /* While this is the opposite sign from the DDK, it makes the fog
382 * test pass, and matches r200.
383 */
384 d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
385 }
386 break;
387 default:
388 break;
389 }
390 if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
391 RADEON_STATECHANGE( rmesa, fog );
392 rmesa->hw.fog.cmd[FOG_C] = c.i;
393 rmesa->hw.fog.cmd[FOG_D] = d.i;
394 }
395 break;
396 case GL_FOG_COLOR:
397 RADEON_STATECHANGE( rmesa, ctx );
398 _mesa_unclamped_float_rgba_to_ubyte(col, ctx->Fog.Color );
399 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
400 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
401 radeonPackColor( 4, col[0], col[1], col[2], 0 );
402 break;
403 case GL_FOG_COORD_SRC:
404 radeonUpdateSpecular( ctx );
405 break;
406 default:
407 return;
408 }
409 }
410
411 /* =============================================================
412 * Culling
413 */
414
415 static void radeonCullFace( struct gl_context *ctx, GLenum unused )
416 {
417 r100ContextPtr rmesa = R100_CONTEXT(ctx);
418 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
419 GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
420
421 s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;
422 t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK);
423
424 if ( ctx->Polygon.CullFlag ) {
425 switch ( ctx->Polygon.CullFaceMode ) {
426 case GL_FRONT:
427 s &= ~RADEON_FFACE_SOLID;
428 t |= RADEON_CULL_FRONT;
429 break;
430 case GL_BACK:
431 s &= ~RADEON_BFACE_SOLID;
432 t |= RADEON_CULL_BACK;
433 break;
434 case GL_FRONT_AND_BACK:
435 s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);
436 t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK);
437 break;
438 }
439 }
440
441 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
442 RADEON_STATECHANGE(rmesa, set );
443 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
444 }
445
446 if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
447 RADEON_STATECHANGE(rmesa, tcl );
448 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
449 }
450 }
451
452 static void radeonFrontFace( struct gl_context *ctx, GLenum mode )
453 {
454 r100ContextPtr rmesa = R100_CONTEXT(ctx);
455
456 RADEON_STATECHANGE( rmesa, set );
457 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK;
458
459 RADEON_STATECHANGE( rmesa, tcl );
460 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;
461
462 /* Winding is inverted when rendering to FBO */
463 if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
464 mode = (mode == GL_CW) ? GL_CCW : GL_CW;
465
466 switch ( mode ) {
467 case GL_CW:
468 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW;
469 break;
470 case GL_CCW:
471 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CCW;
472 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW;
473 break;
474 }
475 }
476
477
478 /* =============================================================
479 * Line state
480 */
481 static void radeonLineWidth( struct gl_context *ctx, GLfloat widthf )
482 {
483 r100ContextPtr rmesa = R100_CONTEXT(ctx);
484
485 RADEON_STATECHANGE( rmesa, lin );
486 RADEON_STATECHANGE( rmesa, set );
487
488 /* Line width is stored in U6.4 format.
489 */
490 rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0);
491 if ( widthf > 1.0 ) {
492 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_WIDELINE_ENABLE;
493 } else {
494 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE;
495 }
496 }
497
498 static void radeonLineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
499 {
500 r100ContextPtr rmesa = R100_CONTEXT(ctx);
501
502 RADEON_STATECHANGE( rmesa, lin );
503 rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
504 ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
505 }
506
507
508 /* =============================================================
509 * Masks
510 */
511 static void radeonColorMask( struct gl_context *ctx,
512 GLboolean r, GLboolean g,
513 GLboolean b, GLboolean a )
514 {
515 r100ContextPtr rmesa = R100_CONTEXT(ctx);
516 struct radeon_renderbuffer *rrb;
517 GLuint mask;
518
519 rrb = radeon_get_colorbuffer(&rmesa->radeon);
520 if (!rrb)
521 return;
522
523 mask = radeonPackColor( rrb->cpp,
524 ctx->Color.ColorMask[0][RCOMP],
525 ctx->Color.ColorMask[0][GCOMP],
526 ctx->Color.ColorMask[0][BCOMP],
527 ctx->Color.ColorMask[0][ACOMP] );
528
529 if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
530 RADEON_STATECHANGE( rmesa, msk );
531 rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
532 }
533 }
534
535
536 /* =============================================================
537 * Polygon state
538 */
539
540 static void radeonPolygonOffset( struct gl_context *ctx,
541 GLfloat factor, GLfloat units )
542 {
543 r100ContextPtr rmesa = R100_CONTEXT(ctx);
544 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
545 float_ui32_type constant = { units * depthScale };
546 float_ui32_type factoru = { factor };
547
548 RADEON_STATECHANGE( rmesa, zbs );
549 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = factoru.ui32;
550 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
551 }
552
553 static void radeonPolygonStipplePreKMS( struct gl_context *ctx, const GLubyte *mask )
554 {
555 r100ContextPtr rmesa = R100_CONTEXT(ctx);
556 GLuint i;
557 drm_radeon_stipple_t stipple;
558
559 /* Must flip pattern upside down.
560 */
561 for ( i = 0 ; i < 32 ; i++ ) {
562 rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i];
563 }
564
565 /* TODO: push this into cmd mechanism
566 */
567 radeon_firevertices(&rmesa->radeon);
568 LOCK_HARDWARE( &rmesa->radeon );
569
570 /* FIXME: Use window x,y offsets into stipple RAM.
571 */
572 stipple.mask = rmesa->state.stipple.mask;
573 drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE,
574 &stipple, sizeof(drm_radeon_stipple_t) );
575 UNLOCK_HARDWARE( &rmesa->radeon );
576 }
577
578 static void radeonPolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
579 {
580 r100ContextPtr rmesa = R100_CONTEXT(ctx);
581 GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
582
583 /* Can't generally do unfilled via tcl, but some good special
584 * cases work.
585 */
586 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag);
587 if (rmesa->radeon.TclFallback) {
588 radeonChooseRenderState( ctx );
589 radeonChooseVertexState( ctx );
590 }
591 }
592
593
594 /* =============================================================
595 * Rendering attributes
596 *
597 * We really don't want to recalculate all this every time we bind a
598 * texture. These things shouldn't change all that often, so it makes
599 * sense to break them out of the core texture state update routines.
600 */
601
602 /* Examine lighting and texture state to determine if separate specular
603 * should be enabled.
604 */
605 static void radeonUpdateSpecular( struct gl_context *ctx )
606 {
607 r100ContextPtr rmesa = R100_CONTEXT(ctx);
608 uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
609 GLuint flag = 0;
610
611 RADEON_STATECHANGE( rmesa, tcl );
612
613 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
614 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
615 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
616 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE;
617 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
618
619 p &= ~RADEON_SPECULAR_ENABLE;
620
621 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE;
622
623
624 if (ctx->Light.Enabled &&
625 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
626 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
627 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
628 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
629 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
630 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
631 p |= RADEON_SPECULAR_ENABLE;
632 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
633 ~RADEON_DIFFUSE_SPECULAR_COMBINE;
634 }
635 else if (ctx->Light.Enabled) {
636 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
637 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
638 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
639 } else if (ctx->Fog.ColorSumEnabled ) {
640 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
641 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
642 p |= RADEON_SPECULAR_ENABLE;
643 } else {
644 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
645 }
646
647 if (ctx->Fog.Enabled) {
648 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
649 if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
650 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
651 /* Bizzare: have to leave lighting enabled to get fog. */
652 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
653 }
654 else {
655 /* cannot do tcl fog factor calculation with fog coord source
656 * (send precomputed factors). Cannot use precomputed fog
657 * factors together with tcl spec light (need tcl fallback) */
658 flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
659 RADEON_TCL_COMPUTE_SPECULAR) != 0;
660 }
661 }
662
663 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
664
665 if (_mesa_need_secondary_color(ctx)) {
666 assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
667 } else {
668 assert( (p & RADEON_SPECULAR_ENABLE) == 0 );
669 }
670
671 if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
672 RADEON_STATECHANGE( rmesa, ctx );
673 rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
674 }
675
676 /* Update vertex/render formats
677 */
678 if (rmesa->radeon.TclFallback) {
679 radeonChooseRenderState( ctx );
680 radeonChooseVertexState( ctx );
681 }
682 }
683
684
685 /* =============================================================
686 * Materials
687 */
688
689
690 /* Update on colormaterial, material emmissive/ambient,
691 * lightmodel.globalambient
692 */
693 static void update_global_ambient( struct gl_context *ctx )
694 {
695 r100ContextPtr rmesa = R100_CONTEXT(ctx);
696 float *fcmd = (float *)RADEON_DB_STATE( glt );
697
698 /* Need to do more if both emmissive & ambient are PREMULT:
699 * Hope this is not needed for MULT
700 */
701 if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
702 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
703 (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
704 {
705 COPY_3V( &fcmd[GLT_RED],
706 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
707 ACC_SCALE_3V( &fcmd[GLT_RED],
708 ctx->Light.Model.Ambient,
709 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
710 }
711 else
712 {
713 COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
714 }
715
716 RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
717 }
718
719 /* Update on change to
720 * - light[p].colors
721 * - light[p].enabled
722 */
723 static void update_light_colors( struct gl_context *ctx, GLuint p )
724 {
725 struct gl_light *l = &ctx->Light.Light[p];
726
727 /* fprintf(stderr, "%s\n", __FUNCTION__); */
728
729 if (l->Enabled) {
730 r100ContextPtr rmesa = R100_CONTEXT(ctx);
731 float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
732
733 COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
734 COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
735 COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
736
737 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
738 }
739 }
740
741 /* Also fallback for asym colormaterial mode in twoside lighting...
742 */
743 static void check_twoside_fallback( struct gl_context *ctx )
744 {
745 GLboolean fallback = GL_FALSE;
746 GLint i;
747
748 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
749 if (ctx->Light.ColorMaterialEnabled &&
750 (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
751 ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
752 fallback = GL_TRUE;
753 else {
754 for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
755 if (memcmp( ctx->Light.Material.Attrib[i],
756 ctx->Light.Material.Attrib[i+1],
757 sizeof(GLfloat)*4) != 0) {
758 fallback = GL_TRUE;
759 break;
760 }
761 }
762 }
763
764 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
765 }
766
767
768 static void radeonColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
769 {
770 r100ContextPtr rmesa = R100_CONTEXT(ctx);
771 GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
772
773 light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
774 (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
775 (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
776 (3 << RADEON_SPECULAR_SOURCE_SHIFT));
777
778 if (ctx->Light.ColorMaterialEnabled) {
779 GLuint mask = ctx->Light.ColorMaterialBitmask;
780
781 if (mask & MAT_BIT_FRONT_EMISSION) {
782 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
783 RADEON_EMISSIVE_SOURCE_SHIFT);
784 }
785 else {
786 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
787 RADEON_EMISSIVE_SOURCE_SHIFT);
788 }
789
790 if (mask & MAT_BIT_FRONT_AMBIENT) {
791 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
792 RADEON_AMBIENT_SOURCE_SHIFT);
793 }
794 else {
795 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
796 RADEON_AMBIENT_SOURCE_SHIFT);
797 }
798
799 if (mask & MAT_BIT_FRONT_DIFFUSE) {
800 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
801 RADEON_DIFFUSE_SOURCE_SHIFT);
802 }
803 else {
804 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
805 RADEON_DIFFUSE_SOURCE_SHIFT);
806 }
807
808 if (mask & MAT_BIT_FRONT_SPECULAR) {
809 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
810 RADEON_SPECULAR_SOURCE_SHIFT);
811 }
812 else {
813 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
814 RADEON_SPECULAR_SOURCE_SHIFT);
815 }
816 }
817 else {
818 /* Default to MULT:
819 */
820 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
821 (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
822 (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
823 (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
824 }
825
826 if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
827 RADEON_STATECHANGE( rmesa, tcl );
828 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
829 }
830 }
831
832 void radeonUpdateMaterial( struct gl_context *ctx )
833 {
834 r100ContextPtr rmesa = R100_CONTEXT(ctx);
835 GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
836 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
837 GLuint mask = ~0;
838
839 if (ctx->Light.ColorMaterialEnabled)
840 mask &= ~ctx->Light.ColorMaterialBitmask;
841
842 if (RADEON_DEBUG & RADEON_STATE)
843 fprintf(stderr, "%s\n", __FUNCTION__);
844
845
846 if (mask & MAT_BIT_FRONT_EMISSION) {
847 fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0];
848 fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
849 fcmd[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_FRONT_EMISSION][2];
850 fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
851 }
852 if (mask & MAT_BIT_FRONT_AMBIENT) {
853 fcmd[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
854 fcmd[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
855 fcmd[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
856 fcmd[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
857 }
858 if (mask & MAT_BIT_FRONT_DIFFUSE) {
859 fcmd[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
860 fcmd[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
861 fcmd[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
862 fcmd[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
863 }
864 if (mask & MAT_BIT_FRONT_SPECULAR) {
865 fcmd[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
866 fcmd[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
867 fcmd[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
868 fcmd[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
869 }
870 if (mask & MAT_BIT_FRONT_SHININESS) {
871 fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0];
872 }
873
874 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl );
875
876 check_twoside_fallback( ctx );
877 /* update_global_ambient( ctx );*/
878 }
879
880 /* _NEW_LIGHT
881 * _NEW_MODELVIEW
882 * _MESA_NEW_NEED_EYE_COORDS
883 *
884 * Uses derived state from mesa:
885 * _VP_inf_norm
886 * _h_inf_norm
887 * _Position
888 * _NormSpotDirection
889 * _ModelViewInvScale
890 * _NeedEyeCoords
891 * _EyeZDir
892 *
893 * which are calculated in light.c and are correct for the current
894 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
895 * and _MESA_NEW_NEED_EYE_COORDS.
896 */
897 static void update_light( struct gl_context *ctx )
898 {
899 r100ContextPtr rmesa = R100_CONTEXT(ctx);
900
901 /* Have to check these, or have an automatic shortcircuit mechanism
902 * to remove noop statechanges. (Or just do a better job on the
903 * front end).
904 */
905 {
906 GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
907
908 if (ctx->_NeedEyeCoords)
909 tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
910 else
911 tmp |= RADEON_LIGHT_IN_MODELSPACE;
912
913
914 /* Leave this test disabled: (unexplained q3 lockup) (even with
915 new packets)
916 */
917 if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
918 {
919 RADEON_STATECHANGE( rmesa, tcl );
920 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
921 }
922 }
923
924 {
925 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
926 fcmd[EYE_X] = ctx->_EyeZDir[0];
927 fcmd[EYE_Y] = ctx->_EyeZDir[1];
928 fcmd[EYE_Z] = - ctx->_EyeZDir[2];
929 fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
930 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
931 }
932
933
934
935 if (ctx->Light.Enabled) {
936 GLint p;
937 for (p = 0 ; p < MAX_LIGHTS; p++) {
938 if (ctx->Light.Light[p].Enabled) {
939 struct gl_light *l = &ctx->Light.Light[p];
940 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
941
942 if (l->EyePosition[3] == 0.0) {
943 COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
944 COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
945 fcmd[LIT_POSITION_W] = 0;
946 fcmd[LIT_DIRECTION_W] = 0;
947 } else {
948 COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
949 fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
950 fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
951 fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
952 fcmd[LIT_DIRECTION_W] = 0;
953 }
954
955 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
956 }
957 }
958 }
959 }
960
961 static void radeonLightfv( struct gl_context *ctx, GLenum light,
962 GLenum pname, const GLfloat *params )
963 {
964 r100ContextPtr rmesa = R100_CONTEXT(ctx);
965 GLint p = light - GL_LIGHT0;
966 struct gl_light *l = &ctx->Light.Light[p];
967 GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
968
969
970 switch (pname) {
971 case GL_AMBIENT:
972 case GL_DIFFUSE:
973 case GL_SPECULAR:
974 update_light_colors( ctx, p );
975 break;
976
977 case GL_SPOT_DIRECTION:
978 /* picked up in update_light */
979 break;
980
981 case GL_POSITION: {
982 /* positions picked up in update_light, but can do flag here */
983 GLuint flag;
984 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
985
986 /* FIXME: Set RANGE_ATTEN only when needed */
987 if (p&1)
988 flag = RADEON_LIGHT_1_IS_LOCAL;
989 else
990 flag = RADEON_LIGHT_0_IS_LOCAL;
991
992 RADEON_STATECHANGE(rmesa, tcl);
993 if (l->EyePosition[3] != 0.0F)
994 rmesa->hw.tcl.cmd[idx] |= flag;
995 else
996 rmesa->hw.tcl.cmd[idx] &= ~flag;
997 break;
998 }
999
1000 case GL_SPOT_EXPONENT:
1001 RADEON_STATECHANGE(rmesa, lit[p]);
1002 fcmd[LIT_SPOT_EXPONENT] = params[0];
1003 break;
1004
1005 case GL_SPOT_CUTOFF: {
1006 GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
1007 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1008
1009 RADEON_STATECHANGE(rmesa, lit[p]);
1010 fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
1011
1012 RADEON_STATECHANGE(rmesa, tcl);
1013 if (l->SpotCutoff != 180.0F)
1014 rmesa->hw.tcl.cmd[idx] |= flag;
1015 else
1016 rmesa->hw.tcl.cmd[idx] &= ~flag;
1017
1018 break;
1019 }
1020
1021 case GL_CONSTANT_ATTENUATION:
1022 RADEON_STATECHANGE(rmesa, lit[p]);
1023 fcmd[LIT_ATTEN_CONST] = params[0];
1024 if ( params[0] == 0.0 )
1025 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
1026 else
1027 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
1028 break;
1029 case GL_LINEAR_ATTENUATION:
1030 RADEON_STATECHANGE(rmesa, lit[p]);
1031 fcmd[LIT_ATTEN_LINEAR] = params[0];
1032 break;
1033 case GL_QUADRATIC_ATTENUATION:
1034 RADEON_STATECHANGE(rmesa, lit[p]);
1035 fcmd[LIT_ATTEN_QUADRATIC] = params[0];
1036 break;
1037 default:
1038 return;
1039 }
1040
1041 /* Set RANGE_ATTEN only when needed */
1042 switch (pname) {
1043 case GL_POSITION:
1044 case GL_CONSTANT_ATTENUATION:
1045 case GL_LINEAR_ATTENUATION:
1046 case GL_QUADRATIC_ATTENUATION:
1047 {
1048 GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
1049 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1050 GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1051 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
1052 GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1053 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
1054
1055 if ( l->EyePosition[3] == 0.0F ||
1056 ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1057 fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1058 /* Disable attenuation */
1059 icmd[idx] &= ~atten_flag;
1060 } else {
1061 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1062 /* Enable only constant portion of attenuation calculation */
1063 icmd[idx] |= ( atten_flag | atten_const_flag );
1064 } else {
1065 /* Enable full attenuation calculation */
1066 icmd[idx] &= ~atten_const_flag;
1067 icmd[idx] |= atten_flag;
1068 }
1069 }
1070
1071 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1072 break;
1073 }
1074 default:
1075 break;
1076 }
1077 }
1078
1079
1080
1081
1082 static void radeonLightModelfv( struct gl_context *ctx, GLenum pname,
1083 const GLfloat *param )
1084 {
1085 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1086
1087 switch (pname) {
1088 case GL_LIGHT_MODEL_AMBIENT:
1089 update_global_ambient( ctx );
1090 break;
1091
1092 case GL_LIGHT_MODEL_LOCAL_VIEWER:
1093 RADEON_STATECHANGE( rmesa, tcl );
1094 if (ctx->Light.Model.LocalViewer)
1095 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
1096 else
1097 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
1098 break;
1099
1100 case GL_LIGHT_MODEL_TWO_SIDE:
1101 RADEON_STATECHANGE( rmesa, tcl );
1102 if (ctx->Light.Model.TwoSide)
1103 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
1104 else
1105 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
1106
1107 check_twoside_fallback( ctx );
1108
1109 if (rmesa->radeon.TclFallback) {
1110 radeonChooseRenderState( ctx );
1111 radeonChooseVertexState( ctx );
1112 }
1113 break;
1114
1115 case GL_LIGHT_MODEL_COLOR_CONTROL:
1116 radeonUpdateSpecular(ctx);
1117 break;
1118
1119 default:
1120 break;
1121 }
1122 }
1123
1124 static void radeonShadeModel( struct gl_context *ctx, GLenum mode )
1125 {
1126 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1127 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1128
1129 s &= ~(RADEON_DIFFUSE_SHADE_MASK |
1130 RADEON_ALPHA_SHADE_MASK |
1131 RADEON_SPECULAR_SHADE_MASK |
1132 RADEON_FOG_SHADE_MASK);
1133
1134 switch ( mode ) {
1135 case GL_FLAT:
1136 s |= (RADEON_DIFFUSE_SHADE_FLAT |
1137 RADEON_ALPHA_SHADE_FLAT |
1138 RADEON_SPECULAR_SHADE_FLAT |
1139 RADEON_FOG_SHADE_FLAT);
1140 break;
1141 case GL_SMOOTH:
1142 s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
1143 RADEON_ALPHA_SHADE_GOURAUD |
1144 RADEON_SPECULAR_SHADE_GOURAUD |
1145 RADEON_FOG_SHADE_GOURAUD);
1146 break;
1147 default:
1148 return;
1149 }
1150
1151 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1152 RADEON_STATECHANGE( rmesa, set );
1153 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1154 }
1155 }
1156
1157
1158 /* =============================================================
1159 * User clip planes
1160 */
1161
1162 static void radeonClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1163 {
1164 GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1165 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1166 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1167
1168 RADEON_STATECHANGE( rmesa, ucp[p] );
1169 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1170 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1171 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1172 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1173 }
1174
1175 static void radeonUpdateClipPlanes( struct gl_context *ctx )
1176 {
1177 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1178 GLuint p;
1179
1180 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1181 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1182 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1183
1184 RADEON_STATECHANGE( rmesa, ucp[p] );
1185 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1186 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1187 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1188 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1189 }
1190 }
1191 }
1192
1193
1194 /* =============================================================
1195 * Stencil
1196 */
1197
1198 static void
1199 radeonStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1200 GLint ref, GLuint mask )
1201 {
1202 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1203 GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) |
1204 ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
1205
1206 RADEON_STATECHANGE( rmesa, ctx );
1207 RADEON_STATECHANGE( rmesa, msk );
1208
1209 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
1210 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
1211 RADEON_STENCIL_VALUE_MASK);
1212
1213 switch ( ctx->Stencil.Function[0] ) {
1214 case GL_NEVER:
1215 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
1216 break;
1217 case GL_LESS:
1218 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
1219 break;
1220 case GL_EQUAL:
1221 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
1222 break;
1223 case GL_LEQUAL:
1224 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
1225 break;
1226 case GL_GREATER:
1227 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
1228 break;
1229 case GL_NOTEQUAL:
1230 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
1231 break;
1232 case GL_GEQUAL:
1233 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
1234 break;
1235 case GL_ALWAYS:
1236 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
1237 break;
1238 }
1239
1240 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1241 }
1242
1243 static void
1244 radeonStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1245 {
1246 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1247
1248 RADEON_STATECHANGE( rmesa, msk );
1249 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
1250 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1251 ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
1252 }
1253
1254 static void radeonStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1255 GLenum zfail, GLenum zpass )
1256 {
1257 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1258
1259 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1260 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1261 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1262
1263 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
1264 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
1265 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1266 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1267 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1268 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
1269
1270 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
1271 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
1272 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
1273 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
1274 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
1275 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
1276 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
1277 }
1278 else {
1279 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
1280 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
1281 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
1282 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
1283 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
1284 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
1285 }
1286
1287 RADEON_STATECHANGE( rmesa, ctx );
1288 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1289 RADEON_STENCIL_ZFAIL_MASK |
1290 RADEON_STENCIL_ZPASS_MASK);
1291
1292 switch ( ctx->Stencil.FailFunc[0] ) {
1293 case GL_KEEP:
1294 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1295 break;
1296 case GL_ZERO:
1297 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1298 break;
1299 case GL_REPLACE:
1300 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1301 break;
1302 case GL_INCR:
1303 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1304 break;
1305 case GL_DECR:
1306 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1307 break;
1308 case GL_INCR_WRAP:
1309 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
1310 break;
1311 case GL_DECR_WRAP:
1312 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
1313 break;
1314 case GL_INVERT:
1315 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1316 break;
1317 }
1318
1319 switch ( ctx->Stencil.ZFailFunc[0] ) {
1320 case GL_KEEP:
1321 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1322 break;
1323 case GL_ZERO:
1324 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1325 break;
1326 case GL_REPLACE:
1327 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1328 break;
1329 case GL_INCR:
1330 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1331 break;
1332 case GL_DECR:
1333 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1334 break;
1335 case GL_INCR_WRAP:
1336 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1337 break;
1338 case GL_DECR_WRAP:
1339 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1340 break;
1341 case GL_INVERT:
1342 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1343 break;
1344 }
1345
1346 switch ( ctx->Stencil.ZPassFunc[0] ) {
1347 case GL_KEEP:
1348 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1349 break;
1350 case GL_ZERO:
1351 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1352 break;
1353 case GL_REPLACE:
1354 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1355 break;
1356 case GL_INCR:
1357 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1358 break;
1359 case GL_DECR:
1360 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1361 break;
1362 case GL_INCR_WRAP:
1363 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
1364 break;
1365 case GL_DECR_WRAP:
1366 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1367 break;
1368 case GL_INVERT:
1369 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1370 break;
1371 }
1372 }
1373
1374 static void radeonClearStencil( struct gl_context *ctx, GLint s )
1375 {
1376 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1377
1378 rmesa->radeon.state.stencil.clear =
1379 ((GLuint) (ctx->Stencil.Clear & 0xff) |
1380 (0xff << RADEON_STENCIL_MASK_SHIFT) |
1381 ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT));
1382 }
1383
1384
1385 /* =============================================================
1386 * Window position and viewport transformation
1387 */
1388
1389 /*
1390 * To correctly position primitives:
1391 */
1392 #define SUBPIXEL_X 0.125
1393 #define SUBPIXEL_Y 0.125
1394
1395
1396 /**
1397 * Called when window size or position changes or viewport or depth range
1398 * state is changed. We update the hardware viewport state here.
1399 */
1400 void radeonUpdateWindow( struct gl_context *ctx )
1401 {
1402 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1403 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1404 GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
1405 GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
1406 const GLfloat *v = ctx->Viewport._WindowMap.m;
1407 const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
1408 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1409 GLfloat y_scale, y_bias;
1410
1411 if (render_to_fbo) {
1412 y_scale = 1.0;
1413 y_bias = 0;
1414 } else {
1415 y_scale = -1.0;
1416 y_bias = yoffset;
1417 }
1418
1419 float_ui32_type sx = { v[MAT_SX] };
1420 float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
1421 float_ui32_type sy = { v[MAT_SY] * y_scale };
1422 float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
1423 float_ui32_type sz = { v[MAT_SZ] * depthScale };
1424 float_ui32_type tz = { v[MAT_TZ] * depthScale };
1425
1426 RADEON_STATECHANGE( rmesa, vpt );
1427
1428 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32;
1429 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1430 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32;
1431 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1432 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32;
1433 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1434 }
1435
1436
1437 static void radeonViewport( struct gl_context *ctx, GLint x, GLint y,
1438 GLsizei width, GLsizei height )
1439 {
1440 /* Don't pipeline viewport changes, conflict with window offset
1441 * setting below. Could apply deltas to rescue pipelined viewport
1442 * values, or keep the originals hanging around.
1443 */
1444 radeonUpdateWindow( ctx );
1445
1446 radeon_viewport(ctx, x, y, width, height);
1447 }
1448
1449 static void radeonDepthRange( struct gl_context *ctx, GLclampd nearval,
1450 GLclampd farval )
1451 {
1452 radeonUpdateWindow( ctx );
1453 }
1454
1455 void radeonUpdateViewportOffset( struct gl_context *ctx )
1456 {
1457 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1458 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1459 GLfloat xoffset = (GLfloat)dPriv->x;
1460 GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1461 const GLfloat *v = ctx->Viewport._WindowMap.m;
1462
1463 float_ui32_type tx;
1464 float_ui32_type ty;
1465
1466 tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X;
1467 ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1468
1469 if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
1470 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
1471 {
1472 /* Note: this should also modify whatever data the context reset
1473 * code uses...
1474 */
1475 RADEON_STATECHANGE( rmesa, vpt );
1476 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1477 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1478
1479 /* update polygon stipple x/y screen offset */
1480 {
1481 GLuint stx, sty;
1482 GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1483
1484 m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
1485 RADEON_STIPPLE_Y_OFFSET_MASK);
1486
1487 /* add magic offsets, then invert */
1488 stx = 31 - ((dPriv->x - 1) & RADEON_STIPPLE_COORD_MASK);
1489 sty = 31 - ((dPriv->y + dPriv->h - 1)
1490 & RADEON_STIPPLE_COORD_MASK);
1491
1492 m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
1493 (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
1494
1495 if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1496 RADEON_STATECHANGE( rmesa, msc );
1497 rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1498 }
1499 }
1500 }
1501
1502 radeonUpdateScissor( ctx );
1503 }
1504
1505
1506
1507 /* =============================================================
1508 * Miscellaneous
1509 */
1510
1511 static void radeonClearColor( struct gl_context *ctx,
1512 const union gl_color_union color )
1513 {
1514 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1515 GLubyte c[4];
1516 struct radeon_renderbuffer *rrb;
1517
1518 rrb = radeon_get_colorbuffer(&rmesa->radeon);
1519 if (!rrb)
1520 return;
1521
1522 _mesa_unclamped_float_rgba_to_ubyte(c, color.f);
1523 rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
1524 c[0], c[1], c[2], c[3] );
1525 }
1526
1527
1528 static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
1529 {
1530 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1531 FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1532 }
1533
1534
1535 static GLuint radeon_rop_tab[] = {
1536 RADEON_ROP_CLEAR,
1537 RADEON_ROP_AND,
1538 RADEON_ROP_AND_REVERSE,
1539 RADEON_ROP_COPY,
1540 RADEON_ROP_AND_INVERTED,
1541 RADEON_ROP_NOOP,
1542 RADEON_ROP_XOR,
1543 RADEON_ROP_OR,
1544 RADEON_ROP_NOR,
1545 RADEON_ROP_EQUIV,
1546 RADEON_ROP_INVERT,
1547 RADEON_ROP_OR_REVERSE,
1548 RADEON_ROP_COPY_INVERTED,
1549 RADEON_ROP_OR_INVERTED,
1550 RADEON_ROP_NAND,
1551 RADEON_ROP_SET,
1552 };
1553
1554 static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode )
1555 {
1556 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1557 GLuint rop = (GLuint)opcode - GL_CLEAR;
1558
1559 ASSERT( rop < 16 );
1560
1561 RADEON_STATECHANGE( rmesa, msk );
1562 rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1563 }
1564
1565 /* =============================================================
1566 * State enable/disable
1567 */
1568
1569 static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
1570 {
1571 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1572 GLuint p, flag;
1573
1574 if ( RADEON_DEBUG & RADEON_STATE )
1575 fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1576 _mesa_lookup_enum_by_nr( cap ),
1577 state ? "GL_TRUE" : "GL_FALSE" );
1578
1579 switch ( cap ) {
1580 /* Fast track this one...
1581 */
1582 case GL_TEXTURE_1D:
1583 case GL_TEXTURE_2D:
1584 case GL_TEXTURE_3D:
1585 break;
1586
1587 case GL_ALPHA_TEST:
1588 RADEON_STATECHANGE( rmesa, ctx );
1589 if (state) {
1590 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1591 } else {
1592 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1593 }
1594 break;
1595
1596 case GL_BLEND:
1597 RADEON_STATECHANGE( rmesa, ctx );
1598 if (state) {
1599 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE;
1600 } else {
1601 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1602 }
1603 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1604 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1605 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1606 } else {
1607 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1608 }
1609
1610 /* Catch a possible fallback:
1611 */
1612 if (state) {
1613 ctx->Driver.BlendEquationSeparate( ctx,
1614 ctx->Color.Blend[0].EquationRGB,
1615 ctx->Color.Blend[0].EquationA );
1616 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
1617 ctx->Color.Blend[0].DstRGB,
1618 ctx->Color.Blend[0].SrcA,
1619 ctx->Color.Blend[0].DstA );
1620 }
1621 else {
1622 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1623 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1624 }
1625 break;
1626
1627 case GL_CLIP_PLANE0:
1628 case GL_CLIP_PLANE1:
1629 case GL_CLIP_PLANE2:
1630 case GL_CLIP_PLANE3:
1631 case GL_CLIP_PLANE4:
1632 case GL_CLIP_PLANE5:
1633 p = cap-GL_CLIP_PLANE0;
1634 RADEON_STATECHANGE( rmesa, tcl );
1635 if (state) {
1636 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1637 radeonClipPlane( ctx, cap, NULL );
1638 }
1639 else {
1640 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1641 }
1642 break;
1643
1644 case GL_COLOR_MATERIAL:
1645 radeonColorMaterial( ctx, 0, 0 );
1646 radeonUpdateMaterial( ctx );
1647 break;
1648
1649 case GL_CULL_FACE:
1650 radeonCullFace( ctx, 0 );
1651 break;
1652
1653 case GL_DEPTH_TEST:
1654 RADEON_STATECHANGE(rmesa, ctx );
1655 if ( state ) {
1656 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE;
1657 } else {
1658 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1659 }
1660 break;
1661
1662 case GL_DITHER:
1663 RADEON_STATECHANGE(rmesa, ctx );
1664 if ( state ) {
1665 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE;
1666 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1667 } else {
1668 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1669 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable;
1670 }
1671 break;
1672
1673 case GL_FOG:
1674 RADEON_STATECHANGE(rmesa, ctx );
1675 if ( state ) {
1676 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1677 radeonFogfv( ctx, GL_FOG_MODE, NULL );
1678 } else {
1679 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1680 RADEON_STATECHANGE(rmesa, tcl);
1681 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1682 }
1683 radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1684 _mesa_allow_light_in_model( ctx, !state );
1685 break;
1686
1687 case GL_LIGHT0:
1688 case GL_LIGHT1:
1689 case GL_LIGHT2:
1690 case GL_LIGHT3:
1691 case GL_LIGHT4:
1692 case GL_LIGHT5:
1693 case GL_LIGHT6:
1694 case GL_LIGHT7:
1695 RADEON_STATECHANGE(rmesa, tcl);
1696 p = cap - GL_LIGHT0;
1697 if (p&1)
1698 flag = (RADEON_LIGHT_1_ENABLE |
1699 RADEON_LIGHT_1_ENABLE_AMBIENT |
1700 RADEON_LIGHT_1_ENABLE_SPECULAR);
1701 else
1702 flag = (RADEON_LIGHT_0_ENABLE |
1703 RADEON_LIGHT_0_ENABLE_AMBIENT |
1704 RADEON_LIGHT_0_ENABLE_SPECULAR);
1705
1706 if (state)
1707 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1708 else
1709 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1710
1711 /*
1712 */
1713 update_light_colors( ctx, p );
1714 break;
1715
1716 case GL_LIGHTING:
1717 RADEON_STATECHANGE(rmesa, tcl);
1718 radeonUpdateSpecular(ctx);
1719 check_twoside_fallback( ctx );
1720 break;
1721
1722 case GL_LINE_SMOOTH:
1723 RADEON_STATECHANGE( rmesa, ctx );
1724 if ( state ) {
1725 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE;
1726 } else {
1727 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1728 }
1729 break;
1730
1731 case GL_LINE_STIPPLE:
1732 RADEON_STATECHANGE( rmesa, ctx );
1733 if ( state ) {
1734 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE;
1735 } else {
1736 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1737 }
1738 break;
1739
1740 case GL_COLOR_LOGIC_OP:
1741 RADEON_STATECHANGE( rmesa, ctx );
1742 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1743 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1744 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1745 } else {
1746 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1747 }
1748 break;
1749
1750 case GL_NORMALIZE:
1751 RADEON_STATECHANGE( rmesa, tcl );
1752 if ( state ) {
1753 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS;
1754 } else {
1755 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1756 }
1757 break;
1758
1759 case GL_POLYGON_OFFSET_POINT:
1760 RADEON_STATECHANGE( rmesa, set );
1761 if ( state ) {
1762 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
1763 } else {
1764 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1765 }
1766 break;
1767
1768 case GL_POLYGON_OFFSET_LINE:
1769 RADEON_STATECHANGE( rmesa, set );
1770 if ( state ) {
1771 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
1772 } else {
1773 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1774 }
1775 break;
1776
1777 case GL_POLYGON_OFFSET_FILL:
1778 RADEON_STATECHANGE( rmesa, set );
1779 if ( state ) {
1780 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
1781 } else {
1782 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1783 }
1784 break;
1785
1786 case GL_POLYGON_SMOOTH:
1787 RADEON_STATECHANGE( rmesa, ctx );
1788 if ( state ) {
1789 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY;
1790 } else {
1791 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1792 }
1793 break;
1794
1795 case GL_POLYGON_STIPPLE:
1796 RADEON_STATECHANGE(rmesa, ctx );
1797 if ( state ) {
1798 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE;
1799 } else {
1800 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1801 }
1802 break;
1803
1804 case GL_RESCALE_NORMAL_EXT: {
1805 GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1806 RADEON_STATECHANGE( rmesa, tcl );
1807 if ( tmp ) {
1808 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1809 } else {
1810 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1811 }
1812 break;
1813 }
1814
1815 case GL_SCISSOR_TEST:
1816 radeon_firevertices(&rmesa->radeon);
1817 rmesa->radeon.state.scissor.enabled = state;
1818 radeonUpdateScissor( ctx );
1819 break;
1820
1821 case GL_STENCIL_TEST:
1822 {
1823 GLboolean hw_stencil = GL_FALSE;
1824 if (ctx->DrawBuffer) {
1825 struct radeon_renderbuffer *rrbStencil
1826 = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1827 hw_stencil = (rrbStencil && rrbStencil->bo);
1828 }
1829
1830 if (hw_stencil) {
1831 RADEON_STATECHANGE( rmesa, ctx );
1832 if ( state ) {
1833 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE;
1834 } else {
1835 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1836 }
1837 } else {
1838 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1839 }
1840 }
1841 break;
1842
1843 case GL_TEXTURE_GEN_Q:
1844 case GL_TEXTURE_GEN_R:
1845 case GL_TEXTURE_GEN_S:
1846 case GL_TEXTURE_GEN_T:
1847 /* Picked up in radeonUpdateTextureState.
1848 */
1849 rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1850 break;
1851
1852 case GL_COLOR_SUM_EXT:
1853 radeonUpdateSpecular ( ctx );
1854 break;
1855
1856 default:
1857 return;
1858 }
1859 }
1860
1861
1862 static void radeonLightingSpaceChange( struct gl_context *ctx )
1863 {
1864 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1865 GLboolean tmp;
1866 RADEON_STATECHANGE( rmesa, tcl );
1867
1868 if (RADEON_DEBUG & RADEON_STATE)
1869 fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1870 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1871
1872 if (ctx->_NeedEyeCoords)
1873 tmp = ctx->Transform.RescaleNormals;
1874 else
1875 tmp = !ctx->Transform.RescaleNormals;
1876
1877 if ( tmp ) {
1878 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1879 } else {
1880 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1881 }
1882
1883 if (RADEON_DEBUG & RADEON_STATE)
1884 fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1885 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1886 }
1887
1888 /* =============================================================
1889 * Deferred state management - matrices, textures, other?
1890 */
1891
1892
1893 void radeonUploadTexMatrix( r100ContextPtr rmesa,
1894 int unit, GLboolean swapcols )
1895 {
1896 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1897 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1898 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1899 texgen generates all 4 coords, at least tests with projtex indicated that.
1900 So: if we need the q coord in the end (solely determined by the texture
1901 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1902 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1903 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1904 will get submitted in the "wrong", i.e. 3rd, slot.
1905 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1906 size and using the texture matrix to swap the r and q coords around (ut2k3
1907 does exactly that), so we don't need the 3rd / 4th column swap - still need
1908 the 3rd / 4th row swap of course. This will potentially break for apps which
1909 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1910 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1911 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1912 incredibly hard to detect so we can't just fallback in such a case. Assume
1913 it never happens... - rs
1914 */
1915
1916 int idx = TEXMAT_0 + unit;
1917 float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1918 int i;
1919 struct gl_texture_unit tUnit = rmesa->radeon.glCtx->Texture.Unit[unit];
1920 GLfloat *src = rmesa->tmpmat[unit].m;
1921
1922 rmesa->TexMatColSwap &= ~(1 << unit);
1923 if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
1924 if (swapcols) {
1925 rmesa->TexMatColSwap |= 1 << unit;
1926 /* attention some elems are swapped 2 times! */
1927 *dest++ = src[0];
1928 *dest++ = src[4];
1929 *dest++ = src[12];
1930 *dest++ = src[8];
1931 *dest++ = src[1];
1932 *dest++ = src[5];
1933 *dest++ = src[13];
1934 *dest++ = src[9];
1935 *dest++ = src[2];
1936 *dest++ = src[6];
1937 *dest++ = src[15];
1938 *dest++ = src[11];
1939 /* those last 4 are probably never used */
1940 *dest++ = src[3];
1941 *dest++ = src[7];
1942 *dest++ = src[14];
1943 *dest++ = src[10];
1944 }
1945 else {
1946 for (i = 0; i < 2; i++) {
1947 *dest++ = src[i];
1948 *dest++ = src[i+4];
1949 *dest++ = src[i+8];
1950 *dest++ = src[i+12];
1951 }
1952 for (i = 3; i >= 2; i--) {
1953 *dest++ = src[i];
1954 *dest++ = src[i+4];
1955 *dest++ = src[i+8];
1956 *dest++ = src[i+12];
1957 }
1958 }
1959 }
1960 else {
1961 for (i = 0 ; i < 4 ; i++) {
1962 *dest++ = src[i];
1963 *dest++ = src[i+4];
1964 *dest++ = src[i+8];
1965 *dest++ = src[i+12];
1966 }
1967 }
1968
1969 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1970 }
1971
1972
1973 static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1974 {
1975 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1976 int i;
1977
1978
1979 for (i = 0 ; i < 4 ; i++) {
1980 *dest++ = src[i];
1981 *dest++ = src[i+4];
1982 *dest++ = src[i+8];
1983 *dest++ = src[i+12];
1984 }
1985
1986 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1987 }
1988
1989 static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1990 {
1991 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1992 memcpy(dest, src, 16*sizeof(float));
1993 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1994 }
1995
1996
1997 static void update_texturematrix( struct gl_context *ctx )
1998 {
1999 r100ContextPtr rmesa = R100_CONTEXT( ctx );
2000 GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
2001 GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
2002 int unit;
2003 GLuint texMatEnabled = 0;
2004 rmesa->NeedTexMatrix = 0;
2005 rmesa->TexMatColSwap = 0;
2006
2007 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
2008 if (ctx->Texture.Unit[unit]._ReallyEnabled) {
2009 GLboolean needMatrix = GL_FALSE;
2010 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2011 needMatrix = GL_TRUE;
2012 texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
2013 RADEON_TEXMAT_0_ENABLE) << unit;
2014
2015 if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2016 /* Need to preconcatenate any active texgen
2017 * obj/eyeplane matrices:
2018 */
2019 _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
2020 ctx->TextureMatrixStack[unit].Top,
2021 &rmesa->TexGenMatrix[unit] );
2022 }
2023 else {
2024 _math_matrix_copy( &rmesa->tmpmat[unit],
2025 ctx->TextureMatrixStack[unit].Top );
2026 }
2027 }
2028 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2029 _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
2030 needMatrix = GL_TRUE;
2031 }
2032 if (needMatrix) {
2033 rmesa->NeedTexMatrix |= 1 << unit;
2034 radeonUploadTexMatrix( rmesa, unit,
2035 !ctx->Texture.Unit[unit].TexGenEnabled );
2036 }
2037 }
2038 }
2039
2040 tpc = (texMatEnabled | rmesa->TexGenEnabled);
2041
2042 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
2043 vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
2044 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
2045 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
2046
2047 vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
2048 (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
2049 ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
2050 (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
2051 ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
2052 (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
2053
2054 if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
2055 vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
2056
2057 RADEON_STATECHANGE(rmesa, tcl);
2058 rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
2059 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
2060 }
2061 }
2062
2063 static GLboolean r100ValidateBuffers(struct gl_context *ctx)
2064 {
2065 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2066 struct radeon_renderbuffer *rrb;
2067 int i, ret;
2068
2069 radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2070
2071 rrb = radeon_get_colorbuffer(&rmesa->radeon);
2072 /* color buffer */
2073 if (rrb && rrb->bo) {
2074 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2075 0, RADEON_GEM_DOMAIN_VRAM);
2076 }
2077
2078 /* depth buffer */
2079 rrb = radeon_get_depthbuffer(&rmesa->radeon);
2080 /* color buffer */
2081 if (rrb && rrb->bo) {
2082 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2083 0, RADEON_GEM_DOMAIN_VRAM);
2084 }
2085
2086 for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
2087 radeonTexObj *t;
2088
2089 if (!ctx->Texture.Unit[i]._ReallyEnabled)
2090 continue;
2091
2092 t = rmesa->state.texture.unit[i].texobj;
2093
2094 if (!t)
2095 continue;
2096 if (t->image_override && t->bo)
2097 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2098 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2099 else if (t->mt->bo)
2100 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2101 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2102 }
2103
2104 ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
2105 if (ret)
2106 return GL_FALSE;
2107 return GL_TRUE;
2108 }
2109
2110 GLboolean radeonValidateState( struct gl_context *ctx )
2111 {
2112 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2113 GLuint new_state = rmesa->radeon.NewGLState;
2114
2115 if (new_state & _NEW_BUFFERS) {
2116 _mesa_update_framebuffer(ctx);
2117 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2118 _mesa_update_draw_buffer_bounds(ctx);
2119 RADEON_STATECHANGE(rmesa, ctx);
2120 }
2121
2122 if (new_state & _NEW_TEXTURE) {
2123 radeonUpdateTextureState( ctx );
2124 new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2125 }
2126
2127 /* we need to do a space check here */
2128 if (!r100ValidateBuffers(ctx))
2129 return GL_FALSE;
2130
2131 /* Need an event driven matrix update?
2132 */
2133 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2134 upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2135
2136 /* Need these for lighting (shouldn't upload otherwise)
2137 */
2138 if (new_state & (_NEW_MODELVIEW)) {
2139 upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2140 upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2141 }
2142
2143 /* Does this need to be triggered on eg. modelview for
2144 * texgen-derived objplane/eyeplane matrices?
2145 */
2146 if (new_state & _NEW_TEXTURE_MATRIX) {
2147 update_texturematrix( ctx );
2148 }
2149
2150 if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2151 update_light( ctx );
2152 }
2153
2154 /* emit all active clip planes if projection matrix changes.
2155 */
2156 if (new_state & (_NEW_PROJECTION)) {
2157 if (ctx->Transform.ClipPlanesEnabled)
2158 radeonUpdateClipPlanes( ctx );
2159 }
2160
2161
2162 rmesa->radeon.NewGLState = 0;
2163
2164 return GL_TRUE;
2165 }
2166
2167
2168 static void radeonInvalidateState( struct gl_context *ctx, GLuint new_state )
2169 {
2170 _swrast_InvalidateState( ctx, new_state );
2171 _swsetup_InvalidateState( ctx, new_state );
2172 _vbo_InvalidateState( ctx, new_state );
2173 _tnl_InvalidateState( ctx, new_state );
2174 _ae_invalidate_state( ctx, new_state );
2175 R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2176 }
2177
2178
2179 /* A hack. Need a faster way to find this out.
2180 */
2181 static GLboolean check_material( struct gl_context *ctx )
2182 {
2183 TNLcontext *tnl = TNL_CONTEXT(ctx);
2184 GLint i;
2185
2186 for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2187 i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2188 i++)
2189 if (tnl->vb.AttribPtr[i] &&
2190 tnl->vb.AttribPtr[i]->stride)
2191 return GL_TRUE;
2192
2193 return GL_FALSE;
2194 }
2195
2196
2197 static void radeonWrapRunPipeline( struct gl_context *ctx )
2198 {
2199 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2200 GLboolean has_material;
2201
2202 if (0)
2203 fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2204
2205 /* Validate state:
2206 */
2207 if (rmesa->radeon.NewGLState)
2208 if (!radeonValidateState( ctx ))
2209 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2210
2211 has_material = (ctx->Light.Enabled && check_material( ctx ));
2212
2213 if (has_material) {
2214 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2215 }
2216
2217 /* Run the pipeline.
2218 */
2219 _tnl_run_pipeline( ctx );
2220
2221 if (has_material) {
2222 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2223 }
2224 }
2225
2226 static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2227 {
2228 r100ContextPtr r100 = R100_CONTEXT(ctx);
2229 GLint i;
2230
2231 radeon_firevertices(&r100->radeon);
2232
2233 RADEON_STATECHANGE(r100, stp);
2234
2235 /* Must flip pattern upside down.
2236 */
2237 for ( i = 31 ; i >= 0; i--) {
2238 r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2239 }
2240 }
2241
2242
2243 /* Initialize the driver's state functions.
2244 * Many of the ctx->Driver functions might have been initialized to
2245 * software defaults in the earlier _mesa_init_driver_functions() call.
2246 */
2247 void radeonInitStateFuncs( struct gl_context *ctx , GLboolean dri2 )
2248 {
2249 ctx->Driver.UpdateState = radeonInvalidateState;
2250 ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
2251
2252 ctx->Driver.DrawBuffer = radeonDrawBuffer;
2253 ctx->Driver.ReadBuffer = radeonReadBuffer;
2254 ctx->Driver.CopyPixels = _mesa_meta_CopyPixels;
2255 ctx->Driver.DrawPixels = _mesa_meta_DrawPixels;
2256 if (dri2)
2257 ctx->Driver.ReadPixels = radeonReadPixels;
2258
2259 ctx->Driver.AlphaFunc = radeonAlphaFunc;
2260 ctx->Driver.BlendEquationSeparate = radeonBlendEquationSeparate;
2261 ctx->Driver.BlendFuncSeparate = radeonBlendFuncSeparate;
2262 ctx->Driver.ClearColor = radeonClearColor;
2263 ctx->Driver.ClearDepth = radeonClearDepth;
2264 ctx->Driver.ClearStencil = radeonClearStencil;
2265 ctx->Driver.ClipPlane = radeonClipPlane;
2266 ctx->Driver.ColorMask = radeonColorMask;
2267 ctx->Driver.CullFace = radeonCullFace;
2268 ctx->Driver.DepthFunc = radeonDepthFunc;
2269 ctx->Driver.DepthMask = radeonDepthMask;
2270 ctx->Driver.DepthRange = radeonDepthRange;
2271 ctx->Driver.Enable = radeonEnable;
2272 ctx->Driver.Fogfv = radeonFogfv;
2273 ctx->Driver.FrontFace = radeonFrontFace;
2274 ctx->Driver.Hint = NULL;
2275 ctx->Driver.LightModelfv = radeonLightModelfv;
2276 ctx->Driver.Lightfv = radeonLightfv;
2277 ctx->Driver.LineStipple = radeonLineStipple;
2278 ctx->Driver.LineWidth = radeonLineWidth;
2279 ctx->Driver.LogicOpcode = radeonLogicOpCode;
2280 ctx->Driver.PolygonMode = radeonPolygonMode;
2281 ctx->Driver.PolygonOffset = radeonPolygonOffset;
2282 if (dri2)
2283 ctx->Driver.PolygonStipple = radeonPolygonStipple;
2284 else
2285 ctx->Driver.PolygonStipple = radeonPolygonStipplePreKMS;
2286 ctx->Driver.RenderMode = radeonRenderMode;
2287 ctx->Driver.Scissor = radeonScissor;
2288 ctx->Driver.ShadeModel = radeonShadeModel;
2289 ctx->Driver.StencilFuncSeparate = radeonStencilFuncSeparate;
2290 ctx->Driver.StencilMaskSeparate = radeonStencilMaskSeparate;
2291 ctx->Driver.StencilOpSeparate = radeonStencilOpSeparate;
2292 ctx->Driver.Viewport = radeonViewport;
2293
2294 TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2295 TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2296 }