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