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