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