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