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