Revert the move of lost_context setting to UNLOCK_HARDWARE that was done in the
[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( drm_clip_rect_t *out,
422 drm_clip_rect_t *a,
423 drm_clip_rect_t *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 drm_clip_rect_t *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(drm_clip_rect_t) );
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 drm_radeon_stipple_t 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(drm_radeon_stipple_t) );
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 uint32_t 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 * Hope this is not needed for MULT
777 */
778 if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
779 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
780 (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
781 {
782 COPY_3V( &fcmd[GLT_RED],
783 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
784 ACC_SCALE_3V( &fcmd[GLT_RED],
785 ctx->Light.Model.Ambient,
786 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
787 }
788 else
789 {
790 COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
791 }
792
793 RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
794 }
795
796 /* Update on change to
797 * - light[p].colors
798 * - light[p].enabled
799 */
800 static void update_light_colors( GLcontext *ctx, GLuint p )
801 {
802 struct gl_light *l = &ctx->Light.Light[p];
803
804 /* fprintf(stderr, "%s\n", __FUNCTION__); */
805
806 if (l->Enabled) {
807 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
808 float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
809
810 COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
811 COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
812 COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
813
814 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
815 }
816 }
817
818 /* Also fallback for asym colormaterial mode in twoside lighting...
819 */
820 static void check_twoside_fallback( GLcontext *ctx )
821 {
822 GLboolean fallback = GL_FALSE;
823 GLint i;
824
825 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
826 if (ctx->Light.ColorMaterialEnabled &&
827 (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
828 ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
829 fallback = GL_TRUE;
830 else {
831 for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
832 if (memcmp( ctx->Light.Material.Attrib[i],
833 ctx->Light.Material.Attrib[i+1],
834 sizeof(GLfloat)*4) != 0) {
835 fallback = GL_TRUE;
836 break;
837 }
838 }
839 }
840
841 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
842 }
843
844
845 static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
846 {
847 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
848 GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
849
850 light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
851 (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
852 (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
853 (3 << RADEON_SPECULAR_SOURCE_SHIFT));
854
855 if (ctx->Light.ColorMaterialEnabled) {
856 GLuint mask = ctx->Light.ColorMaterialBitmask;
857
858 if (mask & MAT_BIT_FRONT_EMISSION) {
859 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
860 RADEON_EMISSIVE_SOURCE_SHIFT);
861 }
862 else {
863 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
864 RADEON_EMISSIVE_SOURCE_SHIFT);
865 }
866
867 if (mask & MAT_BIT_FRONT_AMBIENT) {
868 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
869 RADEON_AMBIENT_SOURCE_SHIFT);
870 }
871 else {
872 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
873 RADEON_AMBIENT_SOURCE_SHIFT);
874 }
875
876 if (mask & MAT_BIT_FRONT_DIFFUSE) {
877 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
878 RADEON_DIFFUSE_SOURCE_SHIFT);
879 }
880 else {
881 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
882 RADEON_DIFFUSE_SOURCE_SHIFT);
883 }
884
885 if (mask & MAT_BIT_FRONT_SPECULAR) {
886 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
887 RADEON_SPECULAR_SOURCE_SHIFT);
888 }
889 else {
890 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
891 RADEON_SPECULAR_SOURCE_SHIFT);
892 }
893 }
894 else {
895 /* Default to MULT:
896 */
897 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
898 (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
899 (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
900 (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
901 }
902
903 if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
904 RADEON_STATECHANGE( rmesa, tcl );
905 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
906 }
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 mask = ~0;
915
916 if (ctx->Light.ColorMaterialEnabled)
917 mask &= ~ctx->Light.ColorMaterialBitmask;
918
919 if (RADEON_DEBUG & DEBUG_STATE)
920 fprintf(stderr, "%s\n", __FUNCTION__);
921
922
923 if (mask & MAT_BIT_FRONT_EMISSION) {
924 fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0];
925 fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
926 fcmd[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_FRONT_EMISSION][2];
927 fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
928 }
929 if (mask & MAT_BIT_FRONT_AMBIENT) {
930 fcmd[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
931 fcmd[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
932 fcmd[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
933 fcmd[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
934 }
935 if (mask & MAT_BIT_FRONT_DIFFUSE) {
936 fcmd[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
937 fcmd[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
938 fcmd[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
939 fcmd[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
940 }
941 if (mask & MAT_BIT_FRONT_SPECULAR) {
942 fcmd[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
943 fcmd[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
944 fcmd[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
945 fcmd[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
946 }
947 if (mask & MAT_BIT_FRONT_SHININESS) {
948 fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0];
949 }
950
951 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl );
952
953 check_twoside_fallback( ctx );
954 /* update_global_ambient( ctx );*/
955 }
956
957 /* _NEW_LIGHT
958 * _NEW_MODELVIEW
959 * _MESA_NEW_NEED_EYE_COORDS
960 *
961 * Uses derived state from mesa:
962 * _VP_inf_norm
963 * _h_inf_norm
964 * _Position
965 * _NormDirection
966 * _ModelViewInvScale
967 * _NeedEyeCoords
968 * _EyeZDir
969 *
970 * which are calculated in light.c and are correct for the current
971 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
972 * and _MESA_NEW_NEED_EYE_COORDS.
973 */
974 static void update_light( GLcontext *ctx )
975 {
976 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
977
978 /* Have to check these, or have an automatic shortcircuit mechanism
979 * to remove noop statechanges. (Or just do a better job on the
980 * front end).
981 */
982 {
983 GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
984
985 if (ctx->_NeedEyeCoords)
986 tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
987 else
988 tmp |= RADEON_LIGHT_IN_MODELSPACE;
989
990
991 /* Leave this test disabled: (unexplained q3 lockup) (even with
992 new packets)
993 */
994 if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
995 {
996 RADEON_STATECHANGE( rmesa, tcl );
997 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
998 }
999 }
1000
1001 {
1002 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
1003 fcmd[EYE_X] = ctx->_EyeZDir[0];
1004 fcmd[EYE_Y] = ctx->_EyeZDir[1];
1005 fcmd[EYE_Z] = - ctx->_EyeZDir[2];
1006 fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
1007 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
1008 }
1009
1010
1011
1012 if (ctx->Light.Enabled) {
1013 GLint p;
1014 for (p = 0 ; p < MAX_LIGHTS; p++) {
1015 if (ctx->Light.Light[p].Enabled) {
1016 struct gl_light *l = &ctx->Light.Light[p];
1017 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
1018
1019 if (l->EyePosition[3] == 0.0) {
1020 COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
1021 COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
1022 fcmd[LIT_POSITION_W] = 0;
1023 fcmd[LIT_DIRECTION_W] = 0;
1024 } else {
1025 COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
1026 fcmd[LIT_DIRECTION_X] = -l->_NormDirection[0];
1027 fcmd[LIT_DIRECTION_Y] = -l->_NormDirection[1];
1028 fcmd[LIT_DIRECTION_Z] = -l->_NormDirection[2];
1029 fcmd[LIT_DIRECTION_W] = 0;
1030 }
1031
1032 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
1033 }
1034 }
1035 }
1036 }
1037
1038 static void radeonLightfv( GLcontext *ctx, GLenum light,
1039 GLenum pname, const GLfloat *params )
1040 {
1041 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1042 GLint p = light - GL_LIGHT0;
1043 struct gl_light *l = &ctx->Light.Light[p];
1044 GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
1045
1046
1047 switch (pname) {
1048 case GL_AMBIENT:
1049 case GL_DIFFUSE:
1050 case GL_SPECULAR:
1051 update_light_colors( ctx, p );
1052 break;
1053
1054 case GL_SPOT_DIRECTION:
1055 /* picked up in update_light */
1056 break;
1057
1058 case GL_POSITION: {
1059 /* positions picked up in update_light, but can do flag here */
1060 GLuint flag;
1061 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1062
1063 /* FIXME: Set RANGE_ATTEN only when needed */
1064 if (p&1)
1065 flag = RADEON_LIGHT_1_IS_LOCAL;
1066 else
1067 flag = RADEON_LIGHT_0_IS_LOCAL;
1068
1069 RADEON_STATECHANGE(rmesa, tcl);
1070 if (l->EyePosition[3] != 0.0F)
1071 rmesa->hw.tcl.cmd[idx] |= flag;
1072 else
1073 rmesa->hw.tcl.cmd[idx] &= ~flag;
1074 break;
1075 }
1076
1077 case GL_SPOT_EXPONENT:
1078 RADEON_STATECHANGE(rmesa, lit[p]);
1079 fcmd[LIT_SPOT_EXPONENT] = params[0];
1080 break;
1081
1082 case GL_SPOT_CUTOFF: {
1083 GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
1084 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1085
1086 RADEON_STATECHANGE(rmesa, lit[p]);
1087 fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
1088
1089 RADEON_STATECHANGE(rmesa, tcl);
1090 if (l->SpotCutoff != 180.0F)
1091 rmesa->hw.tcl.cmd[idx] |= flag;
1092 else
1093 rmesa->hw.tcl.cmd[idx] &= ~flag;
1094
1095 break;
1096 }
1097
1098 case GL_CONSTANT_ATTENUATION:
1099 RADEON_STATECHANGE(rmesa, lit[p]);
1100 fcmd[LIT_ATTEN_CONST] = params[0];
1101 if ( params[0] == 0.0 )
1102 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
1103 else
1104 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
1105 break;
1106 case GL_LINEAR_ATTENUATION:
1107 RADEON_STATECHANGE(rmesa, lit[p]);
1108 fcmd[LIT_ATTEN_LINEAR] = params[0];
1109 break;
1110 case GL_QUADRATIC_ATTENUATION:
1111 RADEON_STATECHANGE(rmesa, lit[p]);
1112 fcmd[LIT_ATTEN_QUADRATIC] = params[0];
1113 break;
1114 default:
1115 return;
1116 }
1117
1118 /* Set RANGE_ATTEN only when needed */
1119 switch (pname) {
1120 case GL_POSITION:
1121 case GL_CONSTANT_ATTENUATION:
1122 case GL_LINEAR_ATTENUATION:
1123 case GL_QUADRATIC_ATTENUATION:
1124 {
1125 GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
1126 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1127 GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1128 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
1129 GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1130 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
1131
1132 if ( l->EyePosition[3] == 0.0F ||
1133 ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1134 fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1135 /* Disable attenuation */
1136 icmd[idx] &= ~atten_flag;
1137 } else {
1138 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1139 /* Enable only constant portion of attenuation calculation */
1140 icmd[idx] |= ( atten_flag | atten_const_flag );
1141 } else {
1142 /* Enable full attenuation calculation */
1143 icmd[idx] &= ~atten_const_flag;
1144 icmd[idx] |= atten_flag;
1145 }
1146 }
1147
1148 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1149 break;
1150 }
1151 default:
1152 break;
1153 }
1154 }
1155
1156
1157
1158
1159 static void radeonLightModelfv( GLcontext *ctx, GLenum pname,
1160 const GLfloat *param )
1161 {
1162 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1163
1164 switch (pname) {
1165 case GL_LIGHT_MODEL_AMBIENT:
1166 update_global_ambient( ctx );
1167 break;
1168
1169 case GL_LIGHT_MODEL_LOCAL_VIEWER:
1170 RADEON_STATECHANGE( rmesa, tcl );
1171 if (ctx->Light.Model.LocalViewer)
1172 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
1173 else
1174 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
1175 break;
1176
1177 case GL_LIGHT_MODEL_TWO_SIDE:
1178 RADEON_STATECHANGE( rmesa, tcl );
1179 if (ctx->Light.Model.TwoSide)
1180 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
1181 else
1182 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
1183
1184 check_twoside_fallback( ctx );
1185
1186 if (rmesa->TclFallback) {
1187 radeonChooseRenderState( ctx );
1188 radeonChooseVertexState( ctx );
1189 }
1190 break;
1191
1192 case GL_LIGHT_MODEL_COLOR_CONTROL:
1193 radeonUpdateSpecular(ctx);
1194 break;
1195
1196 default:
1197 break;
1198 }
1199 }
1200
1201 static void radeonShadeModel( GLcontext *ctx, GLenum mode )
1202 {
1203 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1204 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1205
1206 s &= ~(RADEON_DIFFUSE_SHADE_MASK |
1207 RADEON_ALPHA_SHADE_MASK |
1208 RADEON_SPECULAR_SHADE_MASK |
1209 RADEON_FOG_SHADE_MASK);
1210
1211 switch ( mode ) {
1212 case GL_FLAT:
1213 s |= (RADEON_DIFFUSE_SHADE_FLAT |
1214 RADEON_ALPHA_SHADE_FLAT |
1215 RADEON_SPECULAR_SHADE_FLAT |
1216 RADEON_FOG_SHADE_FLAT);
1217 break;
1218 case GL_SMOOTH:
1219 s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
1220 RADEON_ALPHA_SHADE_GOURAUD |
1221 RADEON_SPECULAR_SHADE_GOURAUD |
1222 RADEON_FOG_SHADE_GOURAUD);
1223 break;
1224 default:
1225 return;
1226 }
1227
1228 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1229 RADEON_STATECHANGE( rmesa, set );
1230 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1231 }
1232 }
1233
1234
1235 /* =============================================================
1236 * User clip planes
1237 */
1238
1239 static void radeonClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
1240 {
1241 GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1242 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1243 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1244
1245 RADEON_STATECHANGE( rmesa, ucp[p] );
1246 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1247 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1248 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1249 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1250 }
1251
1252 static void radeonUpdateClipPlanes( GLcontext *ctx )
1253 {
1254 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1255 GLuint p;
1256
1257 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1258 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1259 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1260
1261 RADEON_STATECHANGE( rmesa, ucp[p] );
1262 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1263 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1264 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1265 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1266 }
1267 }
1268 }
1269
1270
1271 /* =============================================================
1272 * Stencil
1273 */
1274
1275 static void radeonStencilFunc( GLcontext *ctx, GLenum func,
1276 GLint ref, GLuint mask )
1277 {
1278 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1279 GLuint refmask = ((ctx->Stencil.Ref[0] << RADEON_STENCIL_REF_SHIFT) |
1280 (ctx->Stencil.ValueMask[0] << RADEON_STENCIL_MASK_SHIFT));
1281
1282 RADEON_STATECHANGE( rmesa, ctx );
1283 RADEON_STATECHANGE( rmesa, msk );
1284
1285 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
1286 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
1287 RADEON_STENCIL_VALUE_MASK);
1288
1289 switch ( ctx->Stencil.Function[0] ) {
1290 case GL_NEVER:
1291 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
1292 break;
1293 case GL_LESS:
1294 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
1295 break;
1296 case GL_EQUAL:
1297 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
1298 break;
1299 case GL_LEQUAL:
1300 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
1301 break;
1302 case GL_GREATER:
1303 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
1304 break;
1305 case GL_NOTEQUAL:
1306 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
1307 break;
1308 case GL_GEQUAL:
1309 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
1310 break;
1311 case GL_ALWAYS:
1312 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
1313 break;
1314 }
1315
1316 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1317 }
1318
1319 static void radeonStencilMask( GLcontext *ctx, GLuint mask )
1320 {
1321 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1322
1323 RADEON_STATECHANGE( rmesa, msk );
1324 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
1325 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1326 (ctx->Stencil.WriteMask[0] << RADEON_STENCIL_WRITEMASK_SHIFT);
1327 }
1328
1329 static void radeonStencilOp( GLcontext *ctx, GLenum fail,
1330 GLenum zfail, GLenum zpass )
1331 {
1332 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1333
1334 RADEON_STATECHANGE( rmesa, ctx );
1335 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1336 RADEON_STENCIL_ZFAIL_MASK |
1337 RADEON_STENCIL_ZPASS_MASK);
1338
1339 switch ( ctx->Stencil.FailFunc[0] ) {
1340 case GL_KEEP:
1341 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1342 break;
1343 case GL_ZERO:
1344 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1345 break;
1346 case GL_REPLACE:
1347 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1348 break;
1349 case GL_INCR:
1350 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1351 break;
1352 case GL_DECR:
1353 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1354 break;
1355 case GL_INVERT:
1356 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1357 break;
1358 }
1359
1360 switch ( ctx->Stencil.ZFailFunc[0] ) {
1361 case GL_KEEP:
1362 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1363 break;
1364 case GL_ZERO:
1365 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1366 break;
1367 case GL_REPLACE:
1368 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1369 break;
1370 case GL_INCR:
1371 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1372 break;
1373 case GL_DECR:
1374 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1375 break;
1376 case GL_INVERT:
1377 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1378 break;
1379 }
1380
1381 switch ( ctx->Stencil.ZPassFunc[0] ) {
1382 case GL_KEEP:
1383 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1384 break;
1385 case GL_ZERO:
1386 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1387 break;
1388 case GL_REPLACE:
1389 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1390 break;
1391 case GL_INCR:
1392 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1393 break;
1394 case GL_DECR:
1395 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1396 break;
1397 case GL_INVERT:
1398 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1399 break;
1400 }
1401 }
1402
1403 static void radeonClearStencil( GLcontext *ctx, GLint s )
1404 {
1405 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1406
1407 rmesa->state.stencil.clear =
1408 ((GLuint) ctx->Stencil.Clear |
1409 (0xff << RADEON_STENCIL_MASK_SHIFT) |
1410 (ctx->Stencil.WriteMask[0] << RADEON_STENCIL_WRITEMASK_SHIFT));
1411 }
1412
1413
1414 /* =============================================================
1415 * Window position and viewport transformation
1416 */
1417
1418 /*
1419 * To correctly position primitives:
1420 */
1421 #define SUBPIXEL_X 0.125
1422 #define SUBPIXEL_Y 0.125
1423
1424 void radeonUpdateWindow( GLcontext *ctx )
1425 {
1426 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1427 __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
1428 GLfloat xoffset = (GLfloat)dPriv->x;
1429 GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1430 const GLfloat *v = ctx->Viewport._WindowMap.m;
1431
1432 GLfloat sx = v[MAT_SX];
1433 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
1434 GLfloat sy = - v[MAT_SY];
1435 GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1436 GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
1437 GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
1438 RADEON_FIREVERTICES( rmesa );
1439 RADEON_STATECHANGE( rmesa, vpt );
1440
1441 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = *(GLuint *)&sx;
1442 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx;
1443 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = *(GLuint *)&sy;
1444 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty;
1445 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = *(GLuint *)&sz;
1446 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = *(GLuint *)&tz;
1447 }
1448
1449
1450
1451 static void radeonViewport( GLcontext *ctx, GLint x, GLint y,
1452 GLsizei width, GLsizei height )
1453 {
1454 /* Don't pipeline viewport changes, conflict with window offset
1455 * setting below. Could apply deltas to rescue pipelined viewport
1456 * values, or keep the originals hanging around.
1457 */
1458 RADEON_FIREVERTICES( RADEON_CONTEXT(ctx) );
1459 radeonUpdateWindow( ctx );
1460 }
1461
1462 static void radeonDepthRange( GLcontext *ctx, GLclampd nearval,
1463 GLclampd farval )
1464 {
1465 radeonUpdateWindow( ctx );
1466 }
1467
1468 void radeonUpdateViewportOffset( GLcontext *ctx )
1469 {
1470 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1471 __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
1472 GLfloat xoffset = (GLfloat)dPriv->x;
1473 GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1474 const GLfloat *v = ctx->Viewport._WindowMap.m;
1475
1476 GLfloat tx = v[MAT_TX] + xoffset;
1477 GLfloat ty = (- v[MAT_TY]) + yoffset;
1478
1479 if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != *(GLuint *)&tx ||
1480 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != *(GLuint *)&ty )
1481 {
1482 /* Note: this should also modify whatever data the context reset
1483 * code uses...
1484 */
1485 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx;
1486 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty;
1487
1488 /* update polygon stipple x/y screen offset */
1489 {
1490 GLuint stx, sty;
1491 GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1492
1493 m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
1494 RADEON_STIPPLE_Y_OFFSET_MASK);
1495
1496 /* add magic offsets, then invert */
1497 stx = 31 - ((rmesa->dri.drawable->x - 1) & RADEON_STIPPLE_COORD_MASK);
1498 sty = 31 - ((rmesa->dri.drawable->y + rmesa->dri.drawable->h - 1)
1499 & RADEON_STIPPLE_COORD_MASK);
1500
1501 m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
1502 (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
1503
1504 if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1505 RADEON_STATECHANGE( rmesa, msc );
1506 rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1507 }
1508 }
1509 }
1510
1511 radeonUpdateScissor( ctx );
1512 }
1513
1514
1515
1516 /* =============================================================
1517 * Miscellaneous
1518 */
1519
1520 static void radeonClearColor( GLcontext *ctx, const GLfloat color[4] )
1521 {
1522 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1523 GLubyte c[4];
1524 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
1525 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
1526 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
1527 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
1528 rmesa->state.color.clear = radeonPackColor( rmesa->radeonScreen->cpp,
1529 c[0], c[1], c[2], c[3] );
1530 }
1531
1532
1533 static void radeonRenderMode( GLcontext *ctx, GLenum mode )
1534 {
1535 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1536 FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1537 }
1538
1539
1540 static GLuint radeon_rop_tab[] = {
1541 RADEON_ROP_CLEAR,
1542 RADEON_ROP_AND,
1543 RADEON_ROP_AND_REVERSE,
1544 RADEON_ROP_COPY,
1545 RADEON_ROP_AND_INVERTED,
1546 RADEON_ROP_NOOP,
1547 RADEON_ROP_XOR,
1548 RADEON_ROP_OR,
1549 RADEON_ROP_NOR,
1550 RADEON_ROP_EQUIV,
1551 RADEON_ROP_INVERT,
1552 RADEON_ROP_OR_REVERSE,
1553 RADEON_ROP_COPY_INVERTED,
1554 RADEON_ROP_OR_INVERTED,
1555 RADEON_ROP_NAND,
1556 RADEON_ROP_SET,
1557 };
1558
1559 static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode )
1560 {
1561 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1562 GLuint rop = (GLuint)opcode - GL_CLEAR;
1563
1564 ASSERT( rop < 16 );
1565
1566 RADEON_STATECHANGE( rmesa, msk );
1567 rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1568 }
1569
1570
1571 void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode )
1572 {
1573 __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
1574
1575 switch ( mode ) {
1576 case GL_FRONT_LEFT:
1577 rmesa->numClipRects = dPriv->numClipRects;
1578 rmesa->pClipRects = dPriv->pClipRects;
1579 break;
1580 case GL_BACK_LEFT:
1581 /* Can't ignore 2d windows if we are page flipping.
1582 */
1583 if ( dPriv->numBackClipRects == 0 || rmesa->doPageFlip ) {
1584 rmesa->numClipRects = dPriv->numClipRects;
1585 rmesa->pClipRects = dPriv->pClipRects;
1586 }
1587 else {
1588 rmesa->numClipRects = dPriv->numBackClipRects;
1589 rmesa->pClipRects = dPriv->pBackClipRects;
1590 }
1591 break;
1592 default:
1593 fprintf(stderr, "bad mode in radeonSetCliprects\n");
1594 return;
1595 }
1596
1597 if (rmesa->state.scissor.enabled)
1598 radeonRecalcScissorRects( rmesa );
1599 }
1600
1601
1602 static void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
1603 {
1604 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1605
1606 if (RADEON_DEBUG & DEBUG_DRI)
1607 fprintf(stderr, "%s %s\n", __FUNCTION__,
1608 _mesa_lookup_enum_by_nr( mode ));
1609
1610 RADEON_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */
1611
1612 /*
1613 * _DrawDestMask is easier to cope with than <mode>.
1614 */
1615 switch ( ctx->Color._DrawDestMask ) {
1616 case DD_FRONT_LEFT_BIT:
1617 FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE );
1618 radeonSetCliprects( rmesa, GL_FRONT_LEFT );
1619 break;
1620 case DD_BACK_LEFT_BIT:
1621 FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE );
1622 radeonSetCliprects( rmesa, GL_BACK_LEFT );
1623 break;
1624 default:
1625 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
1626 FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE );
1627 return;
1628 }
1629
1630 /* We want to update the s/w rast state too so that r200SetBuffer()
1631 * gets called.
1632 */
1633 _swrast_DrawBuffer(ctx, mode);
1634
1635 RADEON_STATECHANGE( rmesa, ctx );
1636 rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((rmesa->state.color.drawOffset +
1637 rmesa->radeonScreen->fbLocation)
1638 & RADEON_COLOROFFSET_MASK);
1639 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
1640 }
1641
1642 static void radeonReadBuffer( GLcontext *ctx, GLenum mode )
1643 {
1644 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1645 }
1646
1647
1648 /* =============================================================
1649 * State enable/disable
1650 */
1651
1652 static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
1653 {
1654 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1655 GLuint p, flag;
1656
1657 if ( RADEON_DEBUG & DEBUG_STATE )
1658 fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1659 _mesa_lookup_enum_by_nr( cap ),
1660 state ? "GL_TRUE" : "GL_FALSE" );
1661
1662 switch ( cap ) {
1663 /* Fast track this one...
1664 */
1665 case GL_TEXTURE_1D:
1666 case GL_TEXTURE_2D:
1667 case GL_TEXTURE_3D:
1668 break;
1669
1670 case GL_ALPHA_TEST:
1671 RADEON_STATECHANGE( rmesa, ctx );
1672 if (state) {
1673 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1674 } else {
1675 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1676 }
1677 break;
1678
1679 case GL_BLEND:
1680 RADEON_STATECHANGE( rmesa, ctx );
1681 if (state) {
1682 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE;
1683 } else {
1684 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1685 }
1686 if ( ctx->Color._LogicOpEnabled ) {
1687 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1688 } else {
1689 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1690 }
1691
1692 /* Catch a possible fallback:
1693 */
1694 if (state) {
1695 ctx->Driver.BlendEquationSeparate( ctx,
1696 ctx->Color.BlendEquationRGB,
1697 ctx->Color.BlendEquationA );
1698 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.BlendSrcRGB,
1699 ctx->Color.BlendDstRGB,
1700 ctx->Color.BlendSrcA,
1701 ctx->Color.BlendDstA );
1702 }
1703 else {
1704 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1705 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1706 }
1707 break;
1708
1709 case GL_CLIP_PLANE0:
1710 case GL_CLIP_PLANE1:
1711 case GL_CLIP_PLANE2:
1712 case GL_CLIP_PLANE3:
1713 case GL_CLIP_PLANE4:
1714 case GL_CLIP_PLANE5:
1715 p = cap-GL_CLIP_PLANE0;
1716 RADEON_STATECHANGE( rmesa, tcl );
1717 if (state) {
1718 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1719 radeonClipPlane( ctx, cap, NULL );
1720 }
1721 else {
1722 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1723 }
1724 break;
1725
1726 case GL_COLOR_MATERIAL:
1727 radeonColorMaterial( ctx, 0, 0 );
1728 radeonUpdateMaterial( ctx );
1729 break;
1730
1731 case GL_CULL_FACE:
1732 radeonCullFace( ctx, 0 );
1733 break;
1734
1735 case GL_DEPTH_TEST:
1736 RADEON_STATECHANGE(rmesa, ctx );
1737 if ( state ) {
1738 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE;
1739 } else {
1740 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1741 }
1742 break;
1743
1744 case GL_DITHER:
1745 RADEON_STATECHANGE(rmesa, ctx );
1746 if ( state ) {
1747 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE;
1748 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->state.color.roundEnable;
1749 } else {
1750 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1751 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable;
1752 }
1753 break;
1754
1755 case GL_FOG:
1756 RADEON_STATECHANGE(rmesa, ctx );
1757 if ( state ) {
1758 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1759 radeonFogfv( ctx, GL_FOG_MODE, 0 );
1760 } else {
1761 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1762 RADEON_STATECHANGE(rmesa, tcl);
1763 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1764 }
1765 radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1766 if (rmesa->TclFallback)
1767 radeonChooseVertexState( ctx );
1768 _mesa_allow_light_in_model( ctx, !state );
1769 break;
1770
1771 case GL_LIGHT0:
1772 case GL_LIGHT1:
1773 case GL_LIGHT2:
1774 case GL_LIGHT3:
1775 case GL_LIGHT4:
1776 case GL_LIGHT5:
1777 case GL_LIGHT6:
1778 case GL_LIGHT7:
1779 RADEON_STATECHANGE(rmesa, tcl);
1780 p = cap - GL_LIGHT0;
1781 if (p&1)
1782 flag = (RADEON_LIGHT_1_ENABLE |
1783 RADEON_LIGHT_1_ENABLE_AMBIENT |
1784 RADEON_LIGHT_1_ENABLE_SPECULAR);
1785 else
1786 flag = (RADEON_LIGHT_0_ENABLE |
1787 RADEON_LIGHT_0_ENABLE_AMBIENT |
1788 RADEON_LIGHT_0_ENABLE_SPECULAR);
1789
1790 if (state)
1791 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1792 else
1793 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1794
1795 /*
1796 */
1797 update_light_colors( ctx, p );
1798 break;
1799
1800 case GL_LIGHTING:
1801 RADEON_STATECHANGE(rmesa, tcl);
1802 radeonUpdateSpecular(ctx);
1803 check_twoside_fallback( ctx );
1804 break;
1805
1806 case GL_LINE_SMOOTH:
1807 RADEON_STATECHANGE( rmesa, ctx );
1808 if ( state ) {
1809 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE;
1810 } else {
1811 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1812 }
1813 break;
1814
1815 case GL_LINE_STIPPLE:
1816 RADEON_STATECHANGE( rmesa, ctx );
1817 if ( state ) {
1818 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE;
1819 } else {
1820 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1821 }
1822 break;
1823
1824 case GL_COLOR_LOGIC_OP:
1825 RADEON_STATECHANGE( rmesa, ctx );
1826 if ( ctx->Color._LogicOpEnabled ) {
1827 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1828 } else {
1829 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1830 }
1831 break;
1832
1833 case GL_NORMALIZE:
1834 RADEON_STATECHANGE( rmesa, tcl );
1835 if ( state ) {
1836 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS;
1837 } else {
1838 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1839 }
1840 break;
1841
1842 case GL_POLYGON_OFFSET_POINT:
1843 if (rmesa->dri.drmMinor == 1) {
1844 radeonChooseRenderState( ctx );
1845 }
1846 else {
1847 RADEON_STATECHANGE( rmesa, set );
1848 if ( state ) {
1849 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
1850 } else {
1851 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1852 }
1853 }
1854 break;
1855
1856 case GL_POLYGON_OFFSET_LINE:
1857 if (rmesa->dri.drmMinor == 1) {
1858 radeonChooseRenderState( ctx );
1859 }
1860 else {
1861 RADEON_STATECHANGE( rmesa, set );
1862 if ( state ) {
1863 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
1864 } else {
1865 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1866 }
1867 }
1868 break;
1869
1870 case GL_POLYGON_OFFSET_FILL:
1871 if (rmesa->dri.drmMinor == 1) {
1872 radeonChooseRenderState( ctx );
1873 }
1874 else {
1875 RADEON_STATECHANGE( rmesa, set );
1876 if ( state ) {
1877 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
1878 } else {
1879 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1880 }
1881 }
1882 break;
1883
1884 case GL_POLYGON_SMOOTH:
1885 RADEON_STATECHANGE( rmesa, ctx );
1886 if ( state ) {
1887 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY;
1888 } else {
1889 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1890 }
1891 break;
1892
1893 case GL_POLYGON_STIPPLE:
1894 RADEON_STATECHANGE(rmesa, ctx );
1895 if ( state ) {
1896 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE;
1897 } else {
1898 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1899 }
1900 break;
1901
1902 case GL_RESCALE_NORMAL_EXT: {
1903 GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1904 RADEON_STATECHANGE( rmesa, tcl );
1905 if ( tmp ) {
1906 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1907 } else {
1908 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1909 }
1910 break;
1911 }
1912
1913 case GL_SCISSOR_TEST:
1914 RADEON_FIREVERTICES( rmesa );
1915 rmesa->state.scissor.enabled = state;
1916 radeonUpdateScissor( ctx );
1917 break;
1918
1919 case GL_STENCIL_TEST:
1920 if ( rmesa->state.stencil.hwBuffer ) {
1921 RADEON_STATECHANGE( rmesa, ctx );
1922 if ( state ) {
1923 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE;
1924 } else {
1925 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1926 }
1927 } else {
1928 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1929 }
1930 break;
1931
1932 case GL_TEXTURE_GEN_Q:
1933 case GL_TEXTURE_GEN_R:
1934 case GL_TEXTURE_GEN_S:
1935 case GL_TEXTURE_GEN_T:
1936 /* Picked up in radeonUpdateTextureState.
1937 */
1938 rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1939 break;
1940
1941 case GL_COLOR_SUM_EXT:
1942 radeonUpdateSpecular ( ctx );
1943 break;
1944
1945 default:
1946 return;
1947 }
1948 }
1949
1950
1951 static void radeonLightingSpaceChange( GLcontext *ctx )
1952 {
1953 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1954 GLboolean tmp;
1955 RADEON_STATECHANGE( rmesa, tcl );
1956
1957 if (RADEON_DEBUG & DEBUG_STATE)
1958 fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1959 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1960
1961 if (ctx->_NeedEyeCoords)
1962 tmp = ctx->Transform.RescaleNormals;
1963 else
1964 tmp = !ctx->Transform.RescaleNormals;
1965
1966 if ( tmp ) {
1967 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1968 } else {
1969 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1970 }
1971
1972 if (RADEON_DEBUG & DEBUG_STATE)
1973 fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1974 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1975 }
1976
1977 /* =============================================================
1978 * Deferred state management - matrices, textures, other?
1979 */
1980
1981
1982
1983
1984 static void upload_matrix( radeonContextPtr rmesa, GLfloat *src, int idx )
1985 {
1986 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1987 int i;
1988
1989
1990 for (i = 0 ; i < 4 ; i++) {
1991 *dest++ = src[i];
1992 *dest++ = src[i+4];
1993 *dest++ = src[i+8];
1994 *dest++ = src[i+12];
1995 }
1996
1997 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1998 }
1999
2000 static void upload_matrix_t( radeonContextPtr rmesa, GLfloat *src, int idx )
2001 {
2002 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
2003 memcpy(dest, src, 16*sizeof(float));
2004 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2005 }
2006
2007
2008 static void update_texturematrix( GLcontext *ctx )
2009 {
2010 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
2011 GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
2012 GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
2013 int unit;
2014
2015 rmesa->TexMatEnabled = 0;
2016
2017 for (unit = 0 ; unit < 2; unit++) {
2018 if (!ctx->Texture.Unit[unit]._ReallyEnabled) {
2019 }
2020 else if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2021 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
2022
2023 rmesa->TexMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE|
2024 RADEON_TEXMAT_0_ENABLE) << unit;
2025
2026 if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2027 /* Need to preconcatenate any active texgen
2028 * obj/eyeplane matrices:
2029 */
2030 _math_matrix_mul_matrix( &rmesa->tmpmat,
2031 &rmesa->TexGenMatrix[unit],
2032 ctx->TextureMatrixStack[unit].Top );
2033 upload_matrix( rmesa, rmesa->tmpmat.m, TEXMAT_0+unit );
2034 }
2035 else {
2036 rmesa->TexMatEnabled |=
2037 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
2038 upload_matrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,
2039 TEXMAT_0+unit );
2040 }
2041 }
2042 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2043 upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m,
2044 TEXMAT_0+unit );
2045 }
2046 }
2047
2048
2049 tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
2050
2051 vs &= ~((0xf << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
2052 (0xf << RADEON_TCL_TEX_1_OUTPUT_SHIFT));
2053
2054 if (tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE)
2055 vs |= RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT;
2056 else
2057 vs |= RADEON_TCL_TEX_INPUT_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT;
2058
2059 if (tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE)
2060 vs |= RADEON_TCL_TEX_COMPUTED_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT;
2061 else
2062 vs |= RADEON_TCL_TEX_INPUT_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT;
2063
2064 if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
2065 vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
2066
2067 RADEON_STATECHANGE(rmesa, tcl);
2068 rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
2069 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
2070 }
2071 }
2072
2073
2074
2075 void radeonValidateState( GLcontext *ctx )
2076 {
2077 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2078 GLuint new_state = rmesa->NewGLState;
2079
2080 if (new_state & _NEW_TEXTURE) {
2081 radeonUpdateTextureState( ctx );
2082 new_state |= rmesa->NewGLState; /* may add TEXTURE_MATRIX */
2083 }
2084
2085 /* Need an event driven matrix update?
2086 */
2087 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2088 upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2089
2090 /* Need these for lighting (shouldn't upload otherwise)
2091 */
2092 if (new_state & (_NEW_MODELVIEW)) {
2093 upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2094 upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2095 }
2096
2097 /* Does this need to be triggered on eg. modelview for
2098 * texgen-derived objplane/eyeplane matrices?
2099 */
2100 if (new_state & _NEW_TEXTURE_MATRIX) {
2101 update_texturematrix( ctx );
2102 }
2103
2104 if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2105 update_light( ctx );
2106 }
2107
2108 /* emit all active clip planes if projection matrix changes.
2109 */
2110 if (new_state & (_NEW_PROJECTION)) {
2111 if (ctx->Transform.ClipPlanesEnabled)
2112 radeonUpdateClipPlanes( ctx );
2113 }
2114
2115
2116 rmesa->NewGLState = 0;
2117 }
2118
2119
2120 static void radeonInvalidateState( GLcontext *ctx, GLuint new_state )
2121 {
2122 _swrast_InvalidateState( ctx, new_state );
2123 _swsetup_InvalidateState( ctx, new_state );
2124 _ac_InvalidateState( ctx, new_state );
2125 _tnl_InvalidateState( ctx, new_state );
2126 _ae_invalidate_state( ctx, new_state );
2127 RADEON_CONTEXT(ctx)->NewGLState |= new_state;
2128 radeonVtxfmtInvalidate( ctx );
2129 }
2130
2131
2132 /* A hack. Need a faster way to find this out.
2133 */
2134 static GLboolean check_material( GLcontext *ctx )
2135 {
2136 TNLcontext *tnl = TNL_CONTEXT(ctx);
2137 GLint i;
2138
2139 for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2140 i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2141 i++)
2142 if (tnl->vb.AttribPtr[i] &&
2143 tnl->vb.AttribPtr[i]->stride)
2144 return GL_TRUE;
2145
2146 return GL_FALSE;
2147 }
2148
2149
2150 static void radeonWrapRunPipeline( GLcontext *ctx )
2151 {
2152 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2153 GLboolean has_material;
2154
2155 if (0)
2156 fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->NewGLState);
2157
2158 /* Validate state:
2159 */
2160 if (rmesa->NewGLState)
2161 radeonValidateState( ctx );
2162
2163 has_material = (ctx->Light.Enabled && check_material( ctx ));
2164
2165 if (has_material) {
2166 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2167 }
2168
2169 /* Run the pipeline.
2170 */
2171 _tnl_run_pipeline( ctx );
2172
2173 if (has_material) {
2174 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2175 }
2176 }
2177
2178
2179 /* Initialize the driver's state functions.
2180 */
2181 void radeonInitStateFuncs( GLcontext *ctx )
2182 {
2183 ctx->Driver.UpdateState = radeonInvalidateState;
2184 ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
2185
2186 ctx->Driver.DrawBuffer = radeonDrawBuffer;
2187 ctx->Driver.ReadBuffer = radeonReadBuffer;
2188
2189 ctx->Driver.AlphaFunc = radeonAlphaFunc;
2190 ctx->Driver.BlendEquationSeparate = radeonBlendEquationSeparate;
2191 ctx->Driver.BlendFuncSeparate = radeonBlendFuncSeparate;
2192 ctx->Driver.ClearColor = radeonClearColor;
2193 ctx->Driver.ClearDepth = radeonClearDepth;
2194 ctx->Driver.ClearIndex = NULL;
2195 ctx->Driver.ClearStencil = radeonClearStencil;
2196 ctx->Driver.ClipPlane = radeonClipPlane;
2197 ctx->Driver.ColorMask = radeonColorMask;
2198 ctx->Driver.CullFace = radeonCullFace;
2199 ctx->Driver.DepthFunc = radeonDepthFunc;
2200 ctx->Driver.DepthMask = radeonDepthMask;
2201 ctx->Driver.DepthRange = radeonDepthRange;
2202 ctx->Driver.Enable = radeonEnable;
2203 ctx->Driver.Fogfv = radeonFogfv;
2204 ctx->Driver.FrontFace = radeonFrontFace;
2205 ctx->Driver.Hint = NULL;
2206 ctx->Driver.IndexMask = NULL;
2207 ctx->Driver.LightModelfv = radeonLightModelfv;
2208 ctx->Driver.Lightfv = radeonLightfv;
2209 ctx->Driver.LineStipple = radeonLineStipple;
2210 ctx->Driver.LineWidth = radeonLineWidth;
2211 ctx->Driver.LogicOpcode = radeonLogicOpCode;
2212 ctx->Driver.PolygonMode = radeonPolygonMode;
2213
2214 if (RADEON_CONTEXT(ctx)->dri.drmMinor > 1)
2215 ctx->Driver.PolygonOffset = radeonPolygonOffset;
2216
2217 ctx->Driver.PolygonStipple = radeonPolygonStipple;
2218 ctx->Driver.RenderMode = radeonRenderMode;
2219 ctx->Driver.Scissor = radeonScissor;
2220 ctx->Driver.ShadeModel = radeonShadeModel;
2221 ctx->Driver.StencilFunc = radeonStencilFunc;
2222 ctx->Driver.StencilMask = radeonStencilMask;
2223 ctx->Driver.StencilOp = radeonStencilOp;
2224 ctx->Driver.Viewport = radeonViewport;
2225
2226 /* Pixel path fallbacks
2227 */
2228 ctx->Driver.Accum = _swrast_Accum;
2229 ctx->Driver.Bitmap = _swrast_Bitmap;
2230 ctx->Driver.CopyPixels = _swrast_CopyPixels;
2231 ctx->Driver.DrawPixels = _swrast_DrawPixels;
2232 ctx->Driver.ReadPixels = _swrast_ReadPixels;
2233
2234 /* Swrast hooks for imaging extensions:
2235 */
2236 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
2237 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
2238 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
2239 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
2240
2241 TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2242 TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2243 }