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