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