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