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