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