s/__inline/INLINE/
[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 "buffers.h"
43 #include "context.h"
44
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 u_int32_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 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1335 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1336 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1337
1338 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
1339 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
1340 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1341 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1342 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1343 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
1344
1345 if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_BROKEN_STENCIL) {
1346 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
1347 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
1348 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
1349 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
1350 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
1351 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
1352 }
1353 else {
1354 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
1355 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
1356 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
1357 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
1358 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
1359 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
1360 }
1361
1362 RADEON_STATECHANGE( rmesa, ctx );
1363 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1364 RADEON_STENCIL_ZFAIL_MASK |
1365 RADEON_STENCIL_ZPASS_MASK);
1366
1367 switch ( ctx->Stencil.FailFunc[0] ) {
1368 case GL_KEEP:
1369 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1370 break;
1371 case GL_ZERO:
1372 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1373 break;
1374 case GL_REPLACE:
1375 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1376 break;
1377 case GL_INCR:
1378 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1379 break;
1380 case GL_DECR:
1381 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1382 break;
1383 case GL_INCR_WRAP:
1384 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
1385 break;
1386 case GL_DECR_WRAP:
1387 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
1388 break;
1389 case GL_INVERT:
1390 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1391 break;
1392 }
1393
1394 switch ( ctx->Stencil.ZFailFunc[0] ) {
1395 case GL_KEEP:
1396 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1397 break;
1398 case GL_ZERO:
1399 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1400 break;
1401 case GL_REPLACE:
1402 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1403 break;
1404 case GL_INCR:
1405 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1406 break;
1407 case GL_DECR:
1408 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1409 break;
1410 case GL_INCR_WRAP:
1411 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1412 break;
1413 case GL_DECR_WRAP:
1414 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1415 break;
1416 case GL_INVERT:
1417 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1418 break;
1419 }
1420
1421 switch ( ctx->Stencil.ZPassFunc[0] ) {
1422 case GL_KEEP:
1423 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1424 break;
1425 case GL_ZERO:
1426 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1427 break;
1428 case GL_REPLACE:
1429 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1430 break;
1431 case GL_INCR:
1432 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1433 break;
1434 case GL_DECR:
1435 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1436 break;
1437 case GL_INCR_WRAP:
1438 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
1439 break;
1440 case GL_DECR_WRAP:
1441 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1442 break;
1443 case GL_INVERT:
1444 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1445 break;
1446 }
1447 }
1448
1449 static void radeonClearStencil( GLcontext *ctx, GLint s )
1450 {
1451 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1452
1453 rmesa->state.stencil.clear =
1454 ((GLuint) ctx->Stencil.Clear |
1455 (0xff << RADEON_STENCIL_MASK_SHIFT) |
1456 (ctx->Stencil.WriteMask[0] << RADEON_STENCIL_WRITEMASK_SHIFT));
1457 }
1458
1459
1460 /* =============================================================
1461 * Window position and viewport transformation
1462 */
1463
1464 /*
1465 * To correctly position primitives:
1466 */
1467 #define SUBPIXEL_X 0.125
1468 #define SUBPIXEL_Y 0.125
1469
1470 void radeonUpdateWindow( GLcontext *ctx )
1471 {
1472 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1473 __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
1474 GLfloat xoffset = (GLfloat)dPriv->x;
1475 GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1476 const GLfloat *v = ctx->Viewport._WindowMap.m;
1477
1478 GLfloat sx = v[MAT_SX];
1479 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
1480 GLfloat sy = - v[MAT_SY];
1481 GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1482 GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
1483 GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
1484 RADEON_FIREVERTICES( rmesa );
1485 RADEON_STATECHANGE( rmesa, vpt );
1486
1487 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = *(GLuint *)&sx;
1488 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx;
1489 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = *(GLuint *)&sy;
1490 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty;
1491 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = *(GLuint *)&sz;
1492 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = *(GLuint *)&tz;
1493 }
1494
1495
1496
1497 static void radeonViewport( GLcontext *ctx, GLint x, GLint y,
1498 GLsizei width, GLsizei height )
1499 {
1500 /* update size of Mesa/software ancillary buffers */
1501 _mesa_ResizeBuffersMESA();
1502 /* Don't pipeline viewport changes, conflict with window offset
1503 * setting below. Could apply deltas to rescue pipelined viewport
1504 * values, or keep the originals hanging around.
1505 */
1506 RADEON_FIREVERTICES( RADEON_CONTEXT(ctx) );
1507 radeonUpdateWindow( ctx );
1508 }
1509
1510 static void radeonDepthRange( GLcontext *ctx, GLclampd nearval,
1511 GLclampd farval )
1512 {
1513 radeonUpdateWindow( ctx );
1514 }
1515
1516 void radeonUpdateViewportOffset( GLcontext *ctx )
1517 {
1518 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1519 __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
1520 GLfloat xoffset = (GLfloat)dPriv->x;
1521 GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1522 const GLfloat *v = ctx->Viewport._WindowMap.m;
1523
1524 GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
1525 GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1526
1527 if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != *(GLuint *)&tx ||
1528 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != *(GLuint *)&ty )
1529 {
1530 /* Note: this should also modify whatever data the context reset
1531 * code uses...
1532 */
1533 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx;
1534 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty;
1535
1536 /* update polygon stipple x/y screen offset */
1537 {
1538 GLuint stx, sty;
1539 GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1540
1541 m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
1542 RADEON_STIPPLE_Y_OFFSET_MASK);
1543
1544 /* add magic offsets, then invert */
1545 stx = 31 - ((rmesa->dri.drawable->x - 1) & RADEON_STIPPLE_COORD_MASK);
1546 sty = 31 - ((rmesa->dri.drawable->y + rmesa->dri.drawable->h - 1)
1547 & RADEON_STIPPLE_COORD_MASK);
1548
1549 m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
1550 (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
1551
1552 if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1553 RADEON_STATECHANGE( rmesa, msc );
1554 rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1555 }
1556 }
1557 }
1558
1559 radeonUpdateScissor( ctx );
1560 }
1561
1562
1563
1564 /* =============================================================
1565 * Miscellaneous
1566 */
1567
1568 static void radeonClearColor( GLcontext *ctx, const GLfloat color[4] )
1569 {
1570 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1571 GLubyte c[4];
1572 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
1573 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
1574 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
1575 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
1576 rmesa->state.color.clear = radeonPackColor( rmesa->radeonScreen->cpp,
1577 c[0], c[1], c[2], c[3] );
1578 }
1579
1580
1581 static void radeonRenderMode( GLcontext *ctx, GLenum mode )
1582 {
1583 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1584 FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1585 }
1586
1587
1588 static GLuint radeon_rop_tab[] = {
1589 RADEON_ROP_CLEAR,
1590 RADEON_ROP_AND,
1591 RADEON_ROP_AND_REVERSE,
1592 RADEON_ROP_COPY,
1593 RADEON_ROP_AND_INVERTED,
1594 RADEON_ROP_NOOP,
1595 RADEON_ROP_XOR,
1596 RADEON_ROP_OR,
1597 RADEON_ROP_NOR,
1598 RADEON_ROP_EQUIV,
1599 RADEON_ROP_INVERT,
1600 RADEON_ROP_OR_REVERSE,
1601 RADEON_ROP_COPY_INVERTED,
1602 RADEON_ROP_OR_INVERTED,
1603 RADEON_ROP_NAND,
1604 RADEON_ROP_SET,
1605 };
1606
1607 static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode )
1608 {
1609 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1610 GLuint rop = (GLuint)opcode - GL_CLEAR;
1611
1612 ASSERT( rop < 16 );
1613
1614 RADEON_STATECHANGE( rmesa, msk );
1615 rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1616 }
1617
1618
1619 void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode )
1620 {
1621 __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
1622
1623 switch ( mode ) {
1624 case GL_FRONT_LEFT:
1625 rmesa->numClipRects = dPriv->numClipRects;
1626 rmesa->pClipRects = dPriv->pClipRects;
1627 break;
1628 case GL_BACK_LEFT:
1629 /* Can't ignore 2d windows if we are page flipping.
1630 */
1631 if ( dPriv->numBackClipRects == 0 || rmesa->doPageFlip ) {
1632 rmesa->numClipRects = dPriv->numClipRects;
1633 rmesa->pClipRects = dPriv->pClipRects;
1634 }
1635 else {
1636 rmesa->numClipRects = dPriv->numBackClipRects;
1637 rmesa->pClipRects = dPriv->pBackClipRects;
1638 }
1639 break;
1640 default:
1641 fprintf(stderr, "bad mode in radeonSetCliprects\n");
1642 return;
1643 }
1644
1645 if (rmesa->state.scissor.enabled)
1646 radeonRecalcScissorRects( rmesa );
1647 }
1648
1649
1650 static void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
1651 {
1652 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1653
1654 if (RADEON_DEBUG & DEBUG_DRI)
1655 fprintf(stderr, "%s %s\n", __FUNCTION__,
1656 _mesa_lookup_enum_by_nr( mode ));
1657
1658 RADEON_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */
1659
1660 /*
1661 * _DrawDestMask is easier to cope with than <mode>.
1662 */
1663 switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
1664 case BUFFER_BIT_FRONT_LEFT:
1665 FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE );
1666 radeonSetCliprects( rmesa, GL_FRONT_LEFT );
1667 break;
1668 case BUFFER_BIT_BACK_LEFT:
1669 FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE );
1670 radeonSetCliprects( rmesa, GL_BACK_LEFT );
1671 break;
1672 default:
1673 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
1674 FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE );
1675 return;
1676 }
1677
1678 /* We want to update the s/w rast state too so that r200SetBuffer()
1679 * gets called.
1680 */
1681 _swrast_DrawBuffer(ctx, mode);
1682
1683 RADEON_STATECHANGE( rmesa, ctx );
1684 rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((rmesa->state.color.drawOffset +
1685 rmesa->radeonScreen->fbLocation)
1686 & RADEON_COLOROFFSET_MASK);
1687 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
1688 if (rmesa->sarea->tiling_enabled) {
1689 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE;
1690 }
1691 }
1692
1693 static void radeonReadBuffer( GLcontext *ctx, GLenum mode )
1694 {
1695 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
1696 }
1697
1698
1699 /* =============================================================
1700 * State enable/disable
1701 */
1702
1703 static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
1704 {
1705 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1706 GLuint p, flag;
1707
1708 if ( RADEON_DEBUG & DEBUG_STATE )
1709 fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1710 _mesa_lookup_enum_by_nr( cap ),
1711 state ? "GL_TRUE" : "GL_FALSE" );
1712
1713 switch ( cap ) {
1714 /* Fast track this one...
1715 */
1716 case GL_TEXTURE_1D:
1717 case GL_TEXTURE_2D:
1718 case GL_TEXTURE_3D:
1719 break;
1720
1721 case GL_ALPHA_TEST:
1722 RADEON_STATECHANGE( rmesa, ctx );
1723 if (state) {
1724 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1725 } else {
1726 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1727 }
1728 break;
1729
1730 case GL_BLEND:
1731 RADEON_STATECHANGE( rmesa, ctx );
1732 if (state) {
1733 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE;
1734 } else {
1735 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1736 }
1737 if ( ctx->Color._LogicOpEnabled ) {
1738 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1739 } else {
1740 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1741 }
1742
1743 /* Catch a possible fallback:
1744 */
1745 if (state) {
1746 ctx->Driver.BlendEquationSeparate( ctx,
1747 ctx->Color.BlendEquationRGB,
1748 ctx->Color.BlendEquationA );
1749 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.BlendSrcRGB,
1750 ctx->Color.BlendDstRGB,
1751 ctx->Color.BlendSrcA,
1752 ctx->Color.BlendDstA );
1753 }
1754 else {
1755 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1756 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1757 }
1758 break;
1759
1760 case GL_CLIP_PLANE0:
1761 case GL_CLIP_PLANE1:
1762 case GL_CLIP_PLANE2:
1763 case GL_CLIP_PLANE3:
1764 case GL_CLIP_PLANE4:
1765 case GL_CLIP_PLANE5:
1766 p = cap-GL_CLIP_PLANE0;
1767 RADEON_STATECHANGE( rmesa, tcl );
1768 if (state) {
1769 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1770 radeonClipPlane( ctx, cap, NULL );
1771 }
1772 else {
1773 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1774 }
1775 break;
1776
1777 case GL_COLOR_MATERIAL:
1778 radeonColorMaterial( ctx, 0, 0 );
1779 radeonUpdateMaterial( ctx );
1780 break;
1781
1782 case GL_CULL_FACE:
1783 radeonCullFace( ctx, 0 );
1784 break;
1785
1786 case GL_DEPTH_TEST:
1787 RADEON_STATECHANGE(rmesa, ctx );
1788 if ( state ) {
1789 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE;
1790 } else {
1791 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1792 }
1793 break;
1794
1795 case GL_DITHER:
1796 RADEON_STATECHANGE(rmesa, ctx );
1797 if ( state ) {
1798 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE;
1799 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->state.color.roundEnable;
1800 } else {
1801 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1802 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable;
1803 }
1804 break;
1805
1806 case GL_FOG:
1807 RADEON_STATECHANGE(rmesa, ctx );
1808 if ( state ) {
1809 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1810 radeonFogfv( ctx, GL_FOG_MODE, NULL );
1811 } else {
1812 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1813 RADEON_STATECHANGE(rmesa, tcl);
1814 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1815 }
1816 radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1817 if (rmesa->TclFallback)
1818 radeonChooseVertexState( ctx );
1819 _mesa_allow_light_in_model( ctx, !state );
1820 break;
1821
1822 case GL_LIGHT0:
1823 case GL_LIGHT1:
1824 case GL_LIGHT2:
1825 case GL_LIGHT3:
1826 case GL_LIGHT4:
1827 case GL_LIGHT5:
1828 case GL_LIGHT6:
1829 case GL_LIGHT7:
1830 RADEON_STATECHANGE(rmesa, tcl);
1831 p = cap - GL_LIGHT0;
1832 if (p&1)
1833 flag = (RADEON_LIGHT_1_ENABLE |
1834 RADEON_LIGHT_1_ENABLE_AMBIENT |
1835 RADEON_LIGHT_1_ENABLE_SPECULAR);
1836 else
1837 flag = (RADEON_LIGHT_0_ENABLE |
1838 RADEON_LIGHT_0_ENABLE_AMBIENT |
1839 RADEON_LIGHT_0_ENABLE_SPECULAR);
1840
1841 if (state)
1842 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1843 else
1844 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1845
1846 /*
1847 */
1848 update_light_colors( ctx, p );
1849 break;
1850
1851 case GL_LIGHTING:
1852 RADEON_STATECHANGE(rmesa, tcl);
1853 radeonUpdateSpecular(ctx);
1854 check_twoside_fallback( ctx );
1855 break;
1856
1857 case GL_LINE_SMOOTH:
1858 RADEON_STATECHANGE( rmesa, ctx );
1859 if ( state ) {
1860 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE;
1861 } else {
1862 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1863 }
1864 break;
1865
1866 case GL_LINE_STIPPLE:
1867 RADEON_STATECHANGE( rmesa, ctx );
1868 if ( state ) {
1869 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE;
1870 } else {
1871 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1872 }
1873 break;
1874
1875 case GL_COLOR_LOGIC_OP:
1876 RADEON_STATECHANGE( rmesa, ctx );
1877 if ( ctx->Color._LogicOpEnabled ) {
1878 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1879 } else {
1880 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1881 }
1882 break;
1883
1884 case GL_NORMALIZE:
1885 RADEON_STATECHANGE( rmesa, tcl );
1886 if ( state ) {
1887 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS;
1888 } else {
1889 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1890 }
1891 break;
1892
1893 case GL_POLYGON_OFFSET_POINT:
1894 if (rmesa->dri.drmMinor == 1) {
1895 radeonChooseRenderState( ctx );
1896 }
1897 else {
1898 RADEON_STATECHANGE( rmesa, set );
1899 if ( state ) {
1900 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
1901 } else {
1902 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1903 }
1904 }
1905 break;
1906
1907 case GL_POLYGON_OFFSET_LINE:
1908 if (rmesa->dri.drmMinor == 1) {
1909 radeonChooseRenderState( ctx );
1910 }
1911 else {
1912 RADEON_STATECHANGE( rmesa, set );
1913 if ( state ) {
1914 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
1915 } else {
1916 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1917 }
1918 }
1919 break;
1920
1921 case GL_POLYGON_OFFSET_FILL:
1922 if (rmesa->dri.drmMinor == 1) {
1923 radeonChooseRenderState( ctx );
1924 }
1925 else {
1926 RADEON_STATECHANGE( rmesa, set );
1927 if ( state ) {
1928 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
1929 } else {
1930 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1931 }
1932 }
1933 break;
1934
1935 case GL_POLYGON_SMOOTH:
1936 RADEON_STATECHANGE( rmesa, ctx );
1937 if ( state ) {
1938 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY;
1939 } else {
1940 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1941 }
1942 break;
1943
1944 case GL_POLYGON_STIPPLE:
1945 RADEON_STATECHANGE(rmesa, ctx );
1946 if ( state ) {
1947 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE;
1948 } else {
1949 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1950 }
1951 break;
1952
1953 case GL_RESCALE_NORMAL_EXT: {
1954 GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1955 RADEON_STATECHANGE( rmesa, tcl );
1956 if ( tmp ) {
1957 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1958 } else {
1959 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1960 }
1961 break;
1962 }
1963
1964 case GL_SCISSOR_TEST:
1965 RADEON_FIREVERTICES( rmesa );
1966 rmesa->state.scissor.enabled = state;
1967 radeonUpdateScissor( ctx );
1968 break;
1969
1970 case GL_STENCIL_TEST:
1971 if ( rmesa->state.stencil.hwBuffer ) {
1972 RADEON_STATECHANGE( rmesa, ctx );
1973 if ( state ) {
1974 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE;
1975 } else {
1976 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1977 }
1978 } else {
1979 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1980 }
1981 break;
1982
1983 case GL_TEXTURE_GEN_Q:
1984 case GL_TEXTURE_GEN_R:
1985 case GL_TEXTURE_GEN_S:
1986 case GL_TEXTURE_GEN_T:
1987 /* Picked up in radeonUpdateTextureState.
1988 */
1989 rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1990 break;
1991
1992 case GL_COLOR_SUM_EXT:
1993 radeonUpdateSpecular ( ctx );
1994 break;
1995
1996 default:
1997 return;
1998 }
1999 }
2000
2001
2002 static void radeonLightingSpaceChange( GLcontext *ctx )
2003 {
2004 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2005 GLboolean tmp;
2006 RADEON_STATECHANGE( rmesa, tcl );
2007
2008 if (RADEON_DEBUG & DEBUG_STATE)
2009 fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
2010 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
2011
2012 if (ctx->_NeedEyeCoords)
2013 tmp = ctx->Transform.RescaleNormals;
2014 else
2015 tmp = !ctx->Transform.RescaleNormals;
2016
2017 if ( tmp ) {
2018 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
2019 } else {
2020 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
2021 }
2022
2023 if (RADEON_DEBUG & DEBUG_STATE)
2024 fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
2025 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
2026 }
2027
2028 /* =============================================================
2029 * Deferred state management - matrices, textures, other?
2030 */
2031
2032
2033
2034
2035 static void upload_matrix( radeonContextPtr rmesa, GLfloat *src, int idx )
2036 {
2037 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
2038 int i;
2039
2040
2041 for (i = 0 ; i < 4 ; i++) {
2042 *dest++ = src[i];
2043 *dest++ = src[i+4];
2044 *dest++ = src[i+8];
2045 *dest++ = src[i+12];
2046 }
2047
2048 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2049 }
2050
2051 static void upload_matrix_t( radeonContextPtr rmesa, GLfloat *src, int idx )
2052 {
2053 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
2054 memcpy(dest, src, 16*sizeof(float));
2055 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2056 }
2057
2058
2059 static void update_texturematrix( GLcontext *ctx )
2060 {
2061 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
2062 GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
2063 GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
2064 int unit;
2065
2066 rmesa->TexMatEnabled = 0;
2067
2068 for (unit = 0 ; unit < 2; unit++) {
2069 if (!ctx->Texture.Unit[unit]._ReallyEnabled) {
2070 }
2071 else if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2072 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
2073
2074 rmesa->TexMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE|
2075 RADEON_TEXMAT_0_ENABLE) << unit;
2076
2077 if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2078 /* Need to preconcatenate any active texgen
2079 * obj/eyeplane matrices:
2080 */
2081 _math_matrix_mul_matrix( &rmesa->tmpmat,
2082 &rmesa->TexGenMatrix[unit],
2083 ctx->TextureMatrixStack[unit].Top );
2084 upload_matrix( rmesa, rmesa->tmpmat.m, TEXMAT_0+unit );
2085 }
2086 else {
2087 rmesa->TexMatEnabled |=
2088 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
2089 upload_matrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,
2090 TEXMAT_0+unit );
2091 }
2092 }
2093 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
2094 upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m,
2095 TEXMAT_0+unit );
2096 }
2097 }
2098
2099
2100 tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
2101
2102 vs &= ~((0xf << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
2103 (0xf << RADEON_TCL_TEX_1_OUTPUT_SHIFT));
2104
2105 if (tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE)
2106 vs |= RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT;
2107 else
2108 vs |= RADEON_TCL_TEX_INPUT_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT;
2109
2110 if (tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE)
2111 vs |= RADEON_TCL_TEX_COMPUTED_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT;
2112 else
2113 vs |= RADEON_TCL_TEX_INPUT_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT;
2114
2115 if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
2116 vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
2117
2118 RADEON_STATECHANGE(rmesa, tcl);
2119 rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
2120 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
2121 }
2122 }
2123
2124
2125
2126 void radeonValidateState( GLcontext *ctx )
2127 {
2128 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2129 GLuint new_state = rmesa->NewGLState;
2130
2131 if (new_state & _NEW_TEXTURE) {
2132 radeonUpdateTextureState( ctx );
2133 new_state |= rmesa->NewGLState; /* may add TEXTURE_MATRIX */
2134 }
2135
2136 /* Need an event driven matrix update?
2137 */
2138 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2139 upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2140
2141 /* Need these for lighting (shouldn't upload otherwise)
2142 */
2143 if (new_state & (_NEW_MODELVIEW)) {
2144 upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2145 upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2146 }
2147
2148 /* Does this need to be triggered on eg. modelview for
2149 * texgen-derived objplane/eyeplane matrices?
2150 */
2151 if (new_state & _NEW_TEXTURE_MATRIX) {
2152 update_texturematrix( ctx );
2153 }
2154
2155 if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2156 update_light( ctx );
2157 }
2158
2159 /* emit all active clip planes if projection matrix changes.
2160 */
2161 if (new_state & (_NEW_PROJECTION)) {
2162 if (ctx->Transform.ClipPlanesEnabled)
2163 radeonUpdateClipPlanes( ctx );
2164 }
2165
2166
2167 rmesa->NewGLState = 0;
2168 }
2169
2170
2171 static void radeonInvalidateState( GLcontext *ctx, GLuint new_state )
2172 {
2173 _swrast_InvalidateState( ctx, new_state );
2174 _swsetup_InvalidateState( ctx, new_state );
2175 _ac_InvalidateState( ctx, new_state );
2176 _tnl_InvalidateState( ctx, new_state );
2177 _ae_invalidate_state( ctx, new_state );
2178 RADEON_CONTEXT(ctx)->NewGLState |= new_state;
2179 radeonVtxfmtInvalidate( ctx );
2180 }
2181
2182
2183 /* A hack. Need a faster way to find this out.
2184 */
2185 static GLboolean check_material( GLcontext *ctx )
2186 {
2187 TNLcontext *tnl = TNL_CONTEXT(ctx);
2188 GLint i;
2189
2190 for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2191 i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2192 i++)
2193 if (tnl->vb.AttribPtr[i] &&
2194 tnl->vb.AttribPtr[i]->stride)
2195 return GL_TRUE;
2196
2197 return GL_FALSE;
2198 }
2199
2200
2201 static void radeonWrapRunPipeline( GLcontext *ctx )
2202 {
2203 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
2204 GLboolean has_material;
2205
2206 if (0)
2207 fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->NewGLState);
2208
2209 /* Validate state:
2210 */
2211 if (rmesa->NewGLState)
2212 radeonValidateState( ctx );
2213
2214 has_material = (ctx->Light.Enabled && check_material( ctx ));
2215
2216 if (has_material) {
2217 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2218 }
2219
2220 /* Run the pipeline.
2221 */
2222 _tnl_run_pipeline( ctx );
2223
2224 if (has_material) {
2225 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2226 }
2227 }
2228
2229
2230 /* Initialize the driver's state functions.
2231 * Many of the ctx->Driver functions might have been initialized to
2232 * software defaults in the earlier _mesa_init_driver_functions() call.
2233 */
2234 void radeonInitStateFuncs( GLcontext *ctx )
2235 {
2236 ctx->Driver.UpdateState = radeonInvalidateState;
2237 ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
2238
2239 ctx->Driver.DrawBuffer = radeonDrawBuffer;
2240 ctx->Driver.ReadBuffer = radeonReadBuffer;
2241
2242 ctx->Driver.AlphaFunc = radeonAlphaFunc;
2243 ctx->Driver.BlendEquationSeparate = radeonBlendEquationSeparate;
2244 ctx->Driver.BlendFuncSeparate = radeonBlendFuncSeparate;
2245 ctx->Driver.ClearColor = radeonClearColor;
2246 ctx->Driver.ClearDepth = radeonClearDepth;
2247 ctx->Driver.ClearIndex = NULL;
2248 ctx->Driver.ClearStencil = radeonClearStencil;
2249 ctx->Driver.ClipPlane = radeonClipPlane;
2250 ctx->Driver.ColorMask = radeonColorMask;
2251 ctx->Driver.CullFace = radeonCullFace;
2252 ctx->Driver.DepthFunc = radeonDepthFunc;
2253 ctx->Driver.DepthMask = radeonDepthMask;
2254 ctx->Driver.DepthRange = radeonDepthRange;
2255 ctx->Driver.Enable = radeonEnable;
2256 ctx->Driver.Fogfv = radeonFogfv;
2257 ctx->Driver.FrontFace = radeonFrontFace;
2258 ctx->Driver.Hint = NULL;
2259 ctx->Driver.IndexMask = NULL;
2260 ctx->Driver.LightModelfv = radeonLightModelfv;
2261 ctx->Driver.Lightfv = radeonLightfv;
2262 ctx->Driver.LineStipple = radeonLineStipple;
2263 ctx->Driver.LineWidth = radeonLineWidth;
2264 ctx->Driver.LogicOpcode = radeonLogicOpCode;
2265 ctx->Driver.PolygonMode = radeonPolygonMode;
2266
2267 if (RADEON_CONTEXT(ctx)->dri.drmMinor > 1)
2268 ctx->Driver.PolygonOffset = radeonPolygonOffset;
2269
2270 ctx->Driver.PolygonStipple = radeonPolygonStipple;
2271 ctx->Driver.RenderMode = radeonRenderMode;
2272 ctx->Driver.Scissor = radeonScissor;
2273 ctx->Driver.ShadeModel = radeonShadeModel;
2274 ctx->Driver.StencilFunc = radeonStencilFunc;
2275 ctx->Driver.StencilMask = radeonStencilMask;
2276 ctx->Driver.StencilOp = radeonStencilOp;
2277 ctx->Driver.Viewport = radeonViewport;
2278
2279 TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2280 TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2281 }