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