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