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