1 /* -*- mode: c; c-basic-offset: 3 -*-
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
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:
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
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
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */
30 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
33 * Gareth Hughes <gareth@valinux.com>
34 * Brian Paul <brianp@valinux.com>
35 * Keith Whitwell <keith@tungstengraphics.com> (port to 3.5)
41 #include "texformat.h"
44 #include "swrast/swrast.h"
45 #include "array_cache/acache.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
50 #include "tdfx_context.h"
51 #include "tdfx_state.h"
54 #include "tdfx_texman.h"
55 #include "tdfx_texstate.h"
56 #include "tdfx_tris.h"
57 #include "tdfx_render.h"
61 /* =============================================================
65 static void tdfxUpdateAlphaMode( GLcontext
*ctx
)
67 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
69 GrAlphaBlendFnc_t srcRGB
, dstRGB
, srcA
, dstA
;
70 GrAlpha_t ref
= (GLint
) (ctx
->Color
.AlphaRef
* 255.0);
72 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
73 fprintf( stderr
, "%s()\n", __FUNCTION__
);
76 if ( ctx
->Color
.AlphaEnabled
) {
77 switch ( ctx
->Color
.AlphaFunc
) {
94 func
= GR_CMP_GREATER
;
97 func
= GR_CMP_NOTEQUAL
;
101 func
= GR_CMP_ALWAYS
;
105 func
= GR_CMP_ALWAYS
;
108 if ( ctx
->Color
.BlendEnabled
109 && (fxMesa
->Fallback
& TDFX_FALLBACK_BLEND
) == 0 ) {
110 switch ( ctx
->Color
.BlendSrcRGB
) {
112 srcRGB
= GR_BLEND_ZERO
;
115 srcRGB
= GR_BLEND_ONE
;
118 srcRGB
= GR_BLEND_DST_COLOR
;
120 case GL_ONE_MINUS_DST_COLOR
:
121 srcRGB
= GR_BLEND_ONE_MINUS_DST_COLOR
;
124 srcRGB
= GR_BLEND_SRC_ALPHA
;
126 case GL_ONE_MINUS_SRC_ALPHA
:
127 srcRGB
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
130 srcRGB
= GR_BLEND_DST_ALPHA
;
132 case GL_ONE_MINUS_DST_ALPHA
:
133 srcRGB
= GR_BLEND_ONE_MINUS_DST_ALPHA
;
135 case GL_SRC_ALPHA_SATURATE
:
136 srcRGB
= GR_BLEND_ALPHA_SATURATE
;
139 srcRGB
= GR_BLEND_ONE
;
142 switch ( ctx
->Color
.BlendSrcA
) {
144 srcA
= GR_BLEND_ZERO
;
150 srcA
= GR_BLEND_DST_ALPHA
; /* Napalm only */
152 case GL_ONE_MINUS_DST_COLOR
:
153 srcA
= GR_BLEND_ONE_MINUS_DST_ALPHA
; /* Napalm only */
156 srcA
= GR_BLEND_SRC_ALPHA
; /* Napalm only */
158 case GL_ONE_MINUS_SRC_ALPHA
:
159 srcA
= GR_BLEND_ONE_MINUS_SRC_ALPHA
; /* Napalm only */
162 srcA
= GR_BLEND_DST_ALPHA
; /* Napalm only */
164 case GL_ONE_MINUS_DST_ALPHA
:
165 srcA
= GR_BLEND_ONE_MINUS_DST_ALPHA
; /* Napalm only */
167 case GL_SRC_ALPHA_SATURATE
:
174 switch ( ctx
->Color
.BlendDstRGB
) {
176 dstRGB
= GR_BLEND_ZERO
;
179 dstRGB
= GR_BLEND_ONE
;
182 dstRGB
= GR_BLEND_SRC_COLOR
;
184 case GL_ONE_MINUS_SRC_COLOR
:
185 dstRGB
= GR_BLEND_ONE_MINUS_SRC_COLOR
;
188 dstRGB
= GR_BLEND_SRC_ALPHA
;
190 case GL_ONE_MINUS_SRC_ALPHA
:
191 dstRGB
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
194 dstRGB
= GR_BLEND_DST_ALPHA
;
196 case GL_ONE_MINUS_DST_ALPHA
:
197 dstRGB
= GR_BLEND_ONE_MINUS_DST_ALPHA
;
200 dstRGB
= GR_BLEND_ZERO
;
203 switch ( ctx
->Color
.BlendDstA
) {
205 dstA
= GR_BLEND_ZERO
;
211 dstA
= GR_BLEND_SRC_ALPHA
; /* Napalm only */
213 case GL_ONE_MINUS_SRC_COLOR
:
214 dstA
= GR_BLEND_ONE_MINUS_SRC_ALPHA
; /* Napalm only */
217 dstA
= GR_BLEND_SRC_ALPHA
; /* Napalm only */
219 case GL_ONE_MINUS_SRC_ALPHA
:
220 dstA
= GR_BLEND_ONE_MINUS_SRC_ALPHA
; /* Napalm only */
223 dstA
= GR_BLEND_DST_ALPHA
; /* Napalm only */
225 case GL_ONE_MINUS_DST_ALPHA
:
226 dstA
= GR_BLEND_ONE_MINUS_DST_ALPHA
; /* Napalm only */
229 dstA
= GR_BLEND_ZERO
;
233 srcRGB
= GR_BLEND_ONE
;
234 dstRGB
= GR_BLEND_ZERO
;
236 dstA
= GR_BLEND_ZERO
;
239 if ( fxMesa
->Color
.AlphaFunc
!= func
) {
240 fxMesa
->Color
.AlphaFunc
= func
;
241 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_TEST
;
243 if ( fxMesa
->Color
.AlphaRef
!= ref
) {
244 fxMesa
->Color
.AlphaRef
= ref
;
245 fxMesa
->dirty
|= TDFX_UPLOAD_ALPHA_REF
;
248 if ( fxMesa
->Color
.BlendSrcRGB
!= srcRGB
||
249 fxMesa
->Color
.BlendDstRGB
!= dstRGB
||
250 fxMesa
->Color
.BlendSrcA
!= srcA
||
251 fxMesa
->Color
.BlendDstA
!= dstA
)
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
;
261 static void tdfxDDAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
263 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
265 FLUSH_BATCH( fxMesa
);
266 fxMesa
->new_state
|= TDFX_NEW_ALPHA
;
269 static void tdfxDDBlendEquation( GLcontext
*ctx
, GLenum mode
)
271 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
273 FLUSH_BATCH( fxMesa
);
274 fxMesa
->new_state
|= TDFX_NEW_ALPHA
;
277 static void tdfxDDBlendFunc( GLcontext
*ctx
, GLenum sfactor
, GLenum dfactor
)
279 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
281 FLUSH_BATCH( fxMesa
);
282 fxMesa
->new_state
|= TDFX_NEW_ALPHA
;
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.
291 static void tdfxDDBlendFuncSeparate( GLcontext
*ctx
,
292 GLenum sfactorRGB
, GLenum dfactorRGB
,
293 GLenum sfactorA
, GLenum dfactorA
)
295 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
297 FLUSH_BATCH( fxMesa
);
298 fxMesa
->new_state
|= TDFX_NEW_ALPHA
;
301 /* =============================================================
305 void tdfxUpdateStipple( GLcontext
*ctx
)
307 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
308 GrStippleMode_t mode
= GR_STIPPLE_DISABLE
;
310 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
311 fprintf( stderr
, "%s()\n", __FUNCTION__
);
314 FLUSH_BATCH( fxMesa
);
316 if (ctx
->Polygon
.StippleFlag
) {
317 mode
= GR_STIPPLE_PATTERN
;
320 if ( fxMesa
->Stipple
.Mode
!= mode
) {
321 fxMesa
->Stipple
.Mode
= mode
;
322 fxMesa
->dirty
|= TDFX_UPLOAD_STIPPLE
;
327 /* =============================================================
331 static void tdfxUpdateZMode( GLcontext
*ctx
)
333 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
338 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
)
339 fprintf( stderr
, "%s()\n", __FUNCTION__
);
342 bias
= (FxI32
) (ctx
->Polygon
.OffsetUnits
* TDFX_DEPTH_BIAS_SCALE
);
344 if ( ctx
->Depth
.Test
) {
345 switch ( ctx
->Depth
.Func
) {
353 func
= GR_CMP_LEQUAL
;
359 func
= GR_CMP_GEQUAL
;
362 func
= GR_CMP_GREATER
;
365 func
= GR_CMP_NOTEQUAL
;
369 func
= GR_CMP_ALWAYS
;
373 if ( ctx
->Depth
.Mask
) {
381 /* depth testing disabled */
382 func
= GR_CMP_ALWAYS
; /* fragments always pass */
383 mask
= FXFALSE
; /* zbuffer is not touched */
386 fxMesa
->Depth
.Clear
= (FxU32
) (((1 << fxMesa
->glCtx
->Visual
.depthBits
) - 1)
389 if ( fxMesa
->Depth
.Bias
!= bias
) {
390 fxMesa
->Depth
.Bias
= bias
;
391 fxMesa
->dirty
|= TDFX_UPLOAD_DEPTH_BIAS
;
393 if ( fxMesa
->Depth
.Func
!= func
) {
394 fxMesa
->Depth
.Func
= func
;
395 fxMesa
->dirty
|= TDFX_UPLOAD_DEPTH_FUNC
| TDFX_UPLOAD_DEPTH_MASK
;
397 if ( fxMesa
->Depth
.Mask
!= mask
) {
398 fxMesa
->Depth
.Mask
= mask
;
399 fxMesa
->dirty
|= TDFX_UPLOAD_DEPTH_MASK
;
403 static void tdfxDDDepthFunc( GLcontext
*ctx
, GLenum func
)
405 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
407 FLUSH_BATCH( fxMesa
);
408 fxMesa
->new_state
|= TDFX_NEW_DEPTH
;
411 static void tdfxDDDepthMask( GLcontext
*ctx
, GLboolean flag
)
413 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
415 FLUSH_BATCH( fxMesa
);
416 fxMesa
->new_state
|= TDFX_NEW_DEPTH
;
419 static void tdfxDDClearDepth( GLcontext
*ctx
, GLclampd d
)
421 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
423 FLUSH_BATCH( fxMesa
);
424 fxMesa
->new_state
|= TDFX_NEW_DEPTH
;
429 /* =============================================================
434 /* Evaluate all stencil state and make the Glide calls.
436 static GrStencil_t
convertGLStencilOp( GLenum op
)
440 return GR_STENCILOP_KEEP
;
442 return GR_STENCILOP_ZERO
;
444 return GR_STENCILOP_REPLACE
;
446 return GR_STENCILOP_INCR_CLAMP
;
448 return GR_STENCILOP_DECR_CLAMP
;
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
;
456 _mesa_problem( NULL
, "bad stencil op in convertGLStencilOp" );
458 return GR_STENCILOP_KEEP
; /* never get, silence compiler warning */
462 static void tdfxUpdateStencil( GLcontext
*ctx
)
464 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
466 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
467 fprintf( stderr
, "%s()\n", __FUNCTION__
);
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;
481 fxMesa
->dirty
|= TDFX_UPLOAD_STENCIL
;
486 static void tdfxDDStencilFunc( GLcontext
*ctx
, GLenum func
,
487 GLint ref
, GLuint mask
)
489 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
491 FLUSH_BATCH( fxMesa
);
492 fxMesa
->new_state
|= TDFX_NEW_STENCIL
;
495 static void tdfxDDStencilMask( GLcontext
*ctx
, GLuint mask
)
497 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
499 FLUSH_BATCH( fxMesa
);
500 fxMesa
->new_state
|= TDFX_NEW_STENCIL
;
503 static void tdfxDDStencilOp( GLcontext
*ctx
, GLenum sfail
,
504 GLenum zfail
, GLenum zpass
)
506 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
508 FLUSH_BATCH( fxMesa
);
509 fxMesa
->new_state
|= TDFX_NEW_STENCIL
;
513 /* =============================================================
514 * Fog - orthographic fog still not working
517 static void tdfxUpdateFogAttrib( GLcontext
*ctx
)
519 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
523 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
524 fprintf( stderr
, "%s()\n", __FUNCTION__
);
527 if ( ctx
->Fog
.Enabled
) {
528 mode
= GR_FOG_WITH_TABLE_ON_Q
;
530 mode
= GR_FOG_DISABLE
;
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
));
537 if ( fxMesa
->Fog
.Mode
!= mode
) {
538 fxMesa
->Fog
.Mode
= mode
;
539 fxMesa
->dirty
|= TDFX_UPLOAD_FOG_MODE
;
541 if ( fxMesa
->Fog
.Color
!= color
) {
542 fxMesa
->Fog
.Color
= color
;
543 fxMesa
->dirty
|= TDFX_UPLOAD_FOG_COLOR
;
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
)
550 switch( ctx
->Fog
.Mode
) {
552 fxMesa
->Glide
.guFogGenerateExp( fxMesa
->Fog
.Table
, ctx
->Fog
.Density
);
555 fxMesa
->Glide
.guFogGenerateExp2( fxMesa
->Fog
.Table
, ctx
->Fog
.Density
);
558 fxMesa
->Glide
.guFogGenerateLinear( fxMesa
->Fog
.Table
,
559 ctx
->Fog
.Start
, ctx
->Fog
.End
);
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
;
571 static void tdfxDDFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
573 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
575 FLUSH_BATCH( fxMesa
);
576 fxMesa
->new_state
|= TDFX_NEW_FOG
;
580 /* =============================================================
584 static int intersect_rect( XF86DRIClipRectPtr out
,
585 const XF86DRIClipRectPtr a
,
586 const XF86DRIClipRectPtr b
)
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;
600 * Examine XF86 cliprect list and scissor state to recompute our
603 void tdfxUpdateClipping( GLcontext
*ctx
)
605 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
606 __DRIdrawablePrivate
*dPriv
= fxMesa
->driDrawable
;
608 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
609 fprintf( stderr
, "%s()\n", __FUNCTION__
);
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
;
623 fxMesa
->screen_height
- fxMesa
->y_offset
- fxMesa
->height
;
624 tdfxUpdateViewport( ctx
);
627 if (fxMesa
->scissoredClipRects
&& fxMesa
->pClipRects
) {
628 free(fxMesa
->pClipRects
);
631 if (ctx
->Scissor
.Enabled
) {
632 /* intersect OpenGL scissor box with all cliprects to make a new
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);
646 assert(scissor
.x2
>= scissor
.x1
);
647 assert(scissor
.y2
>= scissor
.y1
);
649 fxMesa
->pClipRects
= malloc(dPriv
->numClipRects
650 * sizeof(XF86DRIClipRectRec
));
651 if (fxMesa
->pClipRects
) {
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
++;
660 fxMesa
->scissoredClipRects
= GL_TRUE
;
663 /* out of memory, forgo scissor */
664 fxMesa
->numClipRects
= dPriv
->numClipRects
;
665 fxMesa
->pClipRects
= dPriv
->pClipRects
;
666 fxMesa
->scissoredClipRects
= GL_FALSE
;
670 fxMesa
->numClipRects
= dPriv
->numClipRects
;
671 fxMesa
->pClipRects
= dPriv
->pClipRects
;
672 fxMesa
->scissoredClipRects
= GL_FALSE
;
675 fxMesa
->dirty
|= TDFX_UPLOAD_CLIP
;
680 /* =============================================================
684 void tdfxUpdateCull( GLcontext
*ctx
)
686 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
687 GrCullMode_t mode
= GR_CULL_DISABLE
;
689 /* KW: don't need to check raster_primitive here as we don't
690 * attempt to draw lines or points with triangles.
692 if ( ctx
->Polygon
.CullFlag
) {
693 switch ( ctx
->Polygon
.CullFaceMode
) {
695 if ( ctx
->Polygon
.FrontFace
== GL_CCW
) {
696 mode
= GR_CULL_POSITIVE
;
698 mode
= GR_CULL_NEGATIVE
;
703 if ( ctx
->Polygon
.FrontFace
== GL_CCW
) {
704 mode
= GR_CULL_NEGATIVE
;
706 mode
= GR_CULL_POSITIVE
;
710 case GL_FRONT_AND_BACK
:
711 /* Handled as a fallback on triangles in tdfx_tris.c */
720 if ( fxMesa
->CullMode
!= mode
) {
721 fxMesa
->CullMode
= mode
;
722 fxMesa
->dirty
|= TDFX_UPLOAD_CULL
;
726 static void tdfxDDCullFace( GLcontext
*ctx
, GLenum mode
)
728 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
730 FLUSH_BATCH( fxMesa
);
731 fxMesa
->new_state
|= TDFX_NEW_CULL
;
734 static void tdfxDDFrontFace( GLcontext
*ctx
, GLenum mode
)
736 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
738 FLUSH_BATCH( fxMesa
);
739 fxMesa
->new_state
|= TDFX_NEW_CULL
;
743 /* =============================================================
747 static void tdfxUpdateLine( GLcontext
*ctx
)
749 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
751 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
752 fprintf( stderr
, "%s()\n", __FUNCTION__
);
755 FLUSH_BATCH( fxMesa
);
756 fxMesa
->dirty
|= TDFX_UPLOAD_LINE
;
760 static void tdfxDDLineWidth( GLcontext
*ctx
, GLfloat width
)
762 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
763 FLUSH_BATCH( fxMesa
);
764 fxMesa
->new_state
|= TDFX_NEW_LINE
;
768 /* =============================================================
772 static void tdfxDDColorMask( GLcontext
*ctx
,
773 GLboolean r
, GLboolean g
,
774 GLboolean b
, GLboolean a
)
776 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
778 FLUSH_BATCH( fxMesa
);
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
;
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
) );
799 static void tdfxDDClearColor( GLcontext
*ctx
,
800 const GLfloat color
[4] )
802 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
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];
814 /* =============================================================
818 static void tdfxDDLightModelfv( GLcontext
*ctx
, GLenum pname
,
819 const GLfloat
*param
)
821 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
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
));
830 static void tdfxDDShadeModel( GLcontext
*ctx
, GLenum mode
)
832 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
834 /* FIXME: Can we implement native flat shading? */
835 FLUSH_BATCH( fxMesa
);
836 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
840 /* =============================================================
845 tdfxDDScissor(GLcontext
* ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
847 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
848 FLUSH_BATCH( fxMesa
);
849 fxMesa
->new_state
|= TDFX_NEW_CLIP
;
852 /* =============================================================
856 static void tdfxUpdateRenderAttrib( GLcontext
*ctx
)
858 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
859 FLUSH_BATCH( fxMesa
);
860 fxMesa
->dirty
|= TDFX_UPLOAD_RENDER_BUFFER
;
863 /* =============================================================
867 void tdfxUpdateViewport( GLcontext
*ctx
)
869 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
870 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
871 GLfloat
*m
= fxMesa
->hw_viewport
;
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
];
880 fxMesa
->SetupNewInputs
|= VERT_BIT_CLIP
;
884 static void tdfxDDViewport( GLcontext
*ctx
, GLint x
, GLint y
,
885 GLsizei w
, GLsizei h
)
887 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
888 FLUSH_BATCH( fxMesa
);
889 fxMesa
->new_state
|= TDFX_NEW_VIEWPORT
;
893 static void tdfxDDDepthRange( GLcontext
*ctx
, GLclampd nearVal
, GLclampd farVal
)
895 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
896 FLUSH_BATCH( fxMesa
);
897 fxMesa
->new_state
|= TDFX_NEW_VIEWPORT
;
901 /* =============================================================
902 * State enable/disable
905 static void tdfxDDEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
907 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
911 FLUSH_BATCH( fxMesa
);
912 fxMesa
->new_state
|= TDFX_NEW_ALPHA
;
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
));
924 FLUSH_BATCH( fxMesa
);
925 fxMesa
->new_state
|= TDFX_NEW_CULL
;
929 FLUSH_BATCH( fxMesa
);
930 fxMesa
->new_state
|= TDFX_NEW_DEPTH
;
934 FLUSH_BATCH( fxMesa
);
936 fxMesa
->Color
.Dither
= GR_DITHER_2x2
;
938 fxMesa
->Color
.Dither
= GR_DITHER_DISABLE
;
940 fxMesa
->dirty
|= TDFX_UPLOAD_DITHER
;
944 FLUSH_BATCH( fxMesa
);
945 fxMesa
->new_state
|= TDFX_NEW_FOG
;
948 case GL_COLOR_LOGIC_OP
:
949 FALLBACK( fxMesa
, TDFX_FALLBACK_LOGICOP
,
950 (ctx
->Color
.ColorLogicOpEnabled
&&
951 ctx
->Color
.LogicOp
!= GL_COPY
));
955 FALLBACK( fxMesa
, TDFX_FALLBACK_SPECULAR
,
956 (ctx
->Light
.Enabled
&&
957 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
));
961 FLUSH_BATCH( fxMesa
);
962 fxMesa
->new_state
|= TDFX_NEW_LINE
;
965 case GL_LINE_STIPPLE
:
966 FALLBACK(fxMesa
, TDFX_FALLBACK_LINE_STIPPLE
, state
);
969 case GL_POLYGON_STIPPLE
:
971 fxMesa
->new_state
|= TDFX_NEW_STIPPLE
;
974 case GL_SCISSOR_TEST
:
975 FLUSH_BATCH( fxMesa
);
976 fxMesa
->new_state
|= TDFX_NEW_CLIP
;
979 case GL_STENCIL_TEST
:
980 FLUSH_BATCH( fxMesa
);
981 FALLBACK( fxMesa
, TDFX_FALLBACK_STENCIL
, state
&& !fxMesa
->haveHwStencil
);
986 FLUSH_BATCH( fxMesa
);
987 FALLBACK( fxMesa
, TDFX_FALLBACK_TEXTURE_1D_3D
, state
); /* wrong */
988 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
992 FLUSH_BATCH( fxMesa
);
993 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
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
)
1007 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1009 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
1010 fprintf( stderr
, "%s()\n", __FUNCTION__
);
1013 FLUSH_BATCH( fxMesa
);
1016 * _DrawDestMask is easier to cope with than <mode>.
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
);
1025 fxMesa
->DrawBuffer
= fxMesa
->ReadBuffer
= GR_BUFFER_BACKBUFFER
;
1026 fxMesa
->new_state
|= TDFX_NEW_RENDER
;
1027 FALLBACK( fxMesa
, TDFX_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1030 FX_grColorMaskv( ctx
, false4
);
1031 FALLBACK( fxMesa
, TDFX_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
1034 FALLBACK( fxMesa
, TDFX_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
1038 /* We want to update the s/w rast state too so that tdfxDDSetBuffer()
1041 _swrast_DrawBuffer(ctx
, mode
);
1045 static void tdfxDDReadBuffer( GLcontext
*ctx
, GLenum mode
)
1051 /* =============================================================
1055 static void tdfxDDPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
1057 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1058 const GLubyte
*m
= mask
;
1061 GLboolean allBitsSet
;
1063 /* int active = (ctx->Polygon.StippleFlag && */
1064 /* fxMesa->reduced_prim == GL_TRIANGLES); */
1066 FLUSH_BATCH(fxMesa
);
1067 fxMesa
->Stipple
.Pattern
= 0xffffffff;
1068 fxMesa
->dirty
|= TDFX_UPLOAD_STIPPLE
;
1069 fxMesa
->new_state
|= TDFX_NEW_STIPPLE
;
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
1075 allBitsSet
= GL_TRUE
;
1076 for (i
= 0; i
< 32; i
++) {
1077 if (((GLuint
*) mask
)[i
] != 0xffffffff) {
1078 allBitsSet
= GL_FALSE
;
1083 fxMesa
->haveHwStipple
= GL_FALSE
;
1092 for (k
= 0 ; k
< 8 ; k
++)
1093 for (j
= 0 ; j
< 4; j
++)
1094 for (i
= 0 ; i
< 4 ; i
++,m
++) {
1096 fxMesa
->haveHwStipple
= GL_FALSE
;
1101 fxMesa
->haveHwStipple
= GL_TRUE
;
1102 fxMesa
->Stipple
.Pattern
= ( (q
[0] << 0) |
1110 static void tdfxDDRenderMode( GLcontext
*ctx
, GLenum mode
)
1112 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1113 FALLBACK( fxMesa
, TDFX_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
1118 static void tdfxDDPrintState( const char *msg
, GLuint flags
)
1121 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s\n",
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, " : "");
1141 void tdfxDDUpdateHwState( GLcontext
*ctx
)
1143 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1144 int new_state
= fxMesa
->new_state
;
1146 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
1147 fprintf( stderr
, "%s()\n", __FUNCTION__
);
1152 FLUSH_BATCH( fxMesa
);
1154 fxMesa
->new_state
= 0;
1157 tdfxDDPrintState( "tdfxUpdateHwState", new_state
);
1159 /* Update the various parts of the context's state.
1161 if ( new_state
& TDFX_NEW_ALPHA
) {
1162 tdfxUpdateAlphaMode( ctx
);
1165 if ( new_state
& TDFX_NEW_DEPTH
)
1166 tdfxUpdateZMode( ctx
);
1168 if ( new_state
& TDFX_NEW_FOG
)
1169 tdfxUpdateFogAttrib( ctx
);
1171 if ( new_state
& TDFX_NEW_CLIP
)
1172 tdfxUpdateClipping( ctx
);
1174 if ( new_state
& TDFX_NEW_STIPPLE
)
1175 tdfxUpdateStipple( ctx
);
1177 if ( new_state
& TDFX_NEW_CULL
)
1178 tdfxUpdateCull( ctx
);
1180 if ( new_state
& TDFX_NEW_LINE
)
1181 tdfxUpdateLine( ctx
);
1183 if ( new_state
& TDFX_NEW_VIEWPORT
)
1184 tdfxUpdateViewport( ctx
);
1186 if ( new_state
& TDFX_NEW_RENDER
)
1187 tdfxUpdateRenderAttrib( ctx
);
1189 if ( new_state
& TDFX_NEW_STENCIL
)
1190 tdfxUpdateStencil( ctx
);
1192 if ( new_state
& TDFX_NEW_TEXTURE
) {
1193 tdfxUpdateTextureState( ctx
);
1195 else if ( new_state
& TDFX_NEW_TEXTURE_BIND
) {
1196 tdfxUpdateTextureBinding( ctx
);
1201 FxI32 bias
= (FxI32
) (ctx
->Polygon
.OffsetUnits
* TDFX_DEPTH_BIAS_SCALE
);
1203 if ( fxMesa
->Depth
.Bias
!= bias
) {
1204 fxMesa
->Depth
.Bias
= bias
;
1205 fxMesa
->dirty
|= TDFX_UPLOAD_DEPTH_BIAS
;
1209 if ( fxMesa
->dirty
) {
1210 LOCK_HARDWARE( fxMesa
);
1211 tdfxEmitHwStateLocked( fxMesa
);
1212 UNLOCK_HARDWARE( fxMesa
);
1217 static void tdfxDDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
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
;
1228 /* Initialize the context's Glide state mirror. These values will be
1229 * used as Glide function call parameters when the time comes.
1231 void tdfxInitState( tdfxContextPtr fxMesa
)
1233 GLcontext
*ctx
= fxMesa
->glCtx
;
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
;
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
;
1268 fxMesa
->sScale0
= fxMesa
->tScale0
= 1.0;
1269 fxMesa
->sScale1
= fxMesa
->tScale1
= 1.0;
1271 fxMesa
->TexPalette
.Type
= 0;
1272 fxMesa
->TexPalette
.Data
= NULL
;
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
;
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
;
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;
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;
1299 fxMesa
->TexState
.EnvMode
[i
] = ~0;
1300 fxMesa
->TexState
.TexFormat
[i
] = ~0;
1301 fxMesa
->TexState
.Enabled
[i
] = 0;
1304 if ( ctx
->Visual
.doubleBufferMode
) {
1305 fxMesa
->DrawBuffer
= GR_BUFFER_BACKBUFFER
;
1306 fxMesa
->ReadBuffer
= GR_BUFFER_BACKBUFFER
;
1308 fxMesa
->DrawBuffer
= GR_BUFFER_FRONTBUFFER
;
1309 fxMesa
->ReadBuffer
= GR_BUFFER_FRONTBUFFER
;
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;
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
;
1327 fxMesa
->Color
.Dither
= GR_DITHER_2x2
;
1329 if ( fxMesa
->glCtx
->Visual
.depthBits
> 0 ) {
1330 fxMesa
->Depth
.Mode
= GR_DEPTHBUFFER_ZBUFFER
;
1332 fxMesa
->Depth
.Mode
= GR_DEPTHBUFFER_DISABLE
;
1334 fxMesa
->Depth
.Bias
= 0;
1335 fxMesa
->Depth
.Func
= GR_CMP_LESS
;
1336 fxMesa
->Depth
.Clear
= 0; /* computed later */
1337 fxMesa
->Depth
.Mask
= FXTRUE
;
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;
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;
1356 fxMesa
->Stipple
.Mode
= GR_STIPPLE_DISABLE
;
1357 fxMesa
->Stipple
.Pattern
= 0xffffffff;
1359 fxMesa
->Scissor
.minX
= 0;
1360 fxMesa
->Scissor
.minY
= 0;
1361 fxMesa
->Scissor
.maxX
= 0;
1362 fxMesa
->Scissor
.maxY
= 0;
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;
1372 fxMesa
->CullMode
= GR_CULL_DISABLE
;
1374 fxMesa
->Glide
.ColorFormat
= GR_COLORFORMAT_ABGR
;
1375 fxMesa
->Glide
.Origin
= GR_ORIGIN_LOWER_LEFT
;
1376 fxMesa
->Glide
.Initialized
= FXFALSE
;
1381 void tdfxDDInitStateFuncs( GLcontext
*ctx
)
1383 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1385 ctx
->Driver
.UpdateState
= tdfxDDInvalidateState
;
1388 /* State notification callbacks:
1390 ctx
->Driver
.ClearIndex
= NULL
;
1391 ctx
->Driver
.ClearColor
= tdfxDDClearColor
;
1392 ctx
->Driver
.DrawBuffer
= tdfxDDDrawBuffer
;
1393 ctx
->Driver
.ReadBuffer
= tdfxDDReadBuffer
;
1395 ctx
->Driver
.IndexMask
= NULL
;
1396 ctx
->Driver
.ColorMask
= tdfxDDColorMask
;
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
;
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
;
1429 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1430 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
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
;
1444 /* ctx->Driver.GetTexImage = tdfxDDGetTexImage; */
1445 ctx
->Driver
.UpdateTexturePalette
= tdfxDDTexturePalette
;
1447 if ( fxMesa
->haveHwStencil
) {
1448 ctx
->Driver
.StencilFunc
= tdfxDDStencilFunc
;
1449 ctx
->Driver
.StencilMask
= tdfxDDStencilMask
;
1450 ctx
->Driver
.StencilOp
= tdfxDDStencilOp
;
1452 ctx
->Driver
.StencilFunc
= NULL
;
1453 ctx
->Driver
.StencilMask
= NULL
;
1454 ctx
->Driver
.StencilOp
= NULL
;
1457 ctx
->Driver
.Viewport
= tdfxDDViewport
;
1460 /* Swrast hooks for imaging extensions:
1462 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1463 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1464 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1465 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;