mesa: move max texture image unit constants to gl_program_constants
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_state.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/fbobject.h"
43 #include "main/simple_list.h"
44 #include "main/state.h"
45
46 #include "vbo/vbo.h"
47 #include "tnl/tnl.h"
48 #include "tnl/t_pipeline.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "drivers/common/meta.h"
51
52 #include "radeon_context.h"
53 #include "radeon_mipmap_tree.h"
54 #include "radeon_ioctl.h"
55 #include "radeon_state.h"
56 #include "radeon_tcl.h"
57 #include "radeon_tex.h"
58 #include "radeon_swtcl.h"
59
60 static void radeonUpdateSpecular( struct gl_context *ctx );
61
62 /* =============================================================
63 * Alpha blending
64 */
65
66 static void radeonAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
67 {
68 r100ContextPtr rmesa = R100_CONTEXT(ctx);
69 int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC];
70 GLubyte refByte;
71
72 CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
73
74 RADEON_STATECHANGE( rmesa, ctx );
75
76 pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK);
77 pp_misc |= (refByte & RADEON_REF_ALPHA_MASK);
78
79 switch ( func ) {
80 case GL_NEVER:
81 pp_misc |= RADEON_ALPHA_TEST_FAIL;
82 break;
83 case GL_LESS:
84 pp_misc |= RADEON_ALPHA_TEST_LESS;
85 break;
86 case GL_EQUAL:
87 pp_misc |= RADEON_ALPHA_TEST_EQUAL;
88 break;
89 case GL_LEQUAL:
90 pp_misc |= RADEON_ALPHA_TEST_LEQUAL;
91 break;
92 case GL_GREATER:
93 pp_misc |= RADEON_ALPHA_TEST_GREATER;
94 break;
95 case GL_NOTEQUAL:
96 pp_misc |= RADEON_ALPHA_TEST_NEQUAL;
97 break;
98 case GL_GEQUAL:
99 pp_misc |= RADEON_ALPHA_TEST_GEQUAL;
100 break;
101 case GL_ALWAYS:
102 pp_misc |= RADEON_ALPHA_TEST_PASS;
103 break;
104 }
105
106 rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
107 }
108
109 static void radeonBlendEquationSeparate( struct gl_context *ctx,
110 GLenum modeRGB, GLenum modeA )
111 {
112 r100ContextPtr rmesa = R100_CONTEXT(ctx);
113 GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK;
114 GLboolean fallback = GL_FALSE;
115
116 assert( modeRGB == modeA );
117
118 switch ( modeRGB ) {
119 case GL_FUNC_ADD:
120 case GL_LOGIC_OP:
121 b |= RADEON_COMB_FCN_ADD_CLAMP;
122 break;
123
124 case GL_FUNC_SUBTRACT:
125 b |= RADEON_COMB_FCN_SUB_CLAMP;
126 break;
127
128 default:
129 if (ctx->Color.BlendEnabled)
130 fallback = GL_TRUE;
131 else
132 b |= RADEON_COMB_FCN_ADD_CLAMP;
133 break;
134 }
135
136 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, fallback );
137 if ( !fallback ) {
138 RADEON_STATECHANGE( rmesa, ctx );
139 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
140 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
141 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
142 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
143 } else {
144 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
145 }
146 }
147 }
148
149 static void radeonBlendFuncSeparate( struct gl_context *ctx,
150 GLenum sfactorRGB, GLenum dfactorRGB,
151 GLenum sfactorA, GLenum dfactorA )
152 {
153 r100ContextPtr rmesa = R100_CONTEXT(ctx);
154 GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] &
155 ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
156 GLboolean fallback = GL_FALSE;
157
158 switch ( ctx->Color.Blend[0].SrcRGB ) {
159 case GL_ZERO:
160 b |= RADEON_SRC_BLEND_GL_ZERO;
161 break;
162 case GL_ONE:
163 b |= RADEON_SRC_BLEND_GL_ONE;
164 break;
165 case GL_DST_COLOR:
166 b |= RADEON_SRC_BLEND_GL_DST_COLOR;
167 break;
168 case GL_ONE_MINUS_DST_COLOR:
169 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
170 break;
171 case GL_SRC_COLOR:
172 b |= RADEON_SRC_BLEND_GL_SRC_COLOR;
173 break;
174 case GL_ONE_MINUS_SRC_COLOR:
175 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR;
176 break;
177 case GL_SRC_ALPHA:
178 b |= RADEON_SRC_BLEND_GL_SRC_ALPHA;
179 break;
180 case GL_ONE_MINUS_SRC_ALPHA:
181 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
182 break;
183 case GL_DST_ALPHA:
184 b |= RADEON_SRC_BLEND_GL_DST_ALPHA;
185 break;
186 case GL_ONE_MINUS_DST_ALPHA:
187 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
188 break;
189 case GL_SRC_ALPHA_SATURATE:
190 b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
191 break;
192 case GL_CONSTANT_COLOR:
193 case GL_ONE_MINUS_CONSTANT_COLOR:
194 case GL_CONSTANT_ALPHA:
195 case GL_ONE_MINUS_CONSTANT_ALPHA:
196 if (ctx->Color.BlendEnabled)
197 fallback = GL_TRUE;
198 else
199 b |= RADEON_SRC_BLEND_GL_ONE;
200 break;
201 default:
202 break;
203 }
204
205 switch ( ctx->Color.Blend[0].DstRGB ) {
206 case GL_ZERO:
207 b |= RADEON_DST_BLEND_GL_ZERO;
208 break;
209 case GL_ONE:
210 b |= RADEON_DST_BLEND_GL_ONE;
211 break;
212 case GL_SRC_COLOR:
213 b |= RADEON_DST_BLEND_GL_SRC_COLOR;
214 break;
215 case GL_ONE_MINUS_SRC_COLOR:
216 b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR;
217 break;
218 case GL_SRC_ALPHA:
219 b |= RADEON_DST_BLEND_GL_SRC_ALPHA;
220 break;
221 case GL_ONE_MINUS_SRC_ALPHA:
222 b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
223 break;
224 case GL_DST_COLOR:
225 b |= RADEON_DST_BLEND_GL_DST_COLOR;
226 break;
227 case GL_ONE_MINUS_DST_COLOR:
228 b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR;
229 break;
230 case GL_DST_ALPHA:
231 b |= RADEON_DST_BLEND_GL_DST_ALPHA;
232 break;
233 case GL_ONE_MINUS_DST_ALPHA:
234 b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA;
235 break;
236 case GL_CONSTANT_COLOR:
237 case GL_ONE_MINUS_CONSTANT_COLOR:
238 case GL_CONSTANT_ALPHA:
239 case GL_ONE_MINUS_CONSTANT_ALPHA:
240 if (ctx->Color.BlendEnabled)
241 fallback = GL_TRUE;
242 else
243 b |= RADEON_DST_BLEND_GL_ZERO;
244 break;
245 default:
246 break;
247 }
248
249 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback );
250 if ( !fallback ) {
251 RADEON_STATECHANGE( rmesa, ctx );
252 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
253 }
254 }
255
256
257 /* =============================================================
258 * Depth testing
259 */
260
261 static void radeonDepthFunc( struct gl_context *ctx, GLenum func )
262 {
263 r100ContextPtr rmesa = R100_CONTEXT(ctx);
264
265 RADEON_STATECHANGE( rmesa, ctx );
266 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK;
267
268 switch ( ctx->Depth.Func ) {
269 case GL_NEVER:
270 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEVER;
271 break;
272 case GL_LESS:
273 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LESS;
274 break;
275 case GL_EQUAL:
276 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_EQUAL;
277 break;
278 case GL_LEQUAL:
279 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LEQUAL;
280 break;
281 case GL_GREATER:
282 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GREATER;
283 break;
284 case GL_NOTEQUAL:
285 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEQUAL;
286 break;
287 case GL_GEQUAL:
288 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GEQUAL;
289 break;
290 case GL_ALWAYS:
291 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_ALWAYS;
292 break;
293 }
294 }
295
296
297 static void radeonDepthMask( struct gl_context *ctx, GLboolean flag )
298 {
299 r100ContextPtr rmesa = R100_CONTEXT(ctx);
300 RADEON_STATECHANGE( rmesa, ctx );
301
302 if ( ctx->Depth.Mask ) {
303 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_WRITE_ENABLE;
304 } else {
305 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_WRITE_ENABLE;
306 }
307 }
308
309
310 /* =============================================================
311 * Fog
312 */
313
314
315 static void radeonFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
316 {
317 r100ContextPtr rmesa = R100_CONTEXT(ctx);
318 union { int i; float f; } c, d;
319 GLubyte col[4];
320
321 switch (pname) {
322 case GL_FOG_MODE:
323 if (!ctx->Fog.Enabled)
324 return;
325 RADEON_STATECHANGE(rmesa, tcl);
326 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
327 switch (ctx->Fog.Mode) {
328 case GL_LINEAR:
329 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
330 break;
331 case GL_EXP:
332 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
333 break;
334 case GL_EXP2:
335 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
336 break;
337 default:
338 return;
339 }
340 /* fallthrough */
341 case GL_FOG_DENSITY:
342 case GL_FOG_START:
343 case GL_FOG_END:
344 if (!ctx->Fog.Enabled)
345 return;
346 c.i = rmesa->hw.fog.cmd[FOG_C];
347 d.i = rmesa->hw.fog.cmd[FOG_D];
348 switch (ctx->Fog.Mode) {
349 case GL_EXP:
350 c.f = 0.0;
351 /* While this is the opposite sign from the DDK, it makes the fog test
352 * pass, and matches r200.
353 */
354 d.f = -ctx->Fog.Density;
355 break;
356 case GL_EXP2:
357 c.f = 0.0;
358 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
359 break;
360 case GL_LINEAR:
361 if (ctx->Fog.Start == ctx->Fog.End) {
362 c.f = 1.0F;
363 d.f = 1.0F;
364 } else {
365 c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
366 /* While this is the opposite sign from the DDK, it makes the fog
367 * test pass, and matches r200.
368 */
369 d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
370 }
371 break;
372 default:
373 break;
374 }
375 if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
376 RADEON_STATECHANGE( rmesa, fog );
377 rmesa->hw.fog.cmd[FOG_C] = c.i;
378 rmesa->hw.fog.cmd[FOG_D] = d.i;
379 }
380 break;
381 case GL_FOG_COLOR:
382 RADEON_STATECHANGE( rmesa, ctx );
383 _mesa_unclamped_float_rgba_to_ubyte(col, ctx->Fog.Color );
384 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
385 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
386 radeonPackColor( 4, col[0], col[1], col[2], 0 );
387 break;
388 case GL_FOG_COORD_SRC:
389 radeonUpdateSpecular( ctx );
390 break;
391 default:
392 return;
393 }
394 }
395
396 /* =============================================================
397 * Culling
398 */
399
400 static void radeonCullFace( struct gl_context *ctx, GLenum unused )
401 {
402 r100ContextPtr rmesa = R100_CONTEXT(ctx);
403 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
404 GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
405
406 s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;
407 t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK);
408
409 if ( ctx->Polygon.CullFlag ) {
410 switch ( ctx->Polygon.CullFaceMode ) {
411 case GL_FRONT:
412 s &= ~RADEON_FFACE_SOLID;
413 t |= RADEON_CULL_FRONT;
414 break;
415 case GL_BACK:
416 s &= ~RADEON_BFACE_SOLID;
417 t |= RADEON_CULL_BACK;
418 break;
419 case GL_FRONT_AND_BACK:
420 s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);
421 t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK);
422 break;
423 }
424 }
425
426 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
427 RADEON_STATECHANGE(rmesa, set );
428 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
429 }
430
431 if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
432 RADEON_STATECHANGE(rmesa, tcl );
433 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
434 }
435 }
436
437 static void radeonFrontFace( struct gl_context *ctx, GLenum mode )
438 {
439 r100ContextPtr rmesa = R100_CONTEXT(ctx);
440 int cull_face = (mode == GL_CW) ? RADEON_FFACE_CULL_CW : RADEON_FFACE_CULL_CCW;
441
442 RADEON_STATECHANGE( rmesa, set );
443 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK;
444
445 RADEON_STATECHANGE( rmesa, tcl );
446 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;
447
448 /* Winding is inverted when rendering to FBO */
449 if (ctx->DrawBuffer && _mesa_is_user_fbo(ctx->DrawBuffer))
450 cull_face = (mode == GL_CCW) ? RADEON_FFACE_CULL_CW : RADEON_FFACE_CULL_CCW;
451 rmesa->hw.set.cmd[SET_SE_CNTL] |= cull_face;
452
453 if ( mode == GL_CCW )
454 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW;
455 }
456
457
458 /* =============================================================
459 * Line state
460 */
461 static void radeonLineWidth( struct gl_context *ctx, GLfloat widthf )
462 {
463 r100ContextPtr rmesa = R100_CONTEXT(ctx);
464
465 RADEON_STATECHANGE( rmesa, lin );
466 RADEON_STATECHANGE( rmesa, set );
467
468 /* Line width is stored in U6.4 format.
469 */
470 rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0);
471 if ( widthf > 1.0 ) {
472 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_WIDELINE_ENABLE;
473 } else {
474 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE;
475 }
476 }
477
478 static void radeonLineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
479 {
480 r100ContextPtr rmesa = R100_CONTEXT(ctx);
481
482 RADEON_STATECHANGE( rmesa, lin );
483 rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
484 ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
485 }
486
487
488 /* =============================================================
489 * Masks
490 */
491 static void radeonColorMask( struct gl_context *ctx,
492 GLboolean r, GLboolean g,
493 GLboolean b, GLboolean a )
494 {
495 r100ContextPtr rmesa = R100_CONTEXT(ctx);
496 struct radeon_renderbuffer *rrb;
497 GLuint mask;
498
499 rrb = radeon_get_colorbuffer(&rmesa->radeon);
500 if (!rrb)
501 return;
502
503 mask = radeonPackColor( rrb->cpp,
504 ctx->Color.ColorMask[0][RCOMP],
505 ctx->Color.ColorMask[0][GCOMP],
506 ctx->Color.ColorMask[0][BCOMP],
507 ctx->Color.ColorMask[0][ACOMP] );
508
509 if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
510 RADEON_STATECHANGE( rmesa, msk );
511 rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
512 }
513 }
514
515
516 /* =============================================================
517 * Polygon state
518 */
519
520 static void radeonPolygonOffset( struct gl_context *ctx,
521 GLfloat factor, GLfloat units )
522 {
523 r100ContextPtr rmesa = R100_CONTEXT(ctx);
524 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
525 float_ui32_type constant = { units * depthScale };
526 float_ui32_type factoru = { factor };
527
528 RADEON_STATECHANGE( rmesa, zbs );
529 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = factoru.ui32;
530 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
531 }
532
533 static void radeonPolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
534 {
535 r100ContextPtr rmesa = R100_CONTEXT(ctx);
536 GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
537 ctx->Polygon.BackMode != GL_FILL);
538
539 /* Can't generally do unfilled via tcl, but some good special
540 * cases work.
541 */
542 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, unfilled);
543 if (rmesa->radeon.TclFallback) {
544 radeonChooseRenderState( ctx );
545 radeonChooseVertexState( ctx );
546 }
547 }
548
549
550 /* =============================================================
551 * Rendering attributes
552 *
553 * We really don't want to recalculate all this every time we bind a
554 * texture. These things shouldn't change all that often, so it makes
555 * sense to break them out of the core texture state update routines.
556 */
557
558 /* Examine lighting and texture state to determine if separate specular
559 * should be enabled.
560 */
561 static void radeonUpdateSpecular( struct gl_context *ctx )
562 {
563 r100ContextPtr rmesa = R100_CONTEXT(ctx);
564 uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
565 GLuint flag = 0;
566
567 RADEON_STATECHANGE( rmesa, tcl );
568
569 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
570 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
571 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
572 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE;
573 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
574
575 p &= ~RADEON_SPECULAR_ENABLE;
576
577 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE;
578
579
580 if (ctx->Light.Enabled &&
581 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
582 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
583 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
584 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
585 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
586 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
587 p |= RADEON_SPECULAR_ENABLE;
588 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
589 ~RADEON_DIFFUSE_SPECULAR_COMBINE;
590 }
591 else if (ctx->Light.Enabled) {
592 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
593 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
594 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
595 } else if (ctx->Fog.ColorSumEnabled ) {
596 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
597 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
598 p |= RADEON_SPECULAR_ENABLE;
599 } else {
600 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
601 }
602
603 if (ctx->Fog.Enabled) {
604 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
605 if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
606 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
607 /* Bizzare: have to leave lighting enabled to get fog. */
608 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
609 }
610 else {
611 /* cannot do tcl fog factor calculation with fog coord source
612 * (send precomputed factors). Cannot use precomputed fog
613 * factors together with tcl spec light (need tcl fallback) */
614 flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
615 RADEON_TCL_COMPUTE_SPECULAR) != 0;
616 }
617 }
618
619 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
620
621 if (_mesa_need_secondary_color(ctx)) {
622 assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
623 } else {
624 assert( (p & RADEON_SPECULAR_ENABLE) == 0 );
625 }
626
627 if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
628 RADEON_STATECHANGE( rmesa, ctx );
629 rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
630 }
631
632 /* Update vertex/render formats
633 */
634 if (rmesa->radeon.TclFallback) {
635 radeonChooseRenderState( ctx );
636 radeonChooseVertexState( ctx );
637 }
638 }
639
640
641 /* =============================================================
642 * Materials
643 */
644
645
646 /* Update on colormaterial, material emmissive/ambient,
647 * lightmodel.globalambient
648 */
649 static void update_global_ambient( struct gl_context *ctx )
650 {
651 r100ContextPtr rmesa = R100_CONTEXT(ctx);
652 float *fcmd = (float *)RADEON_DB_STATE( glt );
653
654 /* Need to do more if both emmissive & ambient are PREMULT:
655 * Hope this is not needed for MULT
656 */
657 if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
658 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
659 (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
660 {
661 COPY_3V( &fcmd[GLT_RED],
662 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
663 ACC_SCALE_3V( &fcmd[GLT_RED],
664 ctx->Light.Model.Ambient,
665 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
666 }
667 else
668 {
669 COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
670 }
671
672 RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
673 }
674
675 /* Update on change to
676 * - light[p].colors
677 * - light[p].enabled
678 */
679 static void update_light_colors( struct gl_context *ctx, GLuint p )
680 {
681 struct gl_light *l = &ctx->Light.Light[p];
682
683 /* fprintf(stderr, "%s\n", __FUNCTION__); */
684
685 if (l->Enabled) {
686 r100ContextPtr rmesa = R100_CONTEXT(ctx);
687 float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
688
689 COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
690 COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
691 COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
692
693 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
694 }
695 }
696
697 /* Also fallback for asym colormaterial mode in twoside lighting...
698 */
699 static void check_twoside_fallback( struct gl_context *ctx )
700 {
701 GLboolean fallback = GL_FALSE;
702 GLint i;
703
704 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
705 if (ctx->Light.ColorMaterialEnabled &&
706 (ctx->Light._ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
707 ((ctx->Light._ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
708 fallback = GL_TRUE;
709 else {
710 for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
711 if (memcmp( ctx->Light.Material.Attrib[i],
712 ctx->Light.Material.Attrib[i+1],
713 sizeof(GLfloat)*4) != 0) {
714 fallback = GL_TRUE;
715 break;
716 }
717 }
718 }
719
720 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
721 }
722
723
724 static void radeonColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
725 {
726 r100ContextPtr rmesa = R100_CONTEXT(ctx);
727 GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
728
729 light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
730 (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
731 (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
732 (3 << RADEON_SPECULAR_SOURCE_SHIFT));
733
734 if (ctx->Light.ColorMaterialEnabled) {
735 GLuint mask = ctx->Light._ColorMaterialBitmask;
736
737 if (mask & MAT_BIT_FRONT_EMISSION) {
738 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
739 RADEON_EMISSIVE_SOURCE_SHIFT);
740 }
741 else {
742 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
743 RADEON_EMISSIVE_SOURCE_SHIFT);
744 }
745
746 if (mask & MAT_BIT_FRONT_AMBIENT) {
747 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
748 RADEON_AMBIENT_SOURCE_SHIFT);
749 }
750 else {
751 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
752 RADEON_AMBIENT_SOURCE_SHIFT);
753 }
754
755 if (mask & MAT_BIT_FRONT_DIFFUSE) {
756 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
757 RADEON_DIFFUSE_SOURCE_SHIFT);
758 }
759 else {
760 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
761 RADEON_DIFFUSE_SOURCE_SHIFT);
762 }
763
764 if (mask & MAT_BIT_FRONT_SPECULAR) {
765 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
766 RADEON_SPECULAR_SOURCE_SHIFT);
767 }
768 else {
769 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
770 RADEON_SPECULAR_SOURCE_SHIFT);
771 }
772 }
773 else {
774 /* Default to MULT:
775 */
776 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
777 (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
778 (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
779 (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
780 }
781
782 if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
783 RADEON_STATECHANGE( rmesa, tcl );
784 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
785 }
786 }
787
788 void radeonUpdateMaterial( struct gl_context *ctx )
789 {
790 r100ContextPtr rmesa = R100_CONTEXT(ctx);
791 GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
792 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
793 GLuint mask = ~0;
794
795 if (ctx->Light.ColorMaterialEnabled)
796 mask &= ~ctx->Light._ColorMaterialBitmask;
797
798 if (RADEON_DEBUG & RADEON_STATE)
799 fprintf(stderr, "%s\n", __FUNCTION__);
800
801
802 if (mask & MAT_BIT_FRONT_EMISSION) {
803 fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0];
804 fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
805 fcmd[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_FRONT_EMISSION][2];
806 fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
807 }
808 if (mask & MAT_BIT_FRONT_AMBIENT) {
809 fcmd[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
810 fcmd[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
811 fcmd[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
812 fcmd[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
813 }
814 if (mask & MAT_BIT_FRONT_DIFFUSE) {
815 fcmd[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
816 fcmd[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
817 fcmd[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
818 fcmd[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
819 }
820 if (mask & MAT_BIT_FRONT_SPECULAR) {
821 fcmd[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
822 fcmd[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
823 fcmd[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
824 fcmd[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
825 }
826 if (mask & MAT_BIT_FRONT_SHININESS) {
827 fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0];
828 }
829
830 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl );
831
832 check_twoside_fallback( ctx );
833 /* update_global_ambient( ctx );*/
834 }
835
836 /* _NEW_LIGHT
837 * _NEW_MODELVIEW
838 * _MESA_NEW_NEED_EYE_COORDS
839 *
840 * Uses derived state from mesa:
841 * _VP_inf_norm
842 * _h_inf_norm
843 * _Position
844 * _NormSpotDirection
845 * _ModelViewInvScale
846 * _NeedEyeCoords
847 * _EyeZDir
848 *
849 * which are calculated in light.c and are correct for the current
850 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
851 * and _MESA_NEW_NEED_EYE_COORDS.
852 */
853 static void update_light( struct gl_context *ctx )
854 {
855 r100ContextPtr rmesa = R100_CONTEXT(ctx);
856
857 /* Have to check these, or have an automatic shortcircuit mechanism
858 * to remove noop statechanges. (Or just do a better job on the
859 * front end).
860 */
861 {
862 GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
863
864 if (ctx->_NeedEyeCoords)
865 tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
866 else
867 tmp |= RADEON_LIGHT_IN_MODELSPACE;
868
869
870 /* Leave this test disabled: (unexplained q3 lockup) (even with
871 new packets)
872 */
873 if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
874 {
875 RADEON_STATECHANGE( rmesa, tcl );
876 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
877 }
878 }
879
880 {
881 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
882 fcmd[EYE_X] = ctx->_EyeZDir[0];
883 fcmd[EYE_Y] = ctx->_EyeZDir[1];
884 fcmd[EYE_Z] = - ctx->_EyeZDir[2];
885 fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
886 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
887 }
888
889
890
891 if (ctx->Light.Enabled) {
892 GLint p;
893 for (p = 0 ; p < MAX_LIGHTS; p++) {
894 if (ctx->Light.Light[p].Enabled) {
895 struct gl_light *l = &ctx->Light.Light[p];
896 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
897
898 if (l->EyePosition[3] == 0.0) {
899 COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
900 COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
901 fcmd[LIT_POSITION_W] = 0;
902 fcmd[LIT_DIRECTION_W] = 0;
903 } else {
904 COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
905 fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
906 fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
907 fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
908 fcmd[LIT_DIRECTION_W] = 0;
909 }
910
911 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
912 }
913 }
914 }
915 }
916
917 static void radeonLightfv( struct gl_context *ctx, GLenum light,
918 GLenum pname, const GLfloat *params )
919 {
920 r100ContextPtr rmesa = R100_CONTEXT(ctx);
921 GLint p = light - GL_LIGHT0;
922 struct gl_light *l = &ctx->Light.Light[p];
923 GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
924
925
926 switch (pname) {
927 case GL_AMBIENT:
928 case GL_DIFFUSE:
929 case GL_SPECULAR:
930 update_light_colors( ctx, p );
931 break;
932
933 case GL_SPOT_DIRECTION:
934 /* picked up in update_light */
935 break;
936
937 case GL_POSITION: {
938 /* positions picked up in update_light, but can do flag here */
939 GLuint flag;
940 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
941
942 /* FIXME: Set RANGE_ATTEN only when needed */
943 if (p&1)
944 flag = RADEON_LIGHT_1_IS_LOCAL;
945 else
946 flag = RADEON_LIGHT_0_IS_LOCAL;
947
948 RADEON_STATECHANGE(rmesa, tcl);
949 if (l->EyePosition[3] != 0.0F)
950 rmesa->hw.tcl.cmd[idx] |= flag;
951 else
952 rmesa->hw.tcl.cmd[idx] &= ~flag;
953 break;
954 }
955
956 case GL_SPOT_EXPONENT:
957 RADEON_STATECHANGE(rmesa, lit[p]);
958 fcmd[LIT_SPOT_EXPONENT] = params[0];
959 break;
960
961 case GL_SPOT_CUTOFF: {
962 GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
963 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
964
965 RADEON_STATECHANGE(rmesa, lit[p]);
966 fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
967
968 RADEON_STATECHANGE(rmesa, tcl);
969 if (l->SpotCutoff != 180.0F)
970 rmesa->hw.tcl.cmd[idx] |= flag;
971 else
972 rmesa->hw.tcl.cmd[idx] &= ~flag;
973
974 break;
975 }
976
977 case GL_CONSTANT_ATTENUATION:
978 RADEON_STATECHANGE(rmesa, lit[p]);
979 fcmd[LIT_ATTEN_CONST] = params[0];
980 if ( params[0] == 0.0 )
981 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
982 else
983 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
984 break;
985 case GL_LINEAR_ATTENUATION:
986 RADEON_STATECHANGE(rmesa, lit[p]);
987 fcmd[LIT_ATTEN_LINEAR] = params[0];
988 break;
989 case GL_QUADRATIC_ATTENUATION:
990 RADEON_STATECHANGE(rmesa, lit[p]);
991 fcmd[LIT_ATTEN_QUADRATIC] = params[0];
992 break;
993 default:
994 return;
995 }
996
997 /* Set RANGE_ATTEN only when needed */
998 switch (pname) {
999 case GL_POSITION:
1000 case GL_CONSTANT_ATTENUATION:
1001 case GL_LINEAR_ATTENUATION:
1002 case GL_QUADRATIC_ATTENUATION:
1003 {
1004 GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
1005 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1006 GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1007 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
1008 GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1009 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
1010
1011 if ( l->EyePosition[3] == 0.0F ||
1012 ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1013 fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1014 /* Disable attenuation */
1015 icmd[idx] &= ~atten_flag;
1016 } else {
1017 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1018 /* Enable only constant portion of attenuation calculation */
1019 icmd[idx] |= ( atten_flag | atten_const_flag );
1020 } else {
1021 /* Enable full attenuation calculation */
1022 icmd[idx] &= ~atten_const_flag;
1023 icmd[idx] |= atten_flag;
1024 }
1025 }
1026
1027 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1028 break;
1029 }
1030 default:
1031 break;
1032 }
1033 }
1034
1035
1036
1037
1038 static void radeonLightModelfv( struct gl_context *ctx, GLenum pname,
1039 const GLfloat *param )
1040 {
1041 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1042
1043 switch (pname) {
1044 case GL_LIGHT_MODEL_AMBIENT:
1045 update_global_ambient( ctx );
1046 break;
1047
1048 case GL_LIGHT_MODEL_LOCAL_VIEWER:
1049 RADEON_STATECHANGE( rmesa, tcl );
1050 if (ctx->Light.Model.LocalViewer)
1051 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
1052 else
1053 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
1054 break;
1055
1056 case GL_LIGHT_MODEL_TWO_SIDE:
1057 RADEON_STATECHANGE( rmesa, tcl );
1058 if (ctx->Light.Model.TwoSide)
1059 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
1060 else
1061 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
1062
1063 check_twoside_fallback( ctx );
1064
1065 if (rmesa->radeon.TclFallback) {
1066 radeonChooseRenderState( ctx );
1067 radeonChooseVertexState( ctx );
1068 }
1069 break;
1070
1071 case GL_LIGHT_MODEL_COLOR_CONTROL:
1072 radeonUpdateSpecular(ctx);
1073 break;
1074
1075 default:
1076 break;
1077 }
1078 }
1079
1080 static void radeonShadeModel( struct gl_context *ctx, GLenum mode )
1081 {
1082 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1083 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1084
1085 s &= ~(RADEON_DIFFUSE_SHADE_MASK |
1086 RADEON_ALPHA_SHADE_MASK |
1087 RADEON_SPECULAR_SHADE_MASK |
1088 RADEON_FOG_SHADE_MASK);
1089
1090 switch ( mode ) {
1091 case GL_FLAT:
1092 s |= (RADEON_DIFFUSE_SHADE_FLAT |
1093 RADEON_ALPHA_SHADE_FLAT |
1094 RADEON_SPECULAR_SHADE_FLAT |
1095 RADEON_FOG_SHADE_FLAT);
1096 break;
1097 case GL_SMOOTH:
1098 s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
1099 RADEON_ALPHA_SHADE_GOURAUD |
1100 RADEON_SPECULAR_SHADE_GOURAUD |
1101 RADEON_FOG_SHADE_GOURAUD);
1102 break;
1103 default:
1104 return;
1105 }
1106
1107 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1108 RADEON_STATECHANGE( rmesa, set );
1109 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1110 }
1111 }
1112
1113
1114 /* =============================================================
1115 * User clip planes
1116 */
1117
1118 static void radeonClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1119 {
1120 GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1121 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1122 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1123
1124 RADEON_STATECHANGE( rmesa, ucp[p] );
1125 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1126 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1127 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1128 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1129 }
1130
1131 static void radeonUpdateClipPlanes( struct gl_context *ctx )
1132 {
1133 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1134 GLuint p;
1135
1136 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1137 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1138 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1139
1140 RADEON_STATECHANGE( rmesa, ucp[p] );
1141 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1142 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1143 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1144 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1145 }
1146 }
1147 }
1148
1149
1150 /* =============================================================
1151 * Stencil
1152 */
1153
1154 static void
1155 radeonStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1156 GLint ref, GLuint mask )
1157 {
1158 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1159 GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) |
1160 ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
1161
1162 RADEON_STATECHANGE( rmesa, ctx );
1163 RADEON_STATECHANGE( rmesa, msk );
1164
1165 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
1166 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
1167 RADEON_STENCIL_VALUE_MASK);
1168
1169 switch ( ctx->Stencil.Function[0] ) {
1170 case GL_NEVER:
1171 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
1172 break;
1173 case GL_LESS:
1174 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
1175 break;
1176 case GL_EQUAL:
1177 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
1178 break;
1179 case GL_LEQUAL:
1180 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
1181 break;
1182 case GL_GREATER:
1183 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
1184 break;
1185 case GL_NOTEQUAL:
1186 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
1187 break;
1188 case GL_GEQUAL:
1189 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
1190 break;
1191 case GL_ALWAYS:
1192 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
1193 break;
1194 }
1195
1196 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1197 }
1198
1199 static void
1200 radeonStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1201 {
1202 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1203
1204 RADEON_STATECHANGE( rmesa, msk );
1205 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
1206 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1207 ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
1208 }
1209
1210 static void radeonStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1211 GLenum zfail, GLenum zpass )
1212 {
1213 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1214
1215 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1216 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1217 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1218
1219 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
1220 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
1221 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1222 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1223 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1224 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
1225
1226 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
1227 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
1228 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
1229 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
1230 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
1231 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
1232 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
1233 }
1234 else {
1235 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
1236 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
1237 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
1238 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
1239 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
1240 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
1241 }
1242
1243 RADEON_STATECHANGE( rmesa, ctx );
1244 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1245 RADEON_STENCIL_ZFAIL_MASK |
1246 RADEON_STENCIL_ZPASS_MASK);
1247
1248 switch ( ctx->Stencil.FailFunc[0] ) {
1249 case GL_KEEP:
1250 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1251 break;
1252 case GL_ZERO:
1253 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1254 break;
1255 case GL_REPLACE:
1256 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1257 break;
1258 case GL_INCR:
1259 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1260 break;
1261 case GL_DECR:
1262 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1263 break;
1264 case GL_INCR_WRAP:
1265 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
1266 break;
1267 case GL_DECR_WRAP:
1268 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
1269 break;
1270 case GL_INVERT:
1271 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1272 break;
1273 }
1274
1275 switch ( ctx->Stencil.ZFailFunc[0] ) {
1276 case GL_KEEP:
1277 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1278 break;
1279 case GL_ZERO:
1280 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1281 break;
1282 case GL_REPLACE:
1283 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1284 break;
1285 case GL_INCR:
1286 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1287 break;
1288 case GL_DECR:
1289 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1290 break;
1291 case GL_INCR_WRAP:
1292 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1293 break;
1294 case GL_DECR_WRAP:
1295 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1296 break;
1297 case GL_INVERT:
1298 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1299 break;
1300 }
1301
1302 switch ( ctx->Stencil.ZPassFunc[0] ) {
1303 case GL_KEEP:
1304 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1305 break;
1306 case GL_ZERO:
1307 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1308 break;
1309 case GL_REPLACE:
1310 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1311 break;
1312 case GL_INCR:
1313 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1314 break;
1315 case GL_DECR:
1316 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1317 break;
1318 case GL_INCR_WRAP:
1319 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
1320 break;
1321 case GL_DECR_WRAP:
1322 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1323 break;
1324 case GL_INVERT:
1325 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1326 break;
1327 }
1328 }
1329
1330
1331
1332 /* =============================================================
1333 * Window position and viewport transformation
1334 */
1335
1336 /*
1337 * To correctly position primitives:
1338 */
1339 #define SUBPIXEL_X 0.125
1340 #define SUBPIXEL_Y 0.125
1341
1342
1343 /**
1344 * Called when window size or position changes or viewport or depth range
1345 * state is changed. We update the hardware viewport state here.
1346 */
1347 void radeonUpdateWindow( struct gl_context *ctx )
1348 {
1349 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1350 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1351 GLfloat xoffset = 0.0;
1352 GLfloat yoffset = dPriv ? (GLfloat) dPriv->h : 0;
1353 const GLfloat *v = ctx->Viewport._WindowMap.m;
1354 const GLboolean render_to_fbo = (ctx->DrawBuffer ? _mesa_is_user_fbo(ctx->DrawBuffer) : 0);
1355 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1356 GLfloat y_scale, y_bias;
1357
1358 if (render_to_fbo) {
1359 y_scale = 1.0;
1360 y_bias = 0;
1361 } else {
1362 y_scale = -1.0;
1363 y_bias = yoffset;
1364 }
1365
1366 float_ui32_type sx = { v[MAT_SX] };
1367 float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
1368 float_ui32_type sy = { v[MAT_SY] * y_scale };
1369 float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
1370 float_ui32_type sz = { v[MAT_SZ] * depthScale };
1371 float_ui32_type tz = { v[MAT_TZ] * depthScale };
1372
1373 RADEON_STATECHANGE( rmesa, vpt );
1374
1375 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32;
1376 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1377 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32;
1378 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1379 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32;
1380 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1381 }
1382
1383
1384 static void radeonViewport( struct gl_context *ctx, GLint x, GLint y,
1385 GLsizei width, GLsizei height )
1386 {
1387 /* Don't pipeline viewport changes, conflict with window offset
1388 * setting below. Could apply deltas to rescue pipelined viewport
1389 * values, or keep the originals hanging around.
1390 */
1391 radeonUpdateWindow( ctx );
1392
1393 radeon_viewport(ctx, x, y, width, height);
1394 }
1395
1396 static void radeonDepthRange( struct gl_context *ctx, GLclampd nearval,
1397 GLclampd farval )
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.FragmentProgram.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 }