mesa: don't update draw buffer bounds in _mesa_update_state
[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/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/core.h"
45 #include "main/stencil.h"
46 #include "main/viewport.h"
47
48 #include "vbo/vbo.h"
49 #include "tnl/tnl.h"
50 #include "tnl/t_pipeline.h"
51 #include "swrast_setup/swrast_setup.h"
52 #include "drivers/common/meta.h"
53 #include "util/bitscan.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 GLbitfield mask = ctx->Light._EnabledLights;
896 while (mask) {
897 const int p = u_bit_scan(&mask);
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 static void radeonLightfv( struct gl_context *ctx, GLenum light,
920 GLenum pname, const GLfloat *params )
921 {
922 r100ContextPtr rmesa = R100_CONTEXT(ctx);
923 GLint p = light - GL_LIGHT0;
924 struct gl_light *l = &ctx->Light.Light[p];
925 GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
926
927
928 switch (pname) {
929 case GL_AMBIENT:
930 case GL_DIFFUSE:
931 case GL_SPECULAR:
932 update_light_colors( ctx, p );
933 break;
934
935 case GL_SPOT_DIRECTION:
936 /* picked up in update_light */
937 break;
938
939 case GL_POSITION: {
940 /* positions picked up in update_light, but can do flag here */
941 GLuint flag;
942 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
943
944 /* FIXME: Set RANGE_ATTEN only when needed */
945 if (p&1)
946 flag = RADEON_LIGHT_1_IS_LOCAL;
947 else
948 flag = RADEON_LIGHT_0_IS_LOCAL;
949
950 RADEON_STATECHANGE(rmesa, tcl);
951 if (l->EyePosition[3] != 0.0F)
952 rmesa->hw.tcl.cmd[idx] |= flag;
953 else
954 rmesa->hw.tcl.cmd[idx] &= ~flag;
955 break;
956 }
957
958 case GL_SPOT_EXPONENT:
959 RADEON_STATECHANGE(rmesa, lit[p]);
960 fcmd[LIT_SPOT_EXPONENT] = params[0];
961 break;
962
963 case GL_SPOT_CUTOFF: {
964 GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
965 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
966
967 RADEON_STATECHANGE(rmesa, lit[p]);
968 fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
969
970 RADEON_STATECHANGE(rmesa, tcl);
971 if (l->SpotCutoff != 180.0F)
972 rmesa->hw.tcl.cmd[idx] |= flag;
973 else
974 rmesa->hw.tcl.cmd[idx] &= ~flag;
975
976 break;
977 }
978
979 case GL_CONSTANT_ATTENUATION:
980 RADEON_STATECHANGE(rmesa, lit[p]);
981 fcmd[LIT_ATTEN_CONST] = params[0];
982 if ( params[0] == 0.0 )
983 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
984 else
985 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
986 break;
987 case GL_LINEAR_ATTENUATION:
988 RADEON_STATECHANGE(rmesa, lit[p]);
989 fcmd[LIT_ATTEN_LINEAR] = params[0];
990 break;
991 case GL_QUADRATIC_ATTENUATION:
992 RADEON_STATECHANGE(rmesa, lit[p]);
993 fcmd[LIT_ATTEN_QUADRATIC] = params[0];
994 break;
995 default:
996 return;
997 }
998
999 /* Set RANGE_ATTEN only when needed */
1000 switch (pname) {
1001 case GL_POSITION:
1002 case GL_CONSTANT_ATTENUATION:
1003 case GL_LINEAR_ATTENUATION:
1004 case GL_QUADRATIC_ATTENUATION:
1005 {
1006 GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
1007 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1008 GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1009 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
1010 GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1011 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
1012
1013 if ( l->EyePosition[3] == 0.0F ||
1014 ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1015 fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1016 /* Disable attenuation */
1017 icmd[idx] &= ~atten_flag;
1018 } else {
1019 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1020 /* Enable only constant portion of attenuation calculation */
1021 icmd[idx] |= ( atten_flag | atten_const_flag );
1022 } else {
1023 /* Enable full attenuation calculation */
1024 icmd[idx] &= ~atten_const_flag;
1025 icmd[idx] |= atten_flag;
1026 }
1027 }
1028
1029 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1030 break;
1031 }
1032 default:
1033 break;
1034 }
1035 }
1036
1037
1038
1039
1040 static void radeonLightModelfv( struct gl_context *ctx, GLenum pname,
1041 const GLfloat *param )
1042 {
1043 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1044
1045 switch (pname) {
1046 case GL_LIGHT_MODEL_AMBIENT:
1047 update_global_ambient( ctx );
1048 break;
1049
1050 case GL_LIGHT_MODEL_LOCAL_VIEWER:
1051 RADEON_STATECHANGE( rmesa, tcl );
1052 if (ctx->Light.Model.LocalViewer)
1053 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
1054 else
1055 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
1056 break;
1057
1058 case GL_LIGHT_MODEL_TWO_SIDE:
1059 RADEON_STATECHANGE( rmesa, tcl );
1060 if (ctx->Light.Model.TwoSide)
1061 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
1062 else
1063 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
1064
1065 check_twoside_fallback( ctx );
1066
1067 if (rmesa->radeon.TclFallback) {
1068 radeonChooseRenderState( ctx );
1069 radeonChooseVertexState( ctx );
1070 }
1071 break;
1072
1073 case GL_LIGHT_MODEL_COLOR_CONTROL:
1074 radeonUpdateSpecular(ctx);
1075 break;
1076
1077 default:
1078 break;
1079 }
1080 }
1081
1082 static void radeonShadeModel( struct gl_context *ctx, GLenum mode )
1083 {
1084 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1085 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1086
1087 s &= ~(RADEON_DIFFUSE_SHADE_MASK |
1088 RADEON_ALPHA_SHADE_MASK |
1089 RADEON_SPECULAR_SHADE_MASK |
1090 RADEON_FOG_SHADE_MASK);
1091
1092 switch ( mode ) {
1093 case GL_FLAT:
1094 s |= (RADEON_DIFFUSE_SHADE_FLAT |
1095 RADEON_ALPHA_SHADE_FLAT |
1096 RADEON_SPECULAR_SHADE_FLAT |
1097 RADEON_FOG_SHADE_FLAT);
1098 break;
1099 case GL_SMOOTH:
1100 s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
1101 RADEON_ALPHA_SHADE_GOURAUD |
1102 RADEON_SPECULAR_SHADE_GOURAUD |
1103 RADEON_FOG_SHADE_GOURAUD);
1104 break;
1105 default:
1106 return;
1107 }
1108
1109 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1110 RADEON_STATECHANGE( rmesa, set );
1111 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1112 }
1113 }
1114
1115
1116 /* =============================================================
1117 * User clip planes
1118 */
1119
1120 static void radeonClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1121 {
1122 GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1123 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1124 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1125
1126 RADEON_STATECHANGE( rmesa, ucp[p] );
1127 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1128 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1129 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1130 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1131 }
1132
1133 static void radeonUpdateClipPlanes( struct gl_context *ctx )
1134 {
1135 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1136 GLbitfield mask = ctx->Transform.ClipPlanesEnabled;
1137
1138 while (mask) {
1139 const int p = u_bit_scan(&mask);
1140 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1141
1142 RADEON_STATECHANGE( rmesa, ucp[p] );
1143 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1144 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1145 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1146 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1147 }
1148 }
1149
1150
1151 /* =============================================================
1152 * Stencil
1153 */
1154
1155 static void
1156 radeonStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1157 GLint ref, GLuint mask )
1158 {
1159 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1160 GLuint refmask = ((_mesa_get_stencil_ref(ctx, 0) << RADEON_STENCIL_REF_SHIFT) |
1161 ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
1162
1163 RADEON_STATECHANGE( rmesa, ctx );
1164 RADEON_STATECHANGE( rmesa, msk );
1165
1166 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
1167 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
1168 RADEON_STENCIL_VALUE_MASK);
1169
1170 switch ( ctx->Stencil.Function[0] ) {
1171 case GL_NEVER:
1172 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
1173 break;
1174 case GL_LESS:
1175 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
1176 break;
1177 case GL_EQUAL:
1178 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
1179 break;
1180 case GL_LEQUAL:
1181 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
1182 break;
1183 case GL_GREATER:
1184 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
1185 break;
1186 case GL_NOTEQUAL:
1187 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
1188 break;
1189 case GL_GEQUAL:
1190 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
1191 break;
1192 case GL_ALWAYS:
1193 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
1194 break;
1195 }
1196
1197 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1198 }
1199
1200 static void
1201 radeonStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1202 {
1203 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1204
1205 RADEON_STATECHANGE( rmesa, msk );
1206 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
1207 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1208 ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
1209 }
1210
1211 static void radeonStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1212 GLenum zfail, GLenum zpass )
1213 {
1214 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1215
1216 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1217 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1218 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1219
1220 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
1221 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
1222 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1223 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1224 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1225 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
1226
1227 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
1228 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
1229 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
1230 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
1231 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
1232 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
1233 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
1234 }
1235 else {
1236 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
1237 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
1238 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
1239 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
1240 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
1241 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
1242 }
1243
1244 RADEON_STATECHANGE( rmesa, ctx );
1245 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1246 RADEON_STENCIL_ZFAIL_MASK |
1247 RADEON_STENCIL_ZPASS_MASK);
1248
1249 switch ( ctx->Stencil.FailFunc[0] ) {
1250 case GL_KEEP:
1251 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1252 break;
1253 case GL_ZERO:
1254 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1255 break;
1256 case GL_REPLACE:
1257 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1258 break;
1259 case GL_INCR:
1260 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1261 break;
1262 case GL_DECR:
1263 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1264 break;
1265 case GL_INCR_WRAP:
1266 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
1267 break;
1268 case GL_DECR_WRAP:
1269 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
1270 break;
1271 case GL_INVERT:
1272 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1273 break;
1274 }
1275
1276 switch ( ctx->Stencil.ZFailFunc[0] ) {
1277 case GL_KEEP:
1278 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1279 break;
1280 case GL_ZERO:
1281 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1282 break;
1283 case GL_REPLACE:
1284 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1285 break;
1286 case GL_INCR:
1287 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1288 break;
1289 case GL_DECR:
1290 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1291 break;
1292 case GL_INCR_WRAP:
1293 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1294 break;
1295 case GL_DECR_WRAP:
1296 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1297 break;
1298 case GL_INVERT:
1299 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1300 break;
1301 }
1302
1303 switch ( ctx->Stencil.ZPassFunc[0] ) {
1304 case GL_KEEP:
1305 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1306 break;
1307 case GL_ZERO:
1308 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1309 break;
1310 case GL_REPLACE:
1311 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1312 break;
1313 case GL_INCR:
1314 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1315 break;
1316 case GL_DECR:
1317 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1318 break;
1319 case GL_INCR_WRAP:
1320 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
1321 break;
1322 case GL_DECR_WRAP:
1323 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1324 break;
1325 case GL_INVERT:
1326 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1327 break;
1328 }
1329 }
1330
1331
1332
1333 /* =============================================================
1334 * Window position and viewport transformation
1335 */
1336
1337 /*
1338 * To correctly position primitives:
1339 */
1340 #define SUBPIXEL_X 0.125
1341 #define SUBPIXEL_Y 0.125
1342
1343
1344 /**
1345 * Called when window size or position changes or viewport or depth range
1346 * state is changed. We update the hardware viewport state here.
1347 */
1348 void radeonUpdateWindow( struct gl_context *ctx )
1349 {
1350 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1351 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1352 GLfloat xoffset = 0.0;
1353 GLfloat yoffset = dPriv ? (GLfloat) dPriv->h : 0;
1354 const GLboolean render_to_fbo = (ctx->DrawBuffer ? _mesa_is_user_fbo(ctx->DrawBuffer) : 0);
1355 float scale[3], translate[3];
1356 GLfloat y_scale, y_bias;
1357
1358 if (render_to_fbo) {
1359 y_scale = 1.0;
1360 y_bias = 0;
1361 } else {
1362 y_scale = -1.0;
1363 y_bias = yoffset;
1364 }
1365
1366 _mesa_get_viewport_xform(ctx, 0, scale, translate);
1367 float_ui32_type sx = { scale[0] };
1368 float_ui32_type sy = { scale[1] * y_scale };
1369 float_ui32_type sz = { scale[2] };
1370 float_ui32_type tx = { translate[0] + xoffset + SUBPIXEL_X };
1371 float_ui32_type ty = { (translate[1] * y_scale) + y_bias + SUBPIXEL_Y };
1372 float_ui32_type tz = { translate[2] };
1373
1374 RADEON_STATECHANGE( rmesa, vpt );
1375
1376 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32;
1377 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1378 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32;
1379 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1380 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32;
1381 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1382 }
1383
1384
1385 static void radeonViewport(struct gl_context *ctx)
1386 {
1387 /* Don't pipeline viewport changes, conflict with window offset
1388 * setting below. Could apply deltas to rescue pipelined viewport
1389 * values, or keep the originals hanging around.
1390 */
1391 radeonUpdateWindow( ctx );
1392
1393 radeon_viewport(ctx);
1394 }
1395
1396 static void radeonDepthRange(struct gl_context *ctx)
1397 {
1398 radeonUpdateWindow( ctx );
1399 }
1400
1401 /* =============================================================
1402 * Miscellaneous
1403 */
1404
1405 static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
1406 {
1407 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1408 FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1409 }
1410
1411
1412 static GLuint radeon_rop_tab[] = {
1413 RADEON_ROP_CLEAR,
1414 RADEON_ROP_AND,
1415 RADEON_ROP_AND_REVERSE,
1416 RADEON_ROP_COPY,
1417 RADEON_ROP_AND_INVERTED,
1418 RADEON_ROP_NOOP,
1419 RADEON_ROP_XOR,
1420 RADEON_ROP_OR,
1421 RADEON_ROP_NOR,
1422 RADEON_ROP_EQUIV,
1423 RADEON_ROP_INVERT,
1424 RADEON_ROP_OR_REVERSE,
1425 RADEON_ROP_COPY_INVERTED,
1426 RADEON_ROP_OR_INVERTED,
1427 RADEON_ROP_NAND,
1428 RADEON_ROP_SET,
1429 };
1430
1431 static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode )
1432 {
1433 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1434 GLuint rop = (GLuint)opcode - GL_CLEAR;
1435
1436 assert( rop < 16 );
1437
1438 RADEON_STATECHANGE( rmesa, msk );
1439 rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1440 }
1441
1442 /* =============================================================
1443 * State enable/disable
1444 */
1445
1446 static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
1447 {
1448 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1449 GLuint p, flag;
1450
1451 if ( RADEON_DEBUG & RADEON_STATE )
1452 fprintf( stderr, "%s( %s = %s )\n", __func__,
1453 _mesa_enum_to_string( cap ),
1454 state ? "GL_TRUE" : "GL_FALSE" );
1455
1456 switch ( cap ) {
1457 /* Fast track this one...
1458 */
1459 case GL_TEXTURE_1D:
1460 case GL_TEXTURE_2D:
1461 case GL_TEXTURE_3D:
1462 break;
1463
1464 case GL_ALPHA_TEST:
1465 RADEON_STATECHANGE( rmesa, ctx );
1466 if (state) {
1467 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1468 } else {
1469 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1470 }
1471 break;
1472
1473 case GL_BLEND:
1474 RADEON_STATECHANGE( rmesa, ctx );
1475 if (state) {
1476 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE;
1477 } else {
1478 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1479 }
1480 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1481 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1482 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1483 } else {
1484 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1485 }
1486
1487 /* Catch a possible fallback:
1488 */
1489 if (state) {
1490 ctx->Driver.BlendEquationSeparate( ctx,
1491 ctx->Color.Blend[0].EquationRGB,
1492 ctx->Color.Blend[0].EquationA );
1493 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
1494 ctx->Color.Blend[0].DstRGB,
1495 ctx->Color.Blend[0].SrcA,
1496 ctx->Color.Blend[0].DstA );
1497 }
1498 else {
1499 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1500 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1501 }
1502 break;
1503
1504 case GL_CLIP_PLANE0:
1505 case GL_CLIP_PLANE1:
1506 case GL_CLIP_PLANE2:
1507 case GL_CLIP_PLANE3:
1508 case GL_CLIP_PLANE4:
1509 case GL_CLIP_PLANE5:
1510 p = cap-GL_CLIP_PLANE0;
1511 RADEON_STATECHANGE( rmesa, tcl );
1512 if (state) {
1513 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1514 radeonClipPlane( ctx, cap, NULL );
1515 }
1516 else {
1517 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1518 }
1519 break;
1520
1521 case GL_COLOR_MATERIAL:
1522 radeonColorMaterial( ctx, 0, 0 );
1523 radeonUpdateMaterial( ctx );
1524 break;
1525
1526 case GL_CULL_FACE:
1527 radeonCullFace( ctx, 0 );
1528 break;
1529
1530 case GL_DEPTH_TEST:
1531 RADEON_STATECHANGE(rmesa, ctx );
1532 if ( state ) {
1533 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE;
1534 } else {
1535 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1536 }
1537 break;
1538
1539 case GL_DITHER:
1540 RADEON_STATECHANGE(rmesa, ctx );
1541 if ( state ) {
1542 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE;
1543 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1544 } else {
1545 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1546 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable;
1547 }
1548 break;
1549
1550 case GL_FOG:
1551 RADEON_STATECHANGE(rmesa, ctx );
1552 if ( state ) {
1553 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1554 radeonFogfv( ctx, GL_FOG_MODE, NULL );
1555 } else {
1556 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1557 RADEON_STATECHANGE(rmesa, tcl);
1558 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1559 }
1560 radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1561 _mesa_allow_light_in_model( ctx, !state );
1562 break;
1563
1564 case GL_LIGHT0:
1565 case GL_LIGHT1:
1566 case GL_LIGHT2:
1567 case GL_LIGHT3:
1568 case GL_LIGHT4:
1569 case GL_LIGHT5:
1570 case GL_LIGHT6:
1571 case GL_LIGHT7:
1572 RADEON_STATECHANGE(rmesa, tcl);
1573 p = cap - GL_LIGHT0;
1574 if (p&1)
1575 flag = (RADEON_LIGHT_1_ENABLE |
1576 RADEON_LIGHT_1_ENABLE_AMBIENT |
1577 RADEON_LIGHT_1_ENABLE_SPECULAR);
1578 else
1579 flag = (RADEON_LIGHT_0_ENABLE |
1580 RADEON_LIGHT_0_ENABLE_AMBIENT |
1581 RADEON_LIGHT_0_ENABLE_SPECULAR);
1582
1583 if (state)
1584 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1585 else
1586 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1587
1588 /*
1589 */
1590 update_light_colors( ctx, p );
1591 break;
1592
1593 case GL_LIGHTING:
1594 RADEON_STATECHANGE(rmesa, tcl);
1595 radeonUpdateSpecular(ctx);
1596 check_twoside_fallback( ctx );
1597 break;
1598
1599 case GL_LINE_SMOOTH:
1600 RADEON_STATECHANGE( rmesa, ctx );
1601 if ( state ) {
1602 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE;
1603 } else {
1604 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1605 }
1606 break;
1607
1608 case GL_LINE_STIPPLE:
1609 RADEON_STATECHANGE( rmesa, ctx );
1610 if ( state ) {
1611 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE;
1612 } else {
1613 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1614 }
1615 break;
1616
1617 case GL_COLOR_LOGIC_OP:
1618 RADEON_STATECHANGE( rmesa, ctx );
1619 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1620 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1621 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1622 } else {
1623 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1624 }
1625 break;
1626
1627 case GL_NORMALIZE:
1628 RADEON_STATECHANGE( rmesa, tcl );
1629 if ( state ) {
1630 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS;
1631 } else {
1632 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1633 }
1634 break;
1635
1636 case GL_POLYGON_OFFSET_POINT:
1637 RADEON_STATECHANGE( rmesa, set );
1638 if ( state ) {
1639 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
1640 } else {
1641 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1642 }
1643 break;
1644
1645 case GL_POLYGON_OFFSET_LINE:
1646 RADEON_STATECHANGE( rmesa, set );
1647 if ( state ) {
1648 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
1649 } else {
1650 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1651 }
1652 break;
1653
1654 case GL_POLYGON_OFFSET_FILL:
1655 RADEON_STATECHANGE( rmesa, set );
1656 if ( state ) {
1657 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
1658 } else {
1659 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1660 }
1661 break;
1662
1663 case GL_POLYGON_SMOOTH:
1664 RADEON_STATECHANGE( rmesa, ctx );
1665 if ( state ) {
1666 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY;
1667 } else {
1668 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1669 }
1670 break;
1671
1672 case GL_POLYGON_STIPPLE:
1673 RADEON_STATECHANGE(rmesa, ctx );
1674 if ( state ) {
1675 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE;
1676 } else {
1677 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1678 }
1679 break;
1680
1681 case GL_RESCALE_NORMAL_EXT: {
1682 GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1683 RADEON_STATECHANGE( rmesa, tcl );
1684 if ( tmp ) {
1685 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1686 } else {
1687 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1688 }
1689 break;
1690 }
1691
1692 case GL_SCISSOR_TEST:
1693 radeon_firevertices(&rmesa->radeon);
1694 rmesa->radeon.state.scissor.enabled = state;
1695 radeonUpdateScissor( ctx );
1696 break;
1697
1698 case GL_STENCIL_TEST:
1699 {
1700 GLboolean hw_stencil = GL_FALSE;
1701 if (ctx->DrawBuffer) {
1702 struct radeon_renderbuffer *rrbStencil
1703 = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1704 hw_stencil = (rrbStencil && rrbStencil->bo);
1705 }
1706
1707 if (hw_stencil) {
1708 RADEON_STATECHANGE( rmesa, ctx );
1709 if ( state ) {
1710 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE;
1711 } else {
1712 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1713 }
1714 } else {
1715 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1716 }
1717 }
1718 break;
1719
1720 case GL_TEXTURE_GEN_Q:
1721 case GL_TEXTURE_GEN_R:
1722 case GL_TEXTURE_GEN_S:
1723 case GL_TEXTURE_GEN_T:
1724 /* Picked up in radeonUpdateTextureState.
1725 */
1726 rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1727 break;
1728
1729 case GL_COLOR_SUM_EXT:
1730 radeonUpdateSpecular ( ctx );
1731 break;
1732
1733 default:
1734 return;
1735 }
1736 }
1737
1738
1739 static void radeonLightingSpaceChange( struct gl_context *ctx )
1740 {
1741 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1742 GLboolean tmp;
1743 RADEON_STATECHANGE( rmesa, tcl );
1744
1745 if (RADEON_DEBUG & RADEON_STATE)
1746 fprintf(stderr, "%s %d BEFORE %x\n", __func__, ctx->_NeedEyeCoords,
1747 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1748
1749 if (ctx->_NeedEyeCoords)
1750 tmp = ctx->Transform.RescaleNormals;
1751 else
1752 tmp = !ctx->Transform.RescaleNormals;
1753
1754 if ( tmp ) {
1755 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1756 } else {
1757 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1758 }
1759
1760 if (RADEON_DEBUG & RADEON_STATE)
1761 fprintf(stderr, "%s %d AFTER %x\n", __func__, ctx->_NeedEyeCoords,
1762 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1763 }
1764
1765 /* =============================================================
1766 * Deferred state management - matrices, textures, other?
1767 */
1768
1769
1770 void radeonUploadTexMatrix( r100ContextPtr rmesa,
1771 int unit, GLboolean swapcols )
1772 {
1773 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1774 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1775 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1776 texgen generates all 4 coords, at least tests with projtex indicated that.
1777 So: if we need the q coord in the end (solely determined by the texture
1778 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1779 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1780 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1781 will get submitted in the "wrong", i.e. 3rd, slot.
1782 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1783 size and using the texture matrix to swap the r and q coords around (ut2k3
1784 does exactly that), so we don't need the 3rd / 4th column swap - still need
1785 the 3rd / 4th row swap of course. This will potentially break for apps which
1786 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1787 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1788 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1789 incredibly hard to detect so we can't just fallback in such a case. Assume
1790 it never happens... - rs
1791 */
1792
1793 int idx = TEXMAT_0 + unit;
1794 float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1795 int i;
1796 struct gl_texture_unit tUnit = rmesa->radeon.glCtx.Texture.Unit[unit];
1797 GLfloat *src = rmesa->tmpmat[unit].m;
1798
1799 rmesa->TexMatColSwap &= ~(1 << unit);
1800 if (!tUnit._Current ||
1801 (tUnit._Current->Target != GL_TEXTURE_3D &&
1802 tUnit._Current->Target != GL_TEXTURE_CUBE_MAP)) {
1803 if (swapcols) {
1804 rmesa->TexMatColSwap |= 1 << unit;
1805 /* attention some elems are swapped 2 times! */
1806 *dest++ = src[0];
1807 *dest++ = src[4];
1808 *dest++ = src[12];
1809 *dest++ = src[8];
1810 *dest++ = src[1];
1811 *dest++ = src[5];
1812 *dest++ = src[13];
1813 *dest++ = src[9];
1814 *dest++ = src[2];
1815 *dest++ = src[6];
1816 *dest++ = src[15];
1817 *dest++ = src[11];
1818 /* those last 4 are probably never used */
1819 *dest++ = src[3];
1820 *dest++ = src[7];
1821 *dest++ = src[14];
1822 *dest++ = src[10];
1823 }
1824 else {
1825 for (i = 0; i < 2; i++) {
1826 *dest++ = src[i];
1827 *dest++ = src[i+4];
1828 *dest++ = src[i+8];
1829 *dest++ = src[i+12];
1830 }
1831 for (i = 3; i >= 2; i--) {
1832 *dest++ = src[i];
1833 *dest++ = src[i+4];
1834 *dest++ = src[i+8];
1835 *dest++ = src[i+12];
1836 }
1837 }
1838 }
1839 else {
1840 for (i = 0 ; i < 4 ; i++) {
1841 *dest++ = src[i];
1842 *dest++ = src[i+4];
1843 *dest++ = src[i+8];
1844 *dest++ = src[i+12];
1845 }
1846 }
1847
1848 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1849 }
1850
1851
1852 static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1853 {
1854 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1855 int i;
1856
1857
1858 for (i = 0 ; i < 4 ; i++) {
1859 *dest++ = src[i];
1860 *dest++ = src[i+4];
1861 *dest++ = src[i+8];
1862 *dest++ = src[i+12];
1863 }
1864
1865 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1866 }
1867
1868 static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1869 {
1870 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1871 memcpy(dest, src, 16*sizeof(float));
1872 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1873 }
1874
1875
1876 static void update_texturematrix( struct gl_context *ctx )
1877 {
1878 r100ContextPtr rmesa = R100_CONTEXT( ctx );
1879 GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
1880 GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
1881 int unit;
1882 GLuint texMatEnabled = 0;
1883 rmesa->NeedTexMatrix = 0;
1884 rmesa->TexMatColSwap = 0;
1885
1886 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
1887 if (ctx->Texture.Unit[unit]._Current) {
1888 GLboolean needMatrix = GL_FALSE;
1889 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
1890 needMatrix = GL_TRUE;
1891 texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
1892 RADEON_TEXMAT_0_ENABLE) << unit;
1893
1894 if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1895 /* Need to preconcatenate any active texgen
1896 * obj/eyeplane matrices:
1897 */
1898 _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
1899 ctx->TextureMatrixStack[unit].Top,
1900 &rmesa->TexGenMatrix[unit] );
1901 }
1902 else {
1903 _math_matrix_copy( &rmesa->tmpmat[unit],
1904 ctx->TextureMatrixStack[unit].Top );
1905 }
1906 }
1907 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1908 _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
1909 needMatrix = GL_TRUE;
1910 }
1911 if (needMatrix) {
1912 rmesa->NeedTexMatrix |= 1 << unit;
1913 radeonUploadTexMatrix( rmesa, unit,
1914 !ctx->Texture.Unit[unit].TexGenEnabled );
1915 }
1916 }
1917 }
1918
1919 tpc = (texMatEnabled | rmesa->TexGenEnabled);
1920
1921 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1922 vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
1923 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
1924 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
1925
1926 vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
1927 (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
1928 ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
1929 (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
1930 ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
1931 (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
1932
1933 if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
1934 vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
1935
1936 RADEON_STATECHANGE(rmesa, tcl);
1937 rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
1938 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
1939 }
1940 }
1941
1942 GLboolean r100ValidateBuffers(struct gl_context *ctx)
1943 {
1944 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1945 struct radeon_renderbuffer *rrb;
1946 int i, ret;
1947
1948 radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
1949
1950 rrb = radeon_get_colorbuffer(&rmesa->radeon);
1951 /* color buffer */
1952 if (rrb && rrb->bo) {
1953 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
1954 0, RADEON_GEM_DOMAIN_VRAM);
1955 }
1956
1957 /* depth buffer */
1958 rrb = radeon_get_depthbuffer(&rmesa->radeon);
1959 /* color buffer */
1960 if (rrb && rrb->bo) {
1961 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
1962 0, RADEON_GEM_DOMAIN_VRAM);
1963 }
1964
1965 for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; ++i) {
1966 radeonTexObj *t;
1967
1968 if (!ctx->Texture.Unit[i]._Current)
1969 continue;
1970
1971 t = rmesa->state.texture.unit[i].texobj;
1972
1973 if (!t)
1974 continue;
1975 if (t->image_override && t->bo)
1976 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
1977 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
1978 else if (t->mt->bo)
1979 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
1980 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
1981 }
1982
1983 ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
1984 if (ret)
1985 return GL_FALSE;
1986 return GL_TRUE;
1987 }
1988
1989 GLboolean radeonValidateState( struct gl_context *ctx )
1990 {
1991 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1992 GLuint new_state = rmesa->radeon.NewGLState;
1993
1994 if (new_state & _NEW_BUFFERS) {
1995 _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
1996 /* this updates the DrawBuffer's Width/Height if it's a FBO */
1997 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
1998 RADEON_STATECHANGE(rmesa, ctx);
1999 }
2000
2001 if (new_state & _NEW_TEXTURE) {
2002 radeonUpdateTextureState( ctx );
2003 new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2004 }
2005
2006 /* we need to do a space check here */
2007 if (!r100ValidateBuffers(ctx))
2008 return GL_FALSE;
2009
2010 /* Need an event driven matrix update?
2011 */
2012 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2013 upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2014
2015 /* Need these for lighting (shouldn't upload otherwise)
2016 */
2017 if (new_state & (_NEW_MODELVIEW)) {
2018 upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2019 upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2020 }
2021
2022 /* Does this need to be triggered on eg. modelview for
2023 * texgen-derived objplane/eyeplane matrices?
2024 */
2025 if (new_state & _NEW_TEXTURE_MATRIX) {
2026 update_texturematrix( ctx );
2027 }
2028
2029 if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2030 update_light( ctx );
2031 }
2032
2033 /* emit all active clip planes if projection matrix changes.
2034 */
2035 if (new_state & (_NEW_PROJECTION)) {
2036 if (ctx->Transform.ClipPlanesEnabled)
2037 radeonUpdateClipPlanes( ctx );
2038 }
2039
2040
2041 rmesa->radeon.NewGLState = 0;
2042
2043 return GL_TRUE;
2044 }
2045
2046
2047 static void radeonInvalidateState(struct gl_context *ctx)
2048 {
2049 GLuint new_state = ctx->NewState;
2050
2051 if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
2052 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
2053
2054 _swrast_InvalidateState( ctx, new_state );
2055 _swsetup_InvalidateState( ctx, new_state );
2056 _tnl_InvalidateState( ctx, new_state );
2057 R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2058 }
2059
2060
2061 /* A hack. Need a faster way to find this out.
2062 */
2063 static GLboolean check_material( struct gl_context *ctx )
2064 {
2065 TNLcontext *tnl = TNL_CONTEXT(ctx);
2066 GLint i;
2067
2068 for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2069 i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2070 i++)
2071 if (tnl->vb.AttribPtr[i] &&
2072 tnl->vb.AttribPtr[i]->stride)
2073 return GL_TRUE;
2074
2075 return GL_FALSE;
2076 }
2077
2078
2079 static void radeonWrapRunPipeline( struct gl_context *ctx )
2080 {
2081 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2082 GLboolean has_material;
2083
2084 if (0)
2085 fprintf(stderr, "%s, newstate: %x\n", __func__, rmesa->radeon.NewGLState);
2086
2087 /* Validate state:
2088 */
2089 if (rmesa->radeon.NewGLState)
2090 if (!radeonValidateState( ctx ))
2091 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2092
2093 has_material = (ctx->Light.Enabled && check_material( ctx ));
2094
2095 if (has_material) {
2096 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2097 }
2098
2099 /* Run the pipeline.
2100 */
2101 _tnl_run_pipeline( ctx );
2102
2103 if (has_material) {
2104 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2105 }
2106 }
2107
2108 static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2109 {
2110 r100ContextPtr r100 = R100_CONTEXT(ctx);
2111 GLint i;
2112
2113 radeon_firevertices(&r100->radeon);
2114
2115 RADEON_STATECHANGE(r100, stp);
2116
2117 /* Must flip pattern upside down.
2118 */
2119 for ( i = 31 ; i >= 0; i--) {
2120 r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2121 }
2122 }
2123
2124
2125 /* Initialize the driver's state functions.
2126 * Many of the ctx->Driver functions might have been initialized to
2127 * software defaults in the earlier _mesa_init_driver_functions() call.
2128 */
2129 void radeonInitStateFuncs( struct gl_context *ctx )
2130 {
2131 ctx->Driver.UpdateState = radeonInvalidateState;
2132 ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
2133
2134 ctx->Driver.DrawBuffer = radeonDrawBuffer;
2135 ctx->Driver.ReadBuffer = radeonReadBuffer;
2136 ctx->Driver.CopyPixels = _mesa_meta_CopyPixels;
2137 ctx->Driver.DrawPixels = _mesa_meta_DrawPixels;
2138 ctx->Driver.ReadPixels = radeonReadPixels;
2139
2140 ctx->Driver.AlphaFunc = radeonAlphaFunc;
2141 ctx->Driver.BlendEquationSeparate = radeonBlendEquationSeparate;
2142 ctx->Driver.BlendFuncSeparate = radeonBlendFuncSeparate;
2143 ctx->Driver.ClipPlane = radeonClipPlane;
2144 ctx->Driver.ColorMask = radeonColorMask;
2145 ctx->Driver.CullFace = radeonCullFace;
2146 ctx->Driver.DepthFunc = radeonDepthFunc;
2147 ctx->Driver.DepthMask = radeonDepthMask;
2148 ctx->Driver.DepthRange = radeonDepthRange;
2149 ctx->Driver.Enable = radeonEnable;
2150 ctx->Driver.Fogfv = radeonFogfv;
2151 ctx->Driver.FrontFace = radeonFrontFace;
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 }