add tdfx DRI driver
[mesa.git] / src / mesa / drivers / dri / tdfx / tdfx_state.c
1 /* -*- mode: c; c-basic-offset: 3 -*-
2 *
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */
27
28 /*
29 * Original rewrite:
30 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
31 *
32 * Authors:
33 * Gareth Hughes <gareth@valinux.com>
34 * Brian Paul <brianp@valinux.com>
35 * Keith Whitwell <keith@tungstengraphics.com> (port to 3.5)
36 *
37 */
38
39 #include "mtypes.h"
40 #include "colormac.h"
41 #include "texformat.h"
42 #include "texstore.h"
43
44 #include "swrast/swrast.h"
45 #include "array_cache/acache.h"
46 #include "tnl/tnl.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
49
50 #include "tdfx_context.h"
51 #include "tdfx_state.h"
52 #include "tdfx_vb.h"
53 #include "tdfx_tex.h"
54 #include "tdfx_texman.h"
55 #include "tdfx_texstate.h"
56 #include "tdfx_tris.h"
57 #include "tdfx_render.h"
58
59
60
61 /* =============================================================
62 * Alpha blending
63 */
64
65 static void tdfxUpdateAlphaMode( GLcontext *ctx )
66 {
67 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
68 GrCmpFnc_t func;
69 GrAlphaBlendFnc_t srcRGB, dstRGB, srcA, dstA;
70 GrAlpha_t ref = (GLint) (ctx->Color.AlphaRef * 255.0);
71
72 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
73 fprintf( stderr, "%s()\n", __FUNCTION__ );
74 }
75
76 if ( ctx->Color.AlphaEnabled ) {
77 switch ( ctx->Color.AlphaFunc ) {
78 case GL_NEVER:
79 func = GR_CMP_NEVER;
80 break;
81 case GL_LESS:
82 func = GR_CMP_LESS;
83 break;
84 case GL_LEQUAL:
85 func = GR_CMP_LEQUAL;
86 break;
87 case GL_EQUAL:
88 func = GR_CMP_EQUAL;
89 break;
90 case GL_GEQUAL:
91 func = GR_CMP_GEQUAL;
92 break;
93 case GL_GREATER:
94 func = GR_CMP_GREATER;
95 break;
96 case GL_NOTEQUAL:
97 func = GR_CMP_NOTEQUAL;
98 break;
99 case GL_ALWAYS:
100 default:
101 func = GR_CMP_ALWAYS;
102 break;
103 }
104 } else {
105 func = GR_CMP_ALWAYS;
106 }
107
108 if ( ctx->Color.BlendEnabled
109 && (fxMesa->Fallback & TDFX_FALLBACK_BLEND) == 0 ) {
110 switch ( ctx->Color.BlendSrcRGB ) {
111 case GL_ZERO:
112 srcRGB = GR_BLEND_ZERO;
113 break;
114 case GL_ONE:
115 srcRGB = GR_BLEND_ONE;
116 break;
117 case GL_DST_COLOR:
118 srcRGB = GR_BLEND_DST_COLOR;
119 break;
120 case GL_ONE_MINUS_DST_COLOR:
121 srcRGB = GR_BLEND_ONE_MINUS_DST_COLOR;
122 break;
123 case GL_SRC_ALPHA:
124 srcRGB = GR_BLEND_SRC_ALPHA;
125 break;
126 case GL_ONE_MINUS_SRC_ALPHA:
127 srcRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
128 break;
129 case GL_DST_ALPHA:
130 srcRGB = GR_BLEND_DST_ALPHA;
131 break;
132 case GL_ONE_MINUS_DST_ALPHA:
133 srcRGB = GR_BLEND_ONE_MINUS_DST_ALPHA;
134 break;
135 case GL_SRC_ALPHA_SATURATE:
136 srcRGB = GR_BLEND_ALPHA_SATURATE;
137 break;
138 default:
139 srcRGB = GR_BLEND_ONE;
140 }
141
142 switch ( ctx->Color.BlendSrcA ) {
143 case GL_ZERO:
144 srcA = GR_BLEND_ZERO;
145 break;
146 case GL_ONE:
147 srcA = GR_BLEND_ONE;
148 break;
149 case GL_DST_COLOR:
150 srcA = GR_BLEND_DST_ALPHA; /* Napalm only */
151 break;
152 case GL_ONE_MINUS_DST_COLOR:
153 srcA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */
154 break;
155 case GL_SRC_ALPHA:
156 srcA = GR_BLEND_SRC_ALPHA; /* Napalm only */
157 break;
158 case GL_ONE_MINUS_SRC_ALPHA:
159 srcA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */
160 break;
161 case GL_DST_ALPHA:
162 srcA = GR_BLEND_DST_ALPHA; /* Napalm only */
163 break;
164 case GL_ONE_MINUS_DST_ALPHA:
165 srcA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */
166 break;
167 case GL_SRC_ALPHA_SATURATE:
168 srcA = GR_BLEND_ONE;
169 break;
170 default:
171 srcA = GR_BLEND_ONE;
172 }
173
174 switch ( ctx->Color.BlendDstRGB ) {
175 case GL_ZERO:
176 dstRGB = GR_BLEND_ZERO;
177 break;
178 case GL_ONE:
179 dstRGB = GR_BLEND_ONE;
180 break;
181 case GL_SRC_COLOR:
182 dstRGB = GR_BLEND_SRC_COLOR;
183 break;
184 case GL_ONE_MINUS_SRC_COLOR:
185 dstRGB = GR_BLEND_ONE_MINUS_SRC_COLOR;
186 break;
187 case GL_SRC_ALPHA:
188 dstRGB = GR_BLEND_SRC_ALPHA;
189 break;
190 case GL_ONE_MINUS_SRC_ALPHA:
191 dstRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
192 break;
193 case GL_DST_ALPHA:
194 dstRGB = GR_BLEND_DST_ALPHA;
195 break;
196 case GL_ONE_MINUS_DST_ALPHA:
197 dstRGB = GR_BLEND_ONE_MINUS_DST_ALPHA;
198 break;
199 default:
200 dstRGB = GR_BLEND_ZERO;
201 }
202
203 switch ( ctx->Color.BlendDstA ) {
204 case GL_ZERO:
205 dstA = GR_BLEND_ZERO;
206 break;
207 case GL_ONE:
208 dstA = GR_BLEND_ONE;
209 break;
210 case GL_SRC_COLOR:
211 dstA = GR_BLEND_SRC_ALPHA; /* Napalm only */
212 break;
213 case GL_ONE_MINUS_SRC_COLOR:
214 dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */
215 break;
216 case GL_SRC_ALPHA:
217 dstA = GR_BLEND_SRC_ALPHA; /* Napalm only */
218 break;
219 case GL_ONE_MINUS_SRC_ALPHA:
220 dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */
221 break;
222 case GL_DST_ALPHA:
223 dstA = GR_BLEND_DST_ALPHA; /* Napalm only */
224 break;
225 case GL_ONE_MINUS_DST_ALPHA:
226 dstA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */
227 break;
228 default:
229 dstA = GR_BLEND_ZERO;
230 }
231 } else {
232 /* blend disabled */
233 srcRGB = GR_BLEND_ONE;
234 dstRGB = GR_BLEND_ZERO;
235 srcA = GR_BLEND_ONE;
236 dstA = GR_BLEND_ZERO;
237 }
238
239 if ( fxMesa->Color.AlphaFunc != func ) {
240 fxMesa->Color.AlphaFunc = func;
241 fxMesa->dirty |= TDFX_UPLOAD_ALPHA_TEST;
242 }
243 if ( fxMesa->Color.AlphaRef != ref ) {
244 fxMesa->Color.AlphaRef = ref;
245 fxMesa->dirty |= TDFX_UPLOAD_ALPHA_REF;
246 }
247
248 if ( fxMesa->Color.BlendSrcRGB != srcRGB ||
249 fxMesa->Color.BlendDstRGB != dstRGB ||
250 fxMesa->Color.BlendSrcA != srcA ||
251 fxMesa->Color.BlendDstA != dstA )
252 {
253 fxMesa->Color.BlendSrcRGB = srcRGB;
254 fxMesa->Color.BlendDstRGB = dstRGB;
255 fxMesa->Color.BlendSrcA = srcA;
256 fxMesa->Color.BlendDstA = dstA;
257 fxMesa->dirty |= TDFX_UPLOAD_BLEND_FUNC;
258 }
259 }
260
261 static void tdfxDDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
262 {
263 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
264
265 FLUSH_BATCH( fxMesa );
266 fxMesa->new_state |= TDFX_NEW_ALPHA;
267 }
268
269 static void tdfxDDBlendEquation( GLcontext *ctx, GLenum mode )
270 {
271 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
272
273 FLUSH_BATCH( fxMesa );
274 fxMesa->new_state |= TDFX_NEW_ALPHA;
275 }
276
277 static void tdfxDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
278 {
279 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
280
281 FLUSH_BATCH( fxMesa );
282 fxMesa->new_state |= TDFX_NEW_ALPHA;
283
284 /*
285 * XXX - Voodoo5 seems to suffer from precision problems in some
286 * blend modes. To pass all the conformance tests we'd have to
287 * fall back to software for many modes. Revisit someday.
288 */
289 }
290
291 static void tdfxDDBlendFuncSeparate( GLcontext *ctx,
292 GLenum sfactorRGB, GLenum dfactorRGB,
293 GLenum sfactorA, GLenum dfactorA )
294 {
295 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
296
297 FLUSH_BATCH( fxMesa );
298 fxMesa->new_state |= TDFX_NEW_ALPHA;
299 }
300
301 /* =============================================================
302 * Stipple
303 */
304
305 void tdfxUpdateStipple( GLcontext *ctx )
306 {
307 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
308 GrStippleMode_t mode = GR_STIPPLE_DISABLE;
309
310 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
311 fprintf( stderr, "%s()\n", __FUNCTION__ );
312 }
313
314 FLUSH_BATCH( fxMesa );
315
316 if (ctx->Polygon.StippleFlag) {
317 mode = GR_STIPPLE_PATTERN;
318 }
319
320 if ( fxMesa->Stipple.Mode != mode ) {
321 fxMesa->Stipple.Mode = mode;
322 fxMesa->dirty |= TDFX_UPLOAD_STIPPLE;
323 }
324 }
325
326
327 /* =============================================================
328 * Depth testing
329 */
330
331 static void tdfxUpdateZMode( GLcontext *ctx )
332 {
333 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
334 GrCmpFnc_t func;
335 FxI32 bias;
336 FxBool mask;
337
338 if ( TDFX_DEBUG & DEBUG_VERBOSE_API )
339 fprintf( stderr, "%s()\n", __FUNCTION__ );
340
341
342 bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE);
343
344 if ( ctx->Depth.Test ) {
345 switch ( ctx->Depth.Func ) {
346 case GL_NEVER:
347 func = GR_CMP_NEVER;
348 break;
349 case GL_LESS:
350 func = GR_CMP_LESS;
351 break;
352 case GL_LEQUAL:
353 func = GR_CMP_LEQUAL;
354 break;
355 case GL_EQUAL:
356 func = GR_CMP_EQUAL;
357 break;
358 case GL_GEQUAL:
359 func = GR_CMP_GEQUAL;
360 break;
361 case GL_GREATER:
362 func = GR_CMP_GREATER;
363 break;
364 case GL_NOTEQUAL:
365 func = GR_CMP_NOTEQUAL;
366 break;
367 case GL_ALWAYS:
368 default:
369 func = GR_CMP_ALWAYS;
370 break;
371 }
372
373 if ( ctx->Depth.Mask ) {
374 mask = FXTRUE;
375 }
376 else {
377 mask = FXFALSE;
378 }
379 }
380 else {
381 /* depth testing disabled */
382 func = GR_CMP_ALWAYS; /* fragments always pass */
383 mask = FXFALSE; /* zbuffer is not touched */
384 }
385
386 fxMesa->Depth.Clear = (FxU32) (((1 << fxMesa->glCtx->Visual.depthBits) - 1)
387 * ctx->Depth.Clear);
388
389 if ( fxMesa->Depth.Bias != bias ) {
390 fxMesa->Depth.Bias = bias;
391 fxMesa->dirty |= TDFX_UPLOAD_DEPTH_BIAS;
392 }
393 if ( fxMesa->Depth.Func != func ) {
394 fxMesa->Depth.Func = func;
395 fxMesa->dirty |= TDFX_UPLOAD_DEPTH_FUNC | TDFX_UPLOAD_DEPTH_MASK;
396 }
397 if ( fxMesa->Depth.Mask != mask ) {
398 fxMesa->Depth.Mask = mask;
399 fxMesa->dirty |= TDFX_UPLOAD_DEPTH_MASK;
400 }
401 }
402
403 static void tdfxDDDepthFunc( GLcontext *ctx, GLenum func )
404 {
405 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
406
407 FLUSH_BATCH( fxMesa );
408 fxMesa->new_state |= TDFX_NEW_DEPTH;
409 }
410
411 static void tdfxDDDepthMask( GLcontext *ctx, GLboolean flag )
412 {
413 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
414
415 FLUSH_BATCH( fxMesa );
416 fxMesa->new_state |= TDFX_NEW_DEPTH;
417 }
418
419 static void tdfxDDClearDepth( GLcontext *ctx, GLclampd d )
420 {
421 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
422
423 FLUSH_BATCH( fxMesa );
424 fxMesa->new_state |= TDFX_NEW_DEPTH;
425 }
426
427
428
429 /* =============================================================
430 * Stencil
431 */
432
433
434 /* Evaluate all stencil state and make the Glide calls.
435 */
436 static GrStencil_t convertGLStencilOp( GLenum op )
437 {
438 switch ( op ) {
439 case GL_KEEP:
440 return GR_STENCILOP_KEEP;
441 case GL_ZERO:
442 return GR_STENCILOP_ZERO;
443 case GL_REPLACE:
444 return GR_STENCILOP_REPLACE;
445 case GL_INCR:
446 return GR_STENCILOP_INCR_CLAMP;
447 case GL_DECR:
448 return GR_STENCILOP_DECR_CLAMP;
449 case GL_INVERT:
450 return GR_STENCILOP_INVERT;
451 case GL_INCR_WRAP_EXT:
452 return GR_STENCILOP_INCR_WRAP;
453 case GL_DECR_WRAP_EXT:
454 return GR_STENCILOP_DECR_WRAP;
455 default:
456 _mesa_problem( NULL, "bad stencil op in convertGLStencilOp" );
457 }
458 return GR_STENCILOP_KEEP; /* never get, silence compiler warning */
459 }
460
461
462 static void tdfxUpdateStencil( GLcontext *ctx )
463 {
464 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
465
466 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
467 fprintf( stderr, "%s()\n", __FUNCTION__ );
468 }
469
470 if (fxMesa->haveHwStencil) {
471 if (ctx->Stencil.Enabled) {
472 fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER;
473 fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0];
474 fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0];
475 fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask[0];
476 fxMesa->Stencil.FailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[0]);
477 fxMesa->Stencil.ZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[0]);
478 fxMesa->Stencil.ZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[0]);
479 fxMesa->Stencil.Clear = ctx->Stencil.Clear & 0xff;
480 }
481 fxMesa->dirty |= TDFX_UPLOAD_STENCIL;
482 }
483 }
484
485
486 static void tdfxDDStencilFunc( GLcontext *ctx, GLenum func,
487 GLint ref, GLuint mask )
488 {
489 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
490
491 FLUSH_BATCH( fxMesa );
492 fxMesa->new_state |= TDFX_NEW_STENCIL;
493 }
494
495 static void tdfxDDStencilMask( GLcontext *ctx, GLuint mask )
496 {
497 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
498
499 FLUSH_BATCH( fxMesa );
500 fxMesa->new_state |= TDFX_NEW_STENCIL;
501 }
502
503 static void tdfxDDStencilOp( GLcontext *ctx, GLenum sfail,
504 GLenum zfail, GLenum zpass )
505 {
506 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
507
508 FLUSH_BATCH( fxMesa );
509 fxMesa->new_state |= TDFX_NEW_STENCIL;
510 }
511
512
513 /* =============================================================
514 * Fog - orthographic fog still not working
515 */
516
517 static void tdfxUpdateFogAttrib( GLcontext *ctx )
518 {
519 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
520 GrFogMode_t mode;
521 GrColor_t color;
522
523 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
524 fprintf( stderr, "%s()\n", __FUNCTION__ );
525 }
526
527 if ( ctx->Fog.Enabled ) {
528 mode = GR_FOG_WITH_TABLE_ON_Q;
529 } else {
530 mode = GR_FOG_DISABLE;
531 }
532
533 color = TDFXPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F),
534 (GLubyte)(ctx->Fog.Color[1]*255.0F),
535 (GLubyte)(ctx->Fog.Color[2]*255.0F));
536
537 if ( fxMesa->Fog.Mode != mode ) {
538 fxMesa->Fog.Mode = mode;
539 fxMesa->dirty |= TDFX_UPLOAD_FOG_MODE;
540 }
541 if ( fxMesa->Fog.Color != color ) {
542 fxMesa->Fog.Color = color;
543 fxMesa->dirty |= TDFX_UPLOAD_FOG_COLOR;
544 }
545 if ( fxMesa->Fog.TableMode != ctx->Fog.Mode ||
546 fxMesa->Fog.Density != ctx->Fog.Density ||
547 fxMesa->Fog.Near != ctx->Fog.Start ||
548 fxMesa->Fog.Far != ctx->Fog.End )
549 {
550 switch( ctx->Fog.Mode ) {
551 case GL_EXP:
552 fxMesa->Glide.guFogGenerateExp( fxMesa->Fog.Table, ctx->Fog.Density );
553 break;
554 case GL_EXP2:
555 fxMesa->Glide.guFogGenerateExp2( fxMesa->Fog.Table, ctx->Fog.Density);
556 break;
557 case GL_LINEAR:
558 fxMesa->Glide.guFogGenerateLinear( fxMesa->Fog.Table,
559 ctx->Fog.Start, ctx->Fog.End );
560 break;
561 }
562
563 fxMesa->Fog.TableMode = ctx->Fog.Mode;
564 fxMesa->Fog.Density = ctx->Fog.Density;
565 fxMesa->Fog.Near = ctx->Fog.Start;
566 fxMesa->Fog.Far = ctx->Fog.End;
567 fxMesa->dirty |= TDFX_UPLOAD_FOG_TABLE;
568 }
569 }
570
571 static void tdfxDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
572 {
573 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
574
575 FLUSH_BATCH( fxMesa );
576 fxMesa->new_state |= TDFX_NEW_FOG;
577 }
578
579
580 /* =============================================================
581 * Clipping
582 */
583
584 static int intersect_rect( XF86DRIClipRectPtr out,
585 const XF86DRIClipRectPtr a,
586 const XF86DRIClipRectPtr b)
587 {
588 *out = *a;
589 if (b->x1 > out->x1) out->x1 = b->x1;
590 if (b->y1 > out->y1) out->y1 = b->y1;
591 if (b->x2 < out->x2) out->x2 = b->x2;
592 if (b->y2 < out->y2) out->y2 = b->y2;
593 if (out->x1 >= out->x2) return 0;
594 if (out->y1 >= out->y2) return 0;
595 return 1;
596 }
597
598
599 /*
600 * Examine XF86 cliprect list and scissor state to recompute our
601 * cliprect list.
602 */
603 void tdfxUpdateClipping( GLcontext *ctx )
604 {
605 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
606 __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;
607
608 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
609 fprintf( stderr, "%s()\n", __FUNCTION__ );
610 }
611
612 assert(ctx);
613 assert(fxMesa);
614 assert(dPriv);
615
616 if ( dPriv->x != fxMesa->x_offset || dPriv->y != fxMesa->y_offset ||
617 dPriv->w != fxMesa->width || dPriv->h != fxMesa->height ) {
618 fxMesa->x_offset = dPriv->x;
619 fxMesa->y_offset = dPriv->y;
620 fxMesa->width = dPriv->w;
621 fxMesa->height = dPriv->h;
622 fxMesa->y_delta =
623 fxMesa->screen_height - fxMesa->y_offset - fxMesa->height;
624 tdfxUpdateViewport( ctx );
625 }
626
627 if (fxMesa->scissoredClipRects && fxMesa->pClipRects) {
628 free(fxMesa->pClipRects);
629 }
630
631 if (ctx->Scissor.Enabled) {
632 /* intersect OpenGL scissor box with all cliprects to make a new
633 * list of cliprects.
634 */
635 XF86DRIClipRectRec scissor;
636 int x1 = ctx->Scissor.X + fxMesa->x_offset;
637 int y1 = fxMesa->screen_height - fxMesa->y_delta
638 - ctx->Scissor.Y - ctx->Scissor.Height;
639 int x2 = x1 + ctx->Scissor.Width;
640 int y2 = y1 + ctx->Scissor.Height;
641 scissor.x1 = MAX2(x1, 0);
642 scissor.y1 = MAX2(y1, 0);
643 scissor.x2 = MAX2(x2, 0);
644 scissor.y2 = MAX2(y2, 0);
645
646 assert(scissor.x2 >= scissor.x1);
647 assert(scissor.y2 >= scissor.y1);
648
649 fxMesa->pClipRects = malloc(dPriv->numClipRects
650 * sizeof(XF86DRIClipRectRec));
651 if (fxMesa->pClipRects) {
652 int i;
653 fxMesa->numClipRects = 0;
654 for (i = 0; i < dPriv->numClipRects; i++) {
655 if (intersect_rect(&fxMesa->pClipRects[fxMesa->numClipRects],
656 &scissor, &dPriv->pClipRects[i])) {
657 fxMesa->numClipRects++;
658 }
659 }
660 fxMesa->scissoredClipRects = GL_TRUE;
661 }
662 else {
663 /* out of memory, forgo scissor */
664 fxMesa->numClipRects = dPriv->numClipRects;
665 fxMesa->pClipRects = dPriv->pClipRects;
666 fxMesa->scissoredClipRects = GL_FALSE;
667 }
668 }
669 else {
670 fxMesa->numClipRects = dPriv->numClipRects;
671 fxMesa->pClipRects = dPriv->pClipRects;
672 fxMesa->scissoredClipRects = GL_FALSE;
673 }
674
675 fxMesa->dirty |= TDFX_UPLOAD_CLIP;
676 }
677
678
679
680 /* =============================================================
681 * Culling
682 */
683
684 void tdfxUpdateCull( GLcontext *ctx )
685 {
686 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
687 GrCullMode_t mode = GR_CULL_DISABLE;
688
689 /* KW: don't need to check raster_primitive here as we don't
690 * attempt to draw lines or points with triangles.
691 */
692 if ( ctx->Polygon.CullFlag ) {
693 switch ( ctx->Polygon.CullFaceMode ) {
694 case GL_FRONT:
695 if ( ctx->Polygon.FrontFace == GL_CCW ) {
696 mode = GR_CULL_POSITIVE;
697 } else {
698 mode = GR_CULL_NEGATIVE;
699 }
700 break;
701
702 case GL_BACK:
703 if ( ctx->Polygon.FrontFace == GL_CCW ) {
704 mode = GR_CULL_NEGATIVE;
705 } else {
706 mode = GR_CULL_POSITIVE;
707 }
708 break;
709
710 case GL_FRONT_AND_BACK:
711 /* Handled as a fallback on triangles in tdfx_tris.c */
712 return;
713
714 default:
715 ASSERT(0);
716 break;
717 }
718 }
719
720 if ( fxMesa->CullMode != mode ) {
721 fxMesa->CullMode = mode;
722 fxMesa->dirty |= TDFX_UPLOAD_CULL;
723 }
724 }
725
726 static void tdfxDDCullFace( GLcontext *ctx, GLenum mode )
727 {
728 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
729
730 FLUSH_BATCH( fxMesa );
731 fxMesa->new_state |= TDFX_NEW_CULL;
732 }
733
734 static void tdfxDDFrontFace( GLcontext *ctx, GLenum mode )
735 {
736 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
737
738 FLUSH_BATCH( fxMesa );
739 fxMesa->new_state |= TDFX_NEW_CULL;
740 }
741
742
743 /* =============================================================
744 * Line drawing.
745 */
746
747 static void tdfxUpdateLine( GLcontext *ctx )
748 {
749 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
750
751 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
752 fprintf( stderr, "%s()\n", __FUNCTION__ );
753 }
754
755 FLUSH_BATCH( fxMesa );
756 fxMesa->dirty |= TDFX_UPLOAD_LINE;
757 }
758
759
760 static void tdfxDDLineWidth( GLcontext *ctx, GLfloat width )
761 {
762 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
763 FLUSH_BATCH( fxMesa );
764 fxMesa->new_state |= TDFX_NEW_LINE;
765 }
766
767
768 /* =============================================================
769 * Color Attributes
770 */
771
772 static void tdfxDDColorMask( GLcontext *ctx,
773 GLboolean r, GLboolean g,
774 GLboolean b, GLboolean a )
775 {
776 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
777
778 FLUSH_BATCH( fxMesa );
779
780 if ( fxMesa->Color.ColorMask[RCOMP] != r ||
781 fxMesa->Color.ColorMask[GCOMP] != g ||
782 fxMesa->Color.ColorMask[BCOMP] != b ||
783 fxMesa->Color.ColorMask[ACOMP] != a ) {
784 fxMesa->Color.ColorMask[RCOMP] = r;
785 fxMesa->Color.ColorMask[GCOMP] = g;
786 fxMesa->Color.ColorMask[BCOMP] = b;
787 fxMesa->Color.ColorMask[ACOMP] = a;
788 fxMesa->dirty |= TDFX_UPLOAD_COLOR_MASK;
789
790 if (ctx->Visual.redBits < 8) {
791 /* Can't do RGB colormasking in 16bpp mode. */
792 /* We can completely ignore the alpha mask. */
793 FALLBACK( fxMesa, TDFX_FALLBACK_COLORMASK, (r != g || g != b) );
794 }
795 }
796 }
797
798
799 static void tdfxDDClearColor( GLcontext *ctx,
800 const GLfloat color[4] )
801 {
802 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
803 GLubyte c[4];
804 FLUSH_BATCH( fxMesa );
805 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
806 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
807 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
808 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
809 fxMesa->Color.ClearColor = TDFXPACKCOLOR888( c[0], c[1], c[2] );
810 fxMesa->Color.ClearAlpha = c[3];
811 }
812
813
814 /* =============================================================
815 * Light Model
816 */
817
818 static void tdfxDDLightModelfv( GLcontext *ctx, GLenum pname,
819 const GLfloat *param )
820 {
821 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
822
823 if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) {
824 FALLBACK( fxMesa, TDFX_FALLBACK_SPECULAR,
825 (ctx->Light.Enabled &&
826 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ));
827 }
828 }
829
830 static void tdfxDDShadeModel( GLcontext *ctx, GLenum mode )
831 {
832 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
833
834 /* FIXME: Can we implement native flat shading? */
835 FLUSH_BATCH( fxMesa );
836 fxMesa->new_state |= TDFX_NEW_TEXTURE;
837 }
838
839
840 /* =============================================================
841 * Scissor
842 */
843
844 static void
845 tdfxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
846 {
847 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
848 FLUSH_BATCH( fxMesa );
849 fxMesa->new_state |= TDFX_NEW_CLIP;
850 }
851
852 /* =============================================================
853 * Render
854 */
855
856 static void tdfxUpdateRenderAttrib( GLcontext *ctx )
857 {
858 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
859 FLUSH_BATCH( fxMesa );
860 fxMesa->dirty |= TDFX_UPLOAD_RENDER_BUFFER;
861 }
862
863 /* =============================================================
864 * Viewport
865 */
866
867 void tdfxUpdateViewport( GLcontext *ctx )
868 {
869 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
870 const GLfloat *v = ctx->Viewport._WindowMap.m;
871 GLfloat *m = fxMesa->hw_viewport;
872
873 m[MAT_SX] = v[MAT_SX];
874 m[MAT_TX] = v[MAT_TX] + fxMesa->x_offset + TRI_X_OFFSET;
875 m[MAT_SY] = v[MAT_SY];
876 m[MAT_TY] = v[MAT_TY] + fxMesa->y_delta + TRI_Y_OFFSET;
877 m[MAT_SZ] = v[MAT_SZ];
878 m[MAT_TZ] = v[MAT_TZ];
879
880 fxMesa->SetupNewInputs |= VERT_BIT_CLIP;
881 }
882
883
884 static void tdfxDDViewport( GLcontext *ctx, GLint x, GLint y,
885 GLsizei w, GLsizei h )
886 {
887 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
888 FLUSH_BATCH( fxMesa );
889 fxMesa->new_state |= TDFX_NEW_VIEWPORT;
890 }
891
892
893 static void tdfxDDDepthRange( GLcontext *ctx, GLclampd nearVal, GLclampd farVal )
894 {
895 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
896 FLUSH_BATCH( fxMesa );
897 fxMesa->new_state |= TDFX_NEW_VIEWPORT;
898 }
899
900
901 /* =============================================================
902 * State enable/disable
903 */
904
905 static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
906 {
907 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
908
909 switch ( cap ) {
910 case GL_ALPHA_TEST:
911 FLUSH_BATCH( fxMesa );
912 fxMesa->new_state |= TDFX_NEW_ALPHA;
913 break;
914
915 case GL_BLEND:
916 FLUSH_BATCH( fxMesa );
917 fxMesa->new_state |= TDFX_NEW_ALPHA;
918 FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP,
919 (ctx->Color.ColorLogicOpEnabled &&
920 ctx->Color.LogicOp != GL_COPY));
921 break;
922
923 case GL_CULL_FACE:
924 FLUSH_BATCH( fxMesa );
925 fxMesa->new_state |= TDFX_NEW_CULL;
926 break;
927
928 case GL_DEPTH_TEST:
929 FLUSH_BATCH( fxMesa );
930 fxMesa->new_state |= TDFX_NEW_DEPTH;
931 break;
932
933 case GL_DITHER:
934 FLUSH_BATCH( fxMesa );
935 if ( state ) {
936 fxMesa->Color.Dither = GR_DITHER_2x2;
937 } else {
938 fxMesa->Color.Dither = GR_DITHER_DISABLE;
939 }
940 fxMesa->dirty |= TDFX_UPLOAD_DITHER;
941 break;
942
943 case GL_FOG:
944 FLUSH_BATCH( fxMesa );
945 fxMesa->new_state |= TDFX_NEW_FOG;
946 break;
947
948 case GL_COLOR_LOGIC_OP:
949 FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP,
950 (ctx->Color.ColorLogicOpEnabled &&
951 ctx->Color.LogicOp != GL_COPY));
952 break;
953
954 case GL_LIGHTING:
955 FALLBACK( fxMesa, TDFX_FALLBACK_SPECULAR,
956 (ctx->Light.Enabled &&
957 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ));
958 break;
959
960 case GL_LINE_SMOOTH:
961 FLUSH_BATCH( fxMesa );
962 fxMesa->new_state |= TDFX_NEW_LINE;
963 break;
964
965 case GL_LINE_STIPPLE:
966 FALLBACK(fxMesa, TDFX_FALLBACK_LINE_STIPPLE, state);
967 break;
968
969 case GL_POLYGON_STIPPLE:
970 FLUSH_BATCH(fxMesa);
971 fxMesa->new_state |= TDFX_NEW_STIPPLE;
972 break;
973
974 case GL_SCISSOR_TEST:
975 FLUSH_BATCH( fxMesa );
976 fxMesa->new_state |= TDFX_NEW_CLIP;
977 break;
978
979 case GL_STENCIL_TEST:
980 FLUSH_BATCH( fxMesa );
981 FALLBACK( fxMesa, TDFX_FALLBACK_STENCIL, state && !fxMesa->haveHwStencil);
982 break;
983
984 case GL_TEXTURE_1D:
985 case GL_TEXTURE_3D:
986 FLUSH_BATCH( fxMesa );
987 FALLBACK( fxMesa, TDFX_FALLBACK_TEXTURE_1D_3D, state); /* wrong */
988 fxMesa->new_state |= TDFX_NEW_TEXTURE;
989 break;
990
991 case GL_TEXTURE_2D:
992 FLUSH_BATCH( fxMesa );
993 fxMesa->new_state |= TDFX_NEW_TEXTURE;
994 break;
995
996 default:
997 return;
998 }
999 }
1000
1001
1002
1003 /* Set the buffer used for drawing */
1004 /* XXX support for separate read/draw buffers hasn't been tested */
1005 static void tdfxDDDrawBuffer( GLcontext *ctx, GLenum mode )
1006 {
1007 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1008
1009 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
1010 fprintf( stderr, "%s()\n", __FUNCTION__ );
1011 }
1012
1013 FLUSH_BATCH( fxMesa );
1014
1015 /*
1016 * _DrawDestMask is easier to cope with than <mode>.
1017 */
1018 switch ( ctx->Color._DrawDestMask ) {
1019 case FRONT_LEFT_BIT:
1020 fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_FRONTBUFFER;
1021 fxMesa->new_state |= TDFX_NEW_RENDER;
1022 FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
1023 break;
1024 case BACK_LEFT_BIT:
1025 fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_BACKBUFFER;
1026 fxMesa->new_state |= TDFX_NEW_RENDER;
1027 FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
1028 break;
1029 case 0:
1030 FX_grColorMaskv( ctx, false4 );
1031 FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
1032 break;
1033 default:
1034 FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_TRUE );
1035 break;
1036 }
1037
1038 /* We want to update the s/w rast state too so that tdfxDDSetBuffer()
1039 * gets called.
1040 */
1041 _swrast_DrawBuffer(ctx, mode);
1042 }
1043
1044
1045 static void tdfxDDReadBuffer( GLcontext *ctx, GLenum mode )
1046 {
1047 /* XXX ??? */
1048 }
1049
1050
1051 /* =============================================================
1052 * Polygon stipple
1053 */
1054
1055 static void tdfxDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
1056 {
1057 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1058 const GLubyte *m = mask;
1059 GLubyte q[4];
1060 int i,j,k;
1061 GLboolean allBitsSet;
1062
1063 /* int active = (ctx->Polygon.StippleFlag && */
1064 /* fxMesa->reduced_prim == GL_TRIANGLES); */
1065
1066 FLUSH_BATCH(fxMesa);
1067 fxMesa->Stipple.Pattern = 0xffffffff;
1068 fxMesa->dirty |= TDFX_UPLOAD_STIPPLE;
1069 fxMesa->new_state |= TDFX_NEW_STIPPLE;
1070
1071 /* Check if the stipple pattern is fully opaque. If so, use software
1072 * rendering. This basically a trick to make sure the OpenGL conformance
1073 * test passes.
1074 */
1075 allBitsSet = GL_TRUE;
1076 for (i = 0; i < 32; i++) {
1077 if (((GLuint *) mask)[i] != 0xffffffff) {
1078 allBitsSet = GL_FALSE;
1079 break;
1080 }
1081 }
1082 if (allBitsSet) {
1083 fxMesa->haveHwStipple = GL_FALSE;
1084 return;
1085 }
1086
1087 q[0] = mask[0];
1088 q[1] = mask[4];
1089 q[2] = mask[8];
1090 q[3] = mask[12];
1091
1092 for (k = 0 ; k < 8 ; k++)
1093 for (j = 0 ; j < 4; j++)
1094 for (i = 0 ; i < 4 ; i++,m++) {
1095 if (*m != q[j]) {
1096 fxMesa->haveHwStipple = GL_FALSE;
1097 return;
1098 }
1099 }
1100
1101 fxMesa->haveHwStipple = GL_TRUE;
1102 fxMesa->Stipple.Pattern = ( (q[0] << 0) |
1103 (q[1] << 8) |
1104 (q[2] << 16) |
1105 (q[3] << 24) );
1106 }
1107
1108
1109
1110 static void tdfxDDRenderMode( GLcontext *ctx, GLenum mode )
1111 {
1112 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1113 FALLBACK( fxMesa, TDFX_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1114 }
1115
1116
1117
1118 static void tdfxDDPrintState( const char *msg, GLuint flags )
1119 {
1120 fprintf( stderr,
1121 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s\n",
1122 msg,
1123 flags,
1124 (flags & TDFX_NEW_COLOR) ? "color, " : "",
1125 (flags & TDFX_NEW_ALPHA) ? "alpha, " : "",
1126 (flags & TDFX_NEW_DEPTH) ? "depth, " : "",
1127 (flags & TDFX_NEW_RENDER) ? "render, " : "",
1128 (flags & TDFX_NEW_FOG) ? "fog, " : "",
1129 (flags & TDFX_NEW_STENCIL) ? "stencil, " : "",
1130 (flags & TDFX_NEW_STIPPLE) ? "stipple, " : "",
1131 (flags & TDFX_NEW_CLIP) ? "clip, " : "",
1132 (flags & TDFX_NEW_VIEWPORT) ? "viewport, " : "",
1133 (flags & TDFX_NEW_CULL) ? "cull, " : "",
1134 (flags & TDFX_NEW_GLIDE) ? "glide, " : "",
1135 (flags & TDFX_NEW_TEXTURE) ? "texture, " : "",
1136 (flags & TDFX_NEW_CONTEXT) ? "context, " : "");
1137 }
1138
1139
1140
1141 void tdfxDDUpdateHwState( GLcontext *ctx )
1142 {
1143 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1144 int new_state = fxMesa->new_state;
1145
1146 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
1147 fprintf( stderr, "%s()\n", __FUNCTION__ );
1148 }
1149
1150 if ( new_state )
1151 {
1152 FLUSH_BATCH( fxMesa );
1153
1154 fxMesa->new_state = 0;
1155
1156 if ( 0 )
1157 tdfxDDPrintState( "tdfxUpdateHwState", new_state );
1158
1159 /* Update the various parts of the context's state.
1160 */
1161 if ( new_state & TDFX_NEW_ALPHA ) {
1162 tdfxUpdateAlphaMode( ctx );
1163 }
1164
1165 if ( new_state & TDFX_NEW_DEPTH )
1166 tdfxUpdateZMode( ctx );
1167
1168 if ( new_state & TDFX_NEW_FOG )
1169 tdfxUpdateFogAttrib( ctx );
1170
1171 if ( new_state & TDFX_NEW_CLIP )
1172 tdfxUpdateClipping( ctx );
1173
1174 if ( new_state & TDFX_NEW_STIPPLE )
1175 tdfxUpdateStipple( ctx );
1176
1177 if ( new_state & TDFX_NEW_CULL )
1178 tdfxUpdateCull( ctx );
1179
1180 if ( new_state & TDFX_NEW_LINE )
1181 tdfxUpdateLine( ctx );
1182
1183 if ( new_state & TDFX_NEW_VIEWPORT )
1184 tdfxUpdateViewport( ctx );
1185
1186 if ( new_state & TDFX_NEW_RENDER )
1187 tdfxUpdateRenderAttrib( ctx );
1188
1189 if ( new_state & TDFX_NEW_STENCIL )
1190 tdfxUpdateStencil( ctx );
1191
1192 if ( new_state & TDFX_NEW_TEXTURE ) {
1193 tdfxUpdateTextureState( ctx );
1194 }
1195 else if ( new_state & TDFX_NEW_TEXTURE_BIND ) {
1196 tdfxUpdateTextureBinding( ctx );
1197 }
1198 }
1199
1200 if ( 0 ) {
1201 FxI32 bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE);
1202
1203 if ( fxMesa->Depth.Bias != bias ) {
1204 fxMesa->Depth.Bias = bias;
1205 fxMesa->dirty |= TDFX_UPLOAD_DEPTH_BIAS;
1206 }
1207 }
1208
1209 if ( fxMesa->dirty ) {
1210 LOCK_HARDWARE( fxMesa );
1211 tdfxEmitHwStateLocked( fxMesa );
1212 UNLOCK_HARDWARE( fxMesa );
1213 }
1214 }
1215
1216
1217 static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state )
1218 {
1219 _swrast_InvalidateState( ctx, new_state );
1220 _swsetup_InvalidateState( ctx, new_state );
1221 _ac_InvalidateState( ctx, new_state );
1222 _tnl_InvalidateState( ctx, new_state );
1223 TDFX_CONTEXT(ctx)->new_gl_state |= new_state;
1224 }
1225
1226
1227
1228 /* Initialize the context's Glide state mirror. These values will be
1229 * used as Glide function call parameters when the time comes.
1230 */
1231 void tdfxInitState( tdfxContextPtr fxMesa )
1232 {
1233 GLcontext *ctx = fxMesa->glCtx;
1234 GLint i;
1235
1236 fxMesa->ColorCombine.Function = GR_COMBINE_FUNCTION_LOCAL;
1237 fxMesa->ColorCombine.Factor = GR_COMBINE_FACTOR_NONE;
1238 fxMesa->ColorCombine.Local = GR_COMBINE_LOCAL_ITERATED;
1239 fxMesa->ColorCombine.Other = GR_COMBINE_OTHER_NONE;
1240 fxMesa->ColorCombine.Invert = FXFALSE;
1241 fxMesa->AlphaCombine.Function = GR_COMBINE_FUNCTION_LOCAL;
1242 fxMesa->AlphaCombine.Factor = GR_COMBINE_FACTOR_NONE;
1243 fxMesa->AlphaCombine.Local = GR_COMBINE_LOCAL_ITERATED;
1244 fxMesa->AlphaCombine.Other = GR_COMBINE_OTHER_NONE;
1245 fxMesa->AlphaCombine.Invert = FXFALSE;
1246
1247 fxMesa->ColorCombineExt.SourceA = GR_CMBX_ITRGB;
1248 fxMesa->ColorCombineExt.ModeA = GR_FUNC_MODE_X;
1249 fxMesa->ColorCombineExt.SourceB = GR_CMBX_ZERO;
1250 fxMesa->ColorCombineExt.ModeB = GR_FUNC_MODE_ZERO;
1251 fxMesa->ColorCombineExt.SourceC = GR_CMBX_ZERO;
1252 fxMesa->ColorCombineExt.InvertC = FXTRUE;
1253 fxMesa->ColorCombineExt.SourceD = GR_CMBX_ZERO;
1254 fxMesa->ColorCombineExt.InvertD = FXFALSE;
1255 fxMesa->ColorCombineExt.Shift = 0;
1256 fxMesa->ColorCombineExt.Invert = FXFALSE;
1257 fxMesa->AlphaCombineExt.SourceA = GR_CMBX_ITALPHA;
1258 fxMesa->AlphaCombineExt.ModeA = GR_FUNC_MODE_X;
1259 fxMesa->AlphaCombineExt.SourceB = GR_CMBX_ZERO;
1260 fxMesa->AlphaCombineExt.ModeB = GR_FUNC_MODE_ZERO;
1261 fxMesa->AlphaCombineExt.SourceC = GR_CMBX_ZERO;
1262 fxMesa->AlphaCombineExt.InvertC = FXTRUE;
1263 fxMesa->AlphaCombineExt.SourceD = GR_CMBX_ZERO;
1264 fxMesa->AlphaCombineExt.InvertD = FXFALSE;
1265 fxMesa->AlphaCombineExt.Shift = 0;
1266 fxMesa->AlphaCombineExt.Invert = FXFALSE;
1267
1268 fxMesa->sScale0 = fxMesa->tScale0 = 1.0;
1269 fxMesa->sScale1 = fxMesa->tScale1 = 1.0;
1270
1271 fxMesa->TexPalette.Type = 0;
1272 fxMesa->TexPalette.Data = NULL;
1273
1274 for ( i = 0 ; i < TDFX_NUM_TMU ; i++ ) {
1275 fxMesa->TexSource[i].StartAddress = 0;
1276 fxMesa->TexSource[i].EvenOdd = GR_MIPMAPLEVELMASK_EVEN;
1277 fxMesa->TexSource[i].Info = NULL;
1278
1279 fxMesa->TexCombine[i].FunctionRGB = 0;
1280 fxMesa->TexCombine[i].FactorRGB = 0;
1281 fxMesa->TexCombine[i].FunctionAlpha = 0;
1282 fxMesa->TexCombine[i].FactorAlpha = 0;
1283 fxMesa->TexCombine[i].InvertRGB = FXFALSE;
1284 fxMesa->TexCombine[i].InvertAlpha = FXFALSE;
1285
1286 fxMesa->TexCombineExt[i].Alpha.SourceA = 0;
1287 /* XXX more state to init here */
1288 fxMesa->TexCombineExt[i].Color.SourceA = 0;
1289 fxMesa->TexCombineExt[i].EnvColor = 0x0;
1290
1291 fxMesa->TexParams[i].sClamp = GR_TEXTURECLAMP_WRAP;
1292 fxMesa->TexParams[i].tClamp = GR_TEXTURECLAMP_WRAP;
1293 fxMesa->TexParams[i].minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
1294 fxMesa->TexParams[i].magFilt = GR_TEXTUREFILTER_BILINEAR;
1295 fxMesa->TexParams[i].mmMode = GR_MIPMAP_DISABLE;
1296 fxMesa->TexParams[i].LODblend = FXFALSE;
1297 fxMesa->TexParams[i].LodBias = 0.0;
1298
1299 fxMesa->TexState.EnvMode[i] = ~0;
1300 fxMesa->TexState.TexFormat[i] = ~0;
1301 fxMesa->TexState.Enabled[i] = 0;
1302 }
1303
1304 if ( ctx->Visual.doubleBufferMode) {
1305 fxMesa->DrawBuffer = GR_BUFFER_BACKBUFFER;
1306 fxMesa->ReadBuffer = GR_BUFFER_BACKBUFFER;
1307 } else {
1308 fxMesa->DrawBuffer = GR_BUFFER_FRONTBUFFER;
1309 fxMesa->ReadBuffer = GR_BUFFER_FRONTBUFFER;
1310 }
1311
1312 fxMesa->Color.ClearColor = 0x00000000;
1313 fxMesa->Color.ClearAlpha = 0x00;
1314 fxMesa->Color.ColorMask[RCOMP] = FXTRUE;
1315 fxMesa->Color.ColorMask[BCOMP] = FXTRUE;
1316 fxMesa->Color.ColorMask[GCOMP] = FXTRUE;
1317 fxMesa->Color.ColorMask[ACOMP] = FXTRUE;
1318 fxMesa->Color.MonoColor = 0xffffffff;
1319
1320 fxMesa->Color.AlphaFunc = GR_CMP_ALWAYS;
1321 fxMesa->Color.AlphaRef = 0x00;
1322 fxMesa->Color.BlendSrcRGB = GR_BLEND_ONE;
1323 fxMesa->Color.BlendDstRGB = GR_BLEND_ZERO;
1324 fxMesa->Color.BlendSrcA = GR_BLEND_ONE;
1325 fxMesa->Color.BlendSrcA = GR_BLEND_ZERO;
1326
1327 fxMesa->Color.Dither = GR_DITHER_2x2;
1328
1329 if ( fxMesa->glCtx->Visual.depthBits > 0 ) {
1330 fxMesa->Depth.Mode = GR_DEPTHBUFFER_ZBUFFER;
1331 } else {
1332 fxMesa->Depth.Mode = GR_DEPTHBUFFER_DISABLE;
1333 }
1334 fxMesa->Depth.Bias = 0;
1335 fxMesa->Depth.Func = GR_CMP_LESS;
1336 fxMesa->Depth.Clear = 0; /* computed later */
1337 fxMesa->Depth.Mask = FXTRUE;
1338
1339
1340 fxMesa->Fog.Mode = GR_FOG_DISABLE;
1341 fxMesa->Fog.Color = 0x00000000;
1342 fxMesa->Fog.Table = NULL;
1343 fxMesa->Fog.Density = 1.0;
1344 fxMesa->Fog.Near = 1.0;
1345 fxMesa->Fog.Far = 1.0;
1346
1347 fxMesa->Stencil.Function = GR_CMP_ALWAYS;
1348 fxMesa->Stencil.RefValue = 0;
1349 fxMesa->Stencil.ValueMask = 0xff;
1350 fxMesa->Stencil.WriteMask = 0xff;
1351 fxMesa->Stencil.FailFunc = 0;
1352 fxMesa->Stencil.ZFailFunc = 0;
1353 fxMesa->Stencil.ZPassFunc = 0;
1354 fxMesa->Stencil.Clear = 0;
1355
1356 fxMesa->Stipple.Mode = GR_STIPPLE_DISABLE;
1357 fxMesa->Stipple.Pattern = 0xffffffff;
1358
1359 fxMesa->Scissor.minX = 0;
1360 fxMesa->Scissor.minY = 0;
1361 fxMesa->Scissor.maxX = 0;
1362 fxMesa->Scissor.maxY = 0;
1363
1364 fxMesa->Viewport.Mode = GR_WINDOW_COORDS;
1365 fxMesa->Viewport.X = 0;
1366 fxMesa->Viewport.Y = 0;
1367 fxMesa->Viewport.Width = 0;
1368 fxMesa->Viewport.Height = 0;
1369 fxMesa->Viewport.Near = 0.0;
1370 fxMesa->Viewport.Far = 0.0;
1371
1372 fxMesa->CullMode = GR_CULL_DISABLE;
1373
1374 fxMesa->Glide.ColorFormat = GR_COLORFORMAT_ABGR;
1375 fxMesa->Glide.Origin = GR_ORIGIN_LOWER_LEFT;
1376 fxMesa->Glide.Initialized = FXFALSE;
1377 }
1378
1379
1380
1381 void tdfxDDInitStateFuncs( GLcontext *ctx )
1382 {
1383 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1384
1385 ctx->Driver.UpdateState = tdfxDDInvalidateState;
1386
1387
1388 /* State notification callbacks:
1389 */
1390 ctx->Driver.ClearIndex = NULL;
1391 ctx->Driver.ClearColor = tdfxDDClearColor;
1392 ctx->Driver.DrawBuffer = tdfxDDDrawBuffer;
1393 ctx->Driver.ReadBuffer = tdfxDDReadBuffer;
1394
1395 ctx->Driver.IndexMask = NULL;
1396 ctx->Driver.ColorMask = tdfxDDColorMask;
1397
1398 ctx->Driver.AlphaFunc = tdfxDDAlphaFunc;
1399 ctx->Driver.BlendEquation = tdfxDDBlendEquation;
1400 ctx->Driver.BlendFunc = tdfxDDBlendFunc;
1401 ctx->Driver.BlendFuncSeparate = tdfxDDBlendFuncSeparate;
1402 ctx->Driver.ClearDepth = tdfxDDClearDepth;
1403 ctx->Driver.ClearStencil = NULL;
1404 ctx->Driver.CullFace = tdfxDDCullFace;
1405 ctx->Driver.FrontFace = tdfxDDFrontFace;
1406 ctx->Driver.DepthFunc = tdfxDDDepthFunc;
1407 ctx->Driver.DepthMask = tdfxDDDepthMask;
1408 ctx->Driver.DepthRange = tdfxDDDepthRange;
1409 ctx->Driver.Enable = tdfxDDEnable;
1410 ctx->Driver.Fogfv = tdfxDDFogfv;
1411 ctx->Driver.Hint = NULL;
1412 ctx->Driver.Lightfv = NULL;
1413 ctx->Driver.LightModelfv = tdfxDDLightModelfv;
1414 ctx->Driver.LineStipple = NULL;
1415 ctx->Driver.LineWidth = tdfxDDLineWidth;
1416 ctx->Driver.PolygonStipple = tdfxDDPolygonStipple;
1417 ctx->Driver.RenderMode = tdfxDDRenderMode;
1418 ctx->Driver.Scissor = tdfxDDScissor;
1419 ctx->Driver.ShadeModel = tdfxDDShadeModel;
1420
1421 ctx->Driver.BindTexture = tdfxDDBindTexture;
1422 ctx->Driver.DeleteTexture = tdfxDDDeleteTexture;
1423 ctx->Driver.TexEnv = tdfxDDTexEnv;
1424 ctx->Driver.TexParameter = tdfxDDTexParameter;
1425 ctx->Driver.ChooseTextureFormat = tdfxDDChooseTextureFormat;
1426 ctx->Driver.TexImage2D = tdfxDDTexImage2D;
1427 ctx->Driver.TexSubImage2D = tdfxDDTexSubImage2D;
1428 /*
1429 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1430 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
1431 */
1432
1433 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1434 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1435 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1436 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1437 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
1438 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
1439 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
1440 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
1441 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
1442 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1443
1444 /* ctx->Driver.GetTexImage = tdfxDDGetTexImage; */
1445 ctx->Driver.UpdateTexturePalette = tdfxDDTexturePalette;
1446
1447 if ( fxMesa->haveHwStencil ) {
1448 ctx->Driver.StencilFunc = tdfxDDStencilFunc;
1449 ctx->Driver.StencilMask = tdfxDDStencilMask;
1450 ctx->Driver.StencilOp = tdfxDDStencilOp;
1451 } else {
1452 ctx->Driver.StencilFunc = NULL;
1453 ctx->Driver.StencilMask = NULL;
1454 ctx->Driver.StencilOp = NULL;
1455 }
1456
1457 ctx->Driver.Viewport = tdfxDDViewport;
1458
1459
1460 /* Swrast hooks for imaging extensions:
1461 */
1462 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1463 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1464 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1465 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1466 }