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