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