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