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