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