s/Tungsten Graphics/VMware/
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_state.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keithw@vmware.com>
33 */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/fbobject.h"
43 #include "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)
1398 {
1399 radeonUpdateWindow( ctx );
1400 }
1401
1402 void radeonUpdateViewportOffset( struct gl_context *ctx )
1403 {
1404 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1405 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1406 GLfloat xoffset = 0.0;
1407 GLfloat yoffset = (GLfloat)dPriv->h;
1408 const GLfloat *v = ctx->Viewport._WindowMap.m;
1409
1410 float_ui32_type tx;
1411 float_ui32_type ty;
1412
1413 tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X;
1414 ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1415
1416 if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
1417 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
1418 {
1419 /* Note: this should also modify whatever data the context reset
1420 * code uses...
1421 */
1422 RADEON_STATECHANGE( rmesa, vpt );
1423 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1424 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1425
1426 /* update polygon stipple x/y screen offset */
1427 {
1428 GLuint stx, sty;
1429 GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1430
1431 m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
1432 RADEON_STIPPLE_Y_OFFSET_MASK);
1433
1434 /* add magic offsets, then invert */
1435 stx = 31 - ((-1) & RADEON_STIPPLE_COORD_MASK);
1436 sty = 31 - ((dPriv->h - 1)
1437 & RADEON_STIPPLE_COORD_MASK);
1438
1439 m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
1440 (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
1441
1442 if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1443 RADEON_STATECHANGE( rmesa, msc );
1444 rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1445 }
1446 }
1447 }
1448
1449 radeonUpdateScissor( ctx );
1450 }
1451
1452
1453
1454 /* =============================================================
1455 * Miscellaneous
1456 */
1457
1458 static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
1459 {
1460 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1461 FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1462 }
1463
1464
1465 static GLuint radeon_rop_tab[] = {
1466 RADEON_ROP_CLEAR,
1467 RADEON_ROP_AND,
1468 RADEON_ROP_AND_REVERSE,
1469 RADEON_ROP_COPY,
1470 RADEON_ROP_AND_INVERTED,
1471 RADEON_ROP_NOOP,
1472 RADEON_ROP_XOR,
1473 RADEON_ROP_OR,
1474 RADEON_ROP_NOR,
1475 RADEON_ROP_EQUIV,
1476 RADEON_ROP_INVERT,
1477 RADEON_ROP_OR_REVERSE,
1478 RADEON_ROP_COPY_INVERTED,
1479 RADEON_ROP_OR_INVERTED,
1480 RADEON_ROP_NAND,
1481 RADEON_ROP_SET,
1482 };
1483
1484 static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode )
1485 {
1486 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1487 GLuint rop = (GLuint)opcode - GL_CLEAR;
1488
1489 ASSERT( rop < 16 );
1490
1491 RADEON_STATECHANGE( rmesa, msk );
1492 rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1493 }
1494
1495 /* =============================================================
1496 * State enable/disable
1497 */
1498
1499 static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
1500 {
1501 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1502 GLuint p, flag;
1503
1504 if ( RADEON_DEBUG & RADEON_STATE )
1505 fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1506 _mesa_lookup_enum_by_nr( cap ),
1507 state ? "GL_TRUE" : "GL_FALSE" );
1508
1509 switch ( cap ) {
1510 /* Fast track this one...
1511 */
1512 case GL_TEXTURE_1D:
1513 case GL_TEXTURE_2D:
1514 case GL_TEXTURE_3D:
1515 break;
1516
1517 case GL_ALPHA_TEST:
1518 RADEON_STATECHANGE( rmesa, ctx );
1519 if (state) {
1520 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1521 } else {
1522 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1523 }
1524 break;
1525
1526 case GL_BLEND:
1527 RADEON_STATECHANGE( rmesa, ctx );
1528 if (state) {
1529 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE;
1530 } else {
1531 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1532 }
1533 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1534 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1535 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1536 } else {
1537 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1538 }
1539
1540 /* Catch a possible fallback:
1541 */
1542 if (state) {
1543 ctx->Driver.BlendEquationSeparate( ctx,
1544 ctx->Color.Blend[0].EquationRGB,
1545 ctx->Color.Blend[0].EquationA );
1546 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
1547 ctx->Color.Blend[0].DstRGB,
1548 ctx->Color.Blend[0].SrcA,
1549 ctx->Color.Blend[0].DstA );
1550 }
1551 else {
1552 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1553 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1554 }
1555 break;
1556
1557 case GL_CLIP_PLANE0:
1558 case GL_CLIP_PLANE1:
1559 case GL_CLIP_PLANE2:
1560 case GL_CLIP_PLANE3:
1561 case GL_CLIP_PLANE4:
1562 case GL_CLIP_PLANE5:
1563 p = cap-GL_CLIP_PLANE0;
1564 RADEON_STATECHANGE( rmesa, tcl );
1565 if (state) {
1566 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1567 radeonClipPlane( ctx, cap, NULL );
1568 }
1569 else {
1570 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1571 }
1572 break;
1573
1574 case GL_COLOR_MATERIAL:
1575 radeonColorMaterial( ctx, 0, 0 );
1576 radeonUpdateMaterial( ctx );
1577 break;
1578
1579 case GL_CULL_FACE:
1580 radeonCullFace( ctx, 0 );
1581 break;
1582
1583 case GL_DEPTH_TEST:
1584 RADEON_STATECHANGE(rmesa, ctx );
1585 if ( state ) {
1586 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE;
1587 } else {
1588 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1589 }
1590 break;
1591
1592 case GL_DITHER:
1593 RADEON_STATECHANGE(rmesa, ctx );
1594 if ( state ) {
1595 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE;
1596 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1597 } else {
1598 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1599 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable;
1600 }
1601 break;
1602
1603 case GL_FOG:
1604 RADEON_STATECHANGE(rmesa, ctx );
1605 if ( state ) {
1606 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1607 radeonFogfv( ctx, GL_FOG_MODE, NULL );
1608 } else {
1609 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1610 RADEON_STATECHANGE(rmesa, tcl);
1611 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1612 }
1613 radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1614 _mesa_allow_light_in_model( ctx, !state );
1615 break;
1616
1617 case GL_LIGHT0:
1618 case GL_LIGHT1:
1619 case GL_LIGHT2:
1620 case GL_LIGHT3:
1621 case GL_LIGHT4:
1622 case GL_LIGHT5:
1623 case GL_LIGHT6:
1624 case GL_LIGHT7:
1625 RADEON_STATECHANGE(rmesa, tcl);
1626 p = cap - GL_LIGHT0;
1627 if (p&1)
1628 flag = (RADEON_LIGHT_1_ENABLE |
1629 RADEON_LIGHT_1_ENABLE_AMBIENT |
1630 RADEON_LIGHT_1_ENABLE_SPECULAR);
1631 else
1632 flag = (RADEON_LIGHT_0_ENABLE |
1633 RADEON_LIGHT_0_ENABLE_AMBIENT |
1634 RADEON_LIGHT_0_ENABLE_SPECULAR);
1635
1636 if (state)
1637 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1638 else
1639 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1640
1641 /*
1642 */
1643 update_light_colors( ctx, p );
1644 break;
1645
1646 case GL_LIGHTING:
1647 RADEON_STATECHANGE(rmesa, tcl);
1648 radeonUpdateSpecular(ctx);
1649 check_twoside_fallback( ctx );
1650 break;
1651
1652 case GL_LINE_SMOOTH:
1653 RADEON_STATECHANGE( rmesa, ctx );
1654 if ( state ) {
1655 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE;
1656 } else {
1657 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1658 }
1659 break;
1660
1661 case GL_LINE_STIPPLE:
1662 RADEON_STATECHANGE( rmesa, ctx );
1663 if ( state ) {
1664 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE;
1665 } else {
1666 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1667 }
1668 break;
1669
1670 case GL_COLOR_LOGIC_OP:
1671 RADEON_STATECHANGE( rmesa, ctx );
1672 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1673 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1674 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1675 } else {
1676 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1677 }
1678 break;
1679
1680 case GL_NORMALIZE:
1681 RADEON_STATECHANGE( rmesa, tcl );
1682 if ( state ) {
1683 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS;
1684 } else {
1685 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1686 }
1687 break;
1688
1689 case GL_POLYGON_OFFSET_POINT:
1690 RADEON_STATECHANGE( rmesa, set );
1691 if ( state ) {
1692 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
1693 } else {
1694 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1695 }
1696 break;
1697
1698 case GL_POLYGON_OFFSET_LINE:
1699 RADEON_STATECHANGE( rmesa, set );
1700 if ( state ) {
1701 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
1702 } else {
1703 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1704 }
1705 break;
1706
1707 case GL_POLYGON_OFFSET_FILL:
1708 RADEON_STATECHANGE( rmesa, set );
1709 if ( state ) {
1710 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
1711 } else {
1712 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1713 }
1714 break;
1715
1716 case GL_POLYGON_SMOOTH:
1717 RADEON_STATECHANGE( rmesa, ctx );
1718 if ( state ) {
1719 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY;
1720 } else {
1721 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1722 }
1723 break;
1724
1725 case GL_POLYGON_STIPPLE:
1726 RADEON_STATECHANGE(rmesa, ctx );
1727 if ( state ) {
1728 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE;
1729 } else {
1730 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1731 }
1732 break;
1733
1734 case GL_RESCALE_NORMAL_EXT: {
1735 GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1736 RADEON_STATECHANGE( rmesa, tcl );
1737 if ( tmp ) {
1738 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1739 } else {
1740 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1741 }
1742 break;
1743 }
1744
1745 case GL_SCISSOR_TEST:
1746 radeon_firevertices(&rmesa->radeon);
1747 rmesa->radeon.state.scissor.enabled = state;
1748 radeonUpdateScissor( ctx );
1749 break;
1750
1751 case GL_STENCIL_TEST:
1752 {
1753 GLboolean hw_stencil = GL_FALSE;
1754 if (ctx->DrawBuffer) {
1755 struct radeon_renderbuffer *rrbStencil
1756 = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1757 hw_stencil = (rrbStencil && rrbStencil->bo);
1758 }
1759
1760 if (hw_stencil) {
1761 RADEON_STATECHANGE( rmesa, ctx );
1762 if ( state ) {
1763 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE;
1764 } else {
1765 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1766 }
1767 } else {
1768 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1769 }
1770 }
1771 break;
1772
1773 case GL_TEXTURE_GEN_Q:
1774 case GL_TEXTURE_GEN_R:
1775 case GL_TEXTURE_GEN_S:
1776 case GL_TEXTURE_GEN_T:
1777 /* Picked up in radeonUpdateTextureState.
1778 */
1779 rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1780 break;
1781
1782 case GL_COLOR_SUM_EXT:
1783 radeonUpdateSpecular ( ctx );
1784 break;
1785
1786 default:
1787 return;
1788 }
1789 }
1790
1791
1792 static void radeonLightingSpaceChange( struct gl_context *ctx )
1793 {
1794 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1795 GLboolean tmp;
1796 RADEON_STATECHANGE( rmesa, tcl );
1797
1798 if (RADEON_DEBUG & RADEON_STATE)
1799 fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1800 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1801
1802 if (ctx->_NeedEyeCoords)
1803 tmp = ctx->Transform.RescaleNormals;
1804 else
1805 tmp = !ctx->Transform.RescaleNormals;
1806
1807 if ( tmp ) {
1808 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1809 } else {
1810 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1811 }
1812
1813 if (RADEON_DEBUG & RADEON_STATE)
1814 fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1815 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1816 }
1817
1818 /* =============================================================
1819 * Deferred state management - matrices, textures, other?
1820 */
1821
1822
1823 void radeonUploadTexMatrix( r100ContextPtr rmesa,
1824 int unit, GLboolean swapcols )
1825 {
1826 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1827 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1828 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1829 texgen generates all 4 coords, at least tests with projtex indicated that.
1830 So: if we need the q coord in the end (solely determined by the texture
1831 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1832 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1833 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1834 will get submitted in the "wrong", i.e. 3rd, slot.
1835 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1836 size and using the texture matrix to swap the r and q coords around (ut2k3
1837 does exactly that), so we don't need the 3rd / 4th column swap - still need
1838 the 3rd / 4th row swap of course. This will potentially break for apps which
1839 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1840 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1841 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1842 incredibly hard to detect so we can't just fallback in such a case. Assume
1843 it never happens... - rs
1844 */
1845
1846 int idx = TEXMAT_0 + unit;
1847 float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1848 int i;
1849 struct gl_texture_unit tUnit = rmesa->radeon.glCtx.Texture.Unit[unit];
1850 GLfloat *src = rmesa->tmpmat[unit].m;
1851
1852 rmesa->TexMatColSwap &= ~(1 << unit);
1853 if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
1854 if (swapcols) {
1855 rmesa->TexMatColSwap |= 1 << unit;
1856 /* attention some elems are swapped 2 times! */
1857 *dest++ = src[0];
1858 *dest++ = src[4];
1859 *dest++ = src[12];
1860 *dest++ = src[8];
1861 *dest++ = src[1];
1862 *dest++ = src[5];
1863 *dest++ = src[13];
1864 *dest++ = src[9];
1865 *dest++ = src[2];
1866 *dest++ = src[6];
1867 *dest++ = src[15];
1868 *dest++ = src[11];
1869 /* those last 4 are probably never used */
1870 *dest++ = src[3];
1871 *dest++ = src[7];
1872 *dest++ = src[14];
1873 *dest++ = src[10];
1874 }
1875 else {
1876 for (i = 0; i < 2; i++) {
1877 *dest++ = src[i];
1878 *dest++ = src[i+4];
1879 *dest++ = src[i+8];
1880 *dest++ = src[i+12];
1881 }
1882 for (i = 3; i >= 2; i--) {
1883 *dest++ = src[i];
1884 *dest++ = src[i+4];
1885 *dest++ = src[i+8];
1886 *dest++ = src[i+12];
1887 }
1888 }
1889 }
1890 else {
1891 for (i = 0 ; i < 4 ; i++) {
1892 *dest++ = src[i];
1893 *dest++ = src[i+4];
1894 *dest++ = src[i+8];
1895 *dest++ = src[i+12];
1896 }
1897 }
1898
1899 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1900 }
1901
1902
1903 static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1904 {
1905 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1906 int i;
1907
1908
1909 for (i = 0 ; i < 4 ; i++) {
1910 *dest++ = src[i];
1911 *dest++ = src[i+4];
1912 *dest++ = src[i+8];
1913 *dest++ = src[i+12];
1914 }
1915
1916 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1917 }
1918
1919 static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1920 {
1921 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1922 memcpy(dest, src, 16*sizeof(float));
1923 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1924 }
1925
1926
1927 static void update_texturematrix( struct gl_context *ctx )
1928 {
1929 r100ContextPtr rmesa = R100_CONTEXT( ctx );
1930 GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
1931 GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
1932 int unit;
1933 GLuint texMatEnabled = 0;
1934 rmesa->NeedTexMatrix = 0;
1935 rmesa->TexMatColSwap = 0;
1936
1937 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
1938 if (ctx->Texture.Unit[unit]._ReallyEnabled) {
1939 GLboolean needMatrix = GL_FALSE;
1940 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
1941 needMatrix = GL_TRUE;
1942 texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
1943 RADEON_TEXMAT_0_ENABLE) << unit;
1944
1945 if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1946 /* Need to preconcatenate any active texgen
1947 * obj/eyeplane matrices:
1948 */
1949 _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
1950 ctx->TextureMatrixStack[unit].Top,
1951 &rmesa->TexGenMatrix[unit] );
1952 }
1953 else {
1954 _math_matrix_copy( &rmesa->tmpmat[unit],
1955 ctx->TextureMatrixStack[unit].Top );
1956 }
1957 }
1958 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1959 _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
1960 needMatrix = GL_TRUE;
1961 }
1962 if (needMatrix) {
1963 rmesa->NeedTexMatrix |= 1 << unit;
1964 radeonUploadTexMatrix( rmesa, unit,
1965 !ctx->Texture.Unit[unit].TexGenEnabled );
1966 }
1967 }
1968 }
1969
1970 tpc = (texMatEnabled | rmesa->TexGenEnabled);
1971
1972 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1973 vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
1974 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
1975 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
1976
1977 vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
1978 (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
1979 ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
1980 (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
1981 ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
1982 (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
1983
1984 if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
1985 vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
1986
1987 RADEON_STATECHANGE(rmesa, tcl);
1988 rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
1989 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
1990 }
1991 }
1992
1993 static GLboolean r100ValidateBuffers(struct gl_context *ctx)
1994 {
1995 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1996 struct radeon_renderbuffer *rrb;
1997 int i, ret;
1998
1999 radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2000
2001 rrb = radeon_get_colorbuffer(&rmesa->radeon);
2002 /* color buffer */
2003 if (rrb && rrb->bo) {
2004 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2005 0, RADEON_GEM_DOMAIN_VRAM);
2006 }
2007
2008 /* depth buffer */
2009 rrb = radeon_get_depthbuffer(&rmesa->radeon);
2010 /* color buffer */
2011 if (rrb && rrb->bo) {
2012 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2013 0, RADEON_GEM_DOMAIN_VRAM);
2014 }
2015
2016 for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; ++i) {
2017 radeonTexObj *t;
2018
2019 if (!ctx->Texture.Unit[i]._ReallyEnabled)
2020 continue;
2021
2022 t = rmesa->state.texture.unit[i].texobj;
2023
2024 if (!t)
2025 continue;
2026 if (t->image_override && t->bo)
2027 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2028 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2029 else if (t->mt->bo)
2030 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2031 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2032 }
2033
2034 ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
2035 if (ret)
2036 return GL_FALSE;
2037 return GL_TRUE;
2038 }
2039
2040 GLboolean radeonValidateState( struct gl_context *ctx )
2041 {
2042 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2043 GLuint new_state = rmesa->radeon.NewGLState;
2044
2045 if (new_state & _NEW_BUFFERS) {
2046 _mesa_update_framebuffer(ctx);
2047 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2048 _mesa_update_draw_buffer_bounds(ctx);
2049 RADEON_STATECHANGE(rmesa, ctx);
2050 }
2051
2052 if (new_state & _NEW_TEXTURE) {
2053 radeonUpdateTextureState( ctx );
2054 new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2055 }
2056
2057 /* we need to do a space check here */
2058 if (!r100ValidateBuffers(ctx))
2059 return GL_FALSE;
2060
2061 /* Need an event driven matrix update?
2062 */
2063 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2064 upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2065
2066 /* Need these for lighting (shouldn't upload otherwise)
2067 */
2068 if (new_state & (_NEW_MODELVIEW)) {
2069 upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2070 upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2071 }
2072
2073 /* Does this need to be triggered on eg. modelview for
2074 * texgen-derived objplane/eyeplane matrices?
2075 */
2076 if (new_state & _NEW_TEXTURE_MATRIX) {
2077 update_texturematrix( ctx );
2078 }
2079
2080 if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2081 update_light( ctx );
2082 }
2083
2084 /* emit all active clip planes if projection matrix changes.
2085 */
2086 if (new_state & (_NEW_PROJECTION)) {
2087 if (ctx->Transform.ClipPlanesEnabled)
2088 radeonUpdateClipPlanes( ctx );
2089 }
2090
2091
2092 rmesa->radeon.NewGLState = 0;
2093
2094 return GL_TRUE;
2095 }
2096
2097
2098 static void radeonInvalidateState( struct gl_context *ctx, GLuint new_state )
2099 {
2100 _swrast_InvalidateState( ctx, new_state );
2101 _swsetup_InvalidateState( ctx, new_state );
2102 _vbo_InvalidateState( ctx, new_state );
2103 _tnl_InvalidateState( ctx, new_state );
2104 _ae_invalidate_state( ctx, new_state );
2105 R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2106 }
2107
2108
2109 /* A hack. Need a faster way to find this out.
2110 */
2111 static GLboolean check_material( struct gl_context *ctx )
2112 {
2113 TNLcontext *tnl = TNL_CONTEXT(ctx);
2114 GLint i;
2115
2116 for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2117 i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2118 i++)
2119 if (tnl->vb.AttribPtr[i] &&
2120 tnl->vb.AttribPtr[i]->stride)
2121 return GL_TRUE;
2122
2123 return GL_FALSE;
2124 }
2125
2126
2127 static void radeonWrapRunPipeline( struct gl_context *ctx )
2128 {
2129 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2130 GLboolean has_material;
2131
2132 if (0)
2133 fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2134
2135 /* Validate state:
2136 */
2137 if (rmesa->radeon.NewGLState)
2138 if (!radeonValidateState( ctx ))
2139 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2140
2141 has_material = (ctx->Light.Enabled && check_material( ctx ));
2142
2143 if (has_material) {
2144 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2145 }
2146
2147 /* Run the pipeline.
2148 */
2149 _tnl_run_pipeline( ctx );
2150
2151 if (has_material) {
2152 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2153 }
2154 }
2155
2156 static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2157 {
2158 r100ContextPtr r100 = R100_CONTEXT(ctx);
2159 GLint i;
2160
2161 radeon_firevertices(&r100->radeon);
2162
2163 RADEON_STATECHANGE(r100, stp);
2164
2165 /* Must flip pattern upside down.
2166 */
2167 for ( i = 31 ; i >= 0; i--) {
2168 r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2169 }
2170 }
2171
2172
2173 /* Initialize the driver's state functions.
2174 * Many of the ctx->Driver functions might have been initialized to
2175 * software defaults in the earlier _mesa_init_driver_functions() call.
2176 */
2177 void radeonInitStateFuncs( struct gl_context *ctx )
2178 {
2179 ctx->Driver.UpdateState = radeonInvalidateState;
2180 ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
2181
2182 ctx->Driver.DrawBuffer = radeonDrawBuffer;
2183 ctx->Driver.ReadBuffer = radeonReadBuffer;
2184 ctx->Driver.CopyPixels = _mesa_meta_CopyPixels;
2185 ctx->Driver.DrawPixels = _mesa_meta_DrawPixels;
2186 ctx->Driver.ReadPixels = radeonReadPixels;
2187
2188 ctx->Driver.AlphaFunc = radeonAlphaFunc;
2189 ctx->Driver.BlendEquationSeparate = radeonBlendEquationSeparate;
2190 ctx->Driver.BlendFuncSeparate = radeonBlendFuncSeparate;
2191 ctx->Driver.ClipPlane = radeonClipPlane;
2192 ctx->Driver.ColorMask = radeonColorMask;
2193 ctx->Driver.CullFace = radeonCullFace;
2194 ctx->Driver.DepthFunc = radeonDepthFunc;
2195 ctx->Driver.DepthMask = radeonDepthMask;
2196 ctx->Driver.DepthRange = radeonDepthRange;
2197 ctx->Driver.Enable = radeonEnable;
2198 ctx->Driver.Fogfv = radeonFogfv;
2199 ctx->Driver.FrontFace = radeonFrontFace;
2200 ctx->Driver.Hint = NULL;
2201 ctx->Driver.LightModelfv = radeonLightModelfv;
2202 ctx->Driver.Lightfv = radeonLightfv;
2203 ctx->Driver.LineStipple = radeonLineStipple;
2204 ctx->Driver.LineWidth = radeonLineWidth;
2205 ctx->Driver.LogicOpcode = radeonLogicOpCode;
2206 ctx->Driver.PolygonMode = radeonPolygonMode;
2207 ctx->Driver.PolygonOffset = radeonPolygonOffset;
2208 ctx->Driver.PolygonStipple = radeonPolygonStipple;
2209 ctx->Driver.RenderMode = radeonRenderMode;
2210 ctx->Driver.Scissor = radeonScissor;
2211 ctx->Driver.ShadeModel = radeonShadeModel;
2212 ctx->Driver.StencilFuncSeparate = radeonStencilFuncSeparate;
2213 ctx->Driver.StencilMaskSeparate = radeonStencilMaskSeparate;
2214 ctx->Driver.StencilOpSeparate = radeonStencilOpSeparate;
2215 ctx->Driver.Viewport = radeonViewport;
2216
2217 TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2218 TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2219 }