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