1 /* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
30 * Thank you for your contribution, David!
32 * Please make note of the above copyright/license statement. If you
33 * contributed code or bug fixes to this code under the previous (GNU
34 * Library) license and object to the new license, your code will be
35 * removed at your request. Please see the Mesa docs/COPYRIGHT file
36 * for more information.
38 * Additional Mesa/3Dfx driver developers:
39 * Daryll Strauss <daryll@precisioninsight.com>
40 * Keith Whitwell <keith@precisioninsight.com>
42 * See fxapi.h for more revision/author details.
46 /* fxdd.c - 3Dfx VooDoo Mesa device driver functions */
58 #include "extensions.h"
61 /* These lookup table are used to extract RGB values in [0,255] from
62 * 16-bit pixel values.
64 GLubyte FX_PixelToR
[0x10000];
65 GLubyte FX_PixelToG
[0x10000];
66 GLubyte FX_PixelToB
[0x10000];
70 * Initialize the FX_PixelTo{RGB} arrays.
71 * Input: bgrOrder - if TRUE, pixels are in BGR order, else RGB order.
73 void fxInitPixelTables(GLboolean bgrOrder
)
76 for (pixel
= 0; pixel
<= 0xffff; pixel
++) {
79 r
= (pixel
& 0x001F) << 3;
80 g
= (pixel
& 0x07E0) >> 3;
81 b
= (pixel
& 0xF800) >> 8;
84 r
= (pixel
& 0xF800) >> 8;
85 g
= (pixel
& 0x07E0) >> 3;
86 b
= (pixel
& 0x001F) << 3;
88 r
= r
* 255 / 0xF8; /* fill in low-order bits */
91 FX_PixelToR
[pixel
] = r
;
92 FX_PixelToG
[pixel
] = g
;
93 FX_PixelToB
[pixel
] = b
;
98 /**********************************************************************/
99 /***** Miscellaneous functions *****/
100 /**********************************************************************/
102 /* Enalbe/Disable dithering */
103 void fxDDDither(GLcontext
*ctx
, GLboolean enable
)
105 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
106 fprintf(stderr
,"fxmesa: fxDDDither()\n");
110 FX_grDitherMode(GR_DITHER_4x4
);
112 FX_grDitherMode(GR_DITHER_DISABLE
);
117 /* Return buffer size information */
118 void fxDDBufferSize(GLcontext
*ctx
, GLuint
*width
, GLuint
*height
)
120 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
122 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
123 fprintf(stderr
,"fxmesa: fxDDBufferSize(...) Start\n");
126 *width
=fxMesa
->width
;
127 *height
=fxMesa
->height
;
129 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
130 fprintf(stderr
,"fxmesa: fxDDBufferSize(...) End\n");
135 /* Set current drawing color */
136 static void fxDDSetColor(GLcontext
*ctx
, GLubyte red
, GLubyte green
,
137 GLubyte blue
, GLubyte alpha
)
139 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
141 ASSIGN_4V( col
, red
, green
, blue
, alpha
);
143 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
144 fprintf(stderr
,"fxmesa: fxDDSetColor(%d,%d,%d,%d)\n",red
,green
,blue
,alpha
);
147 fxMesa
->color
=FXCOLOR4(col
);
151 /* Implements glClearColor() */
152 static void fxDDClearColor(GLcontext
*ctx
, GLubyte red
, GLubyte green
,
153 GLubyte blue
, GLubyte alpha
)
155 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
160 ASSIGN_4V( col
, red
, green
, blue
, 255 );
162 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
163 fprintf(stderr
,"fxmesa: fxDDClearColor(%d,%d,%d,%d)\n",red
,green
,blue
,alpha
);
166 fxMesa
->clearC
=FXCOLOR4( col
);
167 fxMesa
->clearA
=alpha
;
170 /* Clear the color and/or depth buffers */
171 static GLbitfield
fxDDClear(GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
172 GLint x
, GLint y
, GLint width
, GLint height
)
174 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
177 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
178 fprintf(stderr
,"fxmesa: fxDDClear(%d,%d,%d,%d)\n",x
,y
,width
,height
);
181 switch(mask
& (GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT
)) {
182 case (GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT
):
183 /* clear color and depth buffer */
185 if (ctx
->Color
.DrawDestMask
& BACK_LEFT_BIT
) {
186 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
187 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
,
188 (FxU16
)(ctx
->Depth
.Clear
*0xffff));
190 if (ctx
->Color
.DrawDestMask
& FRONT_LEFT_BIT
) {
191 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
192 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
,
193 (FxU16
)(ctx
->Depth
.Clear
*0xffff));
196 newmask
=mask
& (~(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT
));
198 case (GL_COLOR_BUFFER_BIT
):
199 /* clear color buffer */
201 if(ctx
->Color
.ColorMask
) {
202 FX_grDepthMask(FXFALSE
);
204 if (ctx
->Color
.DrawDestMask
& BACK_LEFT_BIT
) {
205 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
206 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, 0);
208 if (ctx
->Color
.DrawDestMask
& FRONT_LEFT_BIT
) {
209 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
210 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, 0);
213 if(ctx
->Depth
.Mask
) {
214 FX_grDepthMask(FXTRUE
);
218 newmask
=mask
& (~(GL_COLOR_BUFFER_BIT
));
220 case (GL_DEPTH_BUFFER_BIT
):
221 /* clear depth buffer */
223 if(ctx
->Depth
.Mask
) {
224 FX_grColorMask(FXFALSE
,FXFALSE
);
225 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
,
226 (FxU16
)(ctx
->Depth
.Clear
*0xffff));
228 FX_grColorMask(ctx
->Color
.ColorMask
[RCOMP
] ||
229 ctx
->Color
.ColorMask
[GCOMP
] ||
230 ctx
->Color
.ColorMask
[BCOMP
],
231 ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveAlphaBuffer
);
234 newmask
=mask
& (~(GL_DEPTH_BUFFER_BIT
));
245 /* Set the buffer used for drawing */
246 /* XXX support for separate read/draw buffers hasn't been tested */
247 static GLboolean
fxDDSetDrawBuffer(GLcontext
*ctx
, GLenum mode
)
249 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
251 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
252 fprintf(stderr
,"fxmesa: fxDDSetBuffer(%x)\n",mode
);
255 if (mode
== GL_FRONT_LEFT
) {
256 fxMesa
->currentFB
= GR_BUFFER_FRONTBUFFER
;
257 FX_grRenderBuffer(fxMesa
->currentFB
);
260 else if (mode
== GL_BACK_LEFT
) {
261 fxMesa
->currentFB
= GR_BUFFER_BACKBUFFER
;
262 FX_grRenderBuffer(fxMesa
->currentFB
);
271 /* Set the buffer used for reading */
272 /* XXX support for separate read/draw buffers hasn't been tested */
273 static void fxDDSetReadBuffer(GLcontext
*ctx
, GLframebuffer
*buffer
,
276 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
279 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
280 fprintf(stderr
,"fxmesa: fxDDSetBuffer(%x)\n",mode
);
283 if (mode
== GL_FRONT_LEFT
) {
284 fxMesa
->currentFB
= GR_BUFFER_FRONTBUFFER
;
285 FX_grRenderBuffer(fxMesa
->currentFB
);
287 else if (mode
== GL_BACK_LEFT
) {
288 fxMesa
->currentFB
= GR_BUFFER_BACKBUFFER
;
289 FX_grRenderBuffer(fxMesa
->currentFB
);
295 static GLboolean
inClipRects(fxMesaContext fxMesa
, int px
, int py
)
299 py
=fxMesa
->height
+fxMesa
->y_offset
-py
;
300 for (i
=0; i
<fxMesa
->numClipRects
; i
++) {
301 if ((px
>=fxMesa
->pClipRects
[i
].x1
) &&
302 (px
<fxMesa
->pClipRects
[i
].x2
) &&
303 (py
>=fxMesa
->pClipRects
[i
].y1
) &&
304 (py
<fxMesa
->pClipRects
[i
].y2
)) return GL_TRUE
;
311 static GLboolean
fxDDDrawBitMap(GLcontext
*ctx
, GLint px
, GLint py
,
312 GLsizei width
, GLsizei height
,
313 const struct gl_pixelstore_attrib
*unpack
,
314 const GLubyte
*bitmap
)
316 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
320 int x
,y
,xmin
,xmax
,ymin
,ymax
;
321 GLint r
,g
,b
,a
,scrwidth
,scrheight
,stride
;
324 /* TODO: with a little work, these bitmap unpacking parameter restrictions
327 if((unpack
->Alignment
!=1) ||
328 (unpack
->RowLength
!=0) ||
329 (unpack
->SkipPixels
!=0) ||
330 (unpack
->SkipRows
!=0) ||
331 (unpack
->SwapBytes
) ||
335 if (ctx
->Scissor
.Enabled
) {
337 xmax
=ctx
->Scissor
.X
+ctx
->Scissor
.Width
;
339 ymax
=ctx
->Scissor
.Y
+ctx
->Scissor
.Height
;
347 xmin
+=fxMesa
->x_offset
;
348 xmax
+=fxMesa
->x_offset
;
351 #define ISCLIPPED(rx, ry) ( ((rx)<xmin) || ((rx)>=xmax) || !inClipRects(fxMesa, rx, ry))
353 #define ISCLIPPED(rx, ry) ( ((rx)<xmin) || ((rx)>=xmax) )
355 #define DRAWBIT(i) { \
356 if(!ISCLIPPED(x+px, y)) \
357 if( (*pb) & (1<<(i)) ) \
367 scrwidth
=fxMesa
->width
;
368 scrheight
=fxMesa
->height
;
370 if ((px
>=scrwidth
) || (px
+width
<=0) || (py
>=scrheight
) || (py
+height
<=0))
376 pb
+=(height
*(-py
)) >> (3+1);
381 if (py
+height
>=scrheight
)
382 height
-=(py
+height
)-scrheight
;
384 info
.size
=sizeof(info
);
385 if(!FX_grLfbLock(GR_LFB_WRITE_ONLY
,
388 GR_ORIGIN_UPPER_LEFT
,
392 fprintf(stderr
,"fx Driver: error locking the linear frame buffer\n");
397 r
=(GLint
)(ctx
->Current
.RasterColor
[0]*255.0f
);
398 g
=(GLint
)(ctx
->Current
.RasterColor
[1]*255.0f
);
399 b
=(GLint
)(ctx
->Current
.RasterColor
[2]*255.0f
);
400 a
=(GLint
)(ctx
->Current
.RasterColor
[3]*255.0f
);
402 ( ((FxU16
)0xf8 & b
) <<(11-3)) |
403 ( ((FxU16
)0xfc & g
) <<(5-3+1)) |
404 ( ((FxU16
)0xf8 & r
) >> 3);
406 stride
=info
.strideInBytes
>>1;
408 /* This code is a bit slow... */
410 if (py
>ymin
) ymin
=py
;
411 if (py
+height
<ymax
) ymax
=py
+height
;
413 px
+=fxMesa
->x_offset
;
414 scrheight
=fxMesa
->height
+fxMesa
->y_offset
;
416 for(y
=ymin
; y
<ymax
; y
++) {
418 p
=((FxU16
*)info
.lfbPtr
)+px
+((scrheight
-y
)*stride
);
421 DRAWBIT(7); DRAWBIT(6); DRAWBIT(5); DRAWBIT(4);
422 DRAWBIT(3); DRAWBIT(2); DRAWBIT(1); DRAWBIT(0);
427 FX_grLfbUnlock(GR_LFB_WRITE_ONLY
,fxMesa
->currentFB
);
435 static void fxDDFinish(GLcontext
*ctx
)
441 static GLint
fxDDGetParameteri(const GLcontext
*ctx
, GLint param
)
444 case DD_HAVE_HARDWARE_FOG
:
447 fprintf(stderr
,"fx Driver: internal error in fxDDGetParameteri(): %x\n",param
);
455 void fxDDSetNearFar(GLcontext
*ctx
, GLfloat n
, GLfloat f
)
457 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_FOG
;
458 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
461 /* KW: Put the word Mesa in the render string because quakeworld
462 * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE).
465 static const GLubyte
*fxDDGetString(GLcontext
*ctx
, GLenum name
)
469 #if defined(GLX_DIRECT_RENDERING)
470 return "Mesa Glide - DRI VB/V3";
475 if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
==GR_SSTTYPE_VOODOO
)
477 GrVoodooConfig_t
*vc
=
478 &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
;
481 "Mesa Glide v0.30 Voodoo_Graphics %d "
482 "CARD/%d FB/%d TM/%d TMU/%s",
484 (vc
->sliDetect
? (vc
->fbRam
*2) : vc
->fbRam
),
485 (vc
->tmuConfig
[GR_TMU0
].tmuRam
+
486 ((vc
->nTexelfx
>1) ? vc
->tmuConfig
[GR_TMU1
].tmuRam
: 0)),
488 (vc
->sliDetect
? "SLI" : "NOSLI"));
490 else if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
==GR_SSTTYPE_SST96
)
492 GrSst96Config_t
*sc
=
493 &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.SST96Config
;
496 "Glide v0.30 Voodoo_Rush %d "
497 "CARD/%d FB/%d TM/%d TMU/NOSLI",
500 sc
->tmuConfig
.tmuRam
,
505 strcpy(buf
, "Glide v0.30 UNKNOWN");
508 return (GLubyte
*) buf
;
517 int fxDDInitFxMesaContext( fxMesaContext fxMesa
)
520 FX_setupGrVertexLayout();
522 if (getenv("FX_EMULATE_SINGLE_TMU"))
523 fxMesa
->haveTwoTMUs
= GL_FALSE
;
525 fxMesa
->emulateTwoTMUs
= fxMesa
->haveTwoTMUs
;
527 if (!getenv("FX_DONT_FAKE_MULTITEX"))
528 fxMesa
->emulateTwoTMUs
= GL_TRUE
;
530 if(getenv("FX_GLIDE_SWAPINTERVAL"))
531 fxMesa
->swapInterval
=atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
533 fxMesa
->swapInterval
=1;
535 if(getenv("MESA_FX_SWAP_PENDING"))
536 fxMesa
->maxPendingSwapBuffers
=atoi(getenv("MESA_FX_SWAP_PENDING"));
538 fxMesa
->maxPendingSwapBuffers
=2;
540 fxMesa
->color
=0xffffffff;
544 fxMesa
->stats
.swapBuffer
=0;
545 fxMesa
->stats
.reqTexUpload
=0;
546 fxMesa
->stats
.texUpload
=0;
547 fxMesa
->stats
.memTexUpload
=0;
549 fxMesa
->tmuSrc
=FX_TMU_NONE
;
550 fxMesa
->lastUnitsMode
=FX_UM_NONE
;
555 fxMesa
->unitsState
.alphaTestEnabled
=GL_FALSE
;
556 fxMesa
->unitsState
.alphaTestFunc
=GR_CMP_ALWAYS
;
557 fxMesa
->unitsState
.alphaTestRefValue
=0;
559 fxMesa
->unitsState
.blendEnabled
=GL_FALSE
;
560 fxMesa
->unitsState
.blendSrcFuncRGB
=GR_BLEND_ONE
;
561 fxMesa
->unitsState
.blendDstFuncRGB
=GR_BLEND_ZERO
;
562 fxMesa
->unitsState
.blendSrcFuncAlpha
=GR_BLEND_ONE
;
563 fxMesa
->unitsState
.blendDstFuncAlpha
=GR_BLEND_ZERO
;
565 fxMesa
->unitsState
.depthTestEnabled
=GL_FALSE
;
566 fxMesa
->unitsState
.depthMask
=GL_TRUE
;
567 fxMesa
->unitsState
.depthTestFunc
=GR_CMP_LESS
;
569 FX_grColorMask(FXTRUE
, fxMesa
->haveAlphaBuffer
? FXTRUE
: FXFALSE
);
570 if(fxMesa
->haveDoubleBuffer
) {
571 fxMesa
->currentFB
=GR_BUFFER_BACKBUFFER
;
572 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
574 fxMesa
->currentFB
=GR_BUFFER_FRONTBUFFER
;
575 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
578 fxMesa
->state
= NULL
;
579 fxMesa
->fogTable
= NULL
;
581 fxMesa
->state
= malloc(FX_grGetInteger(FX_GLIDE_STATE_SIZE
));
582 fxMesa
->fogTable
= malloc(FX_grGetInteger(FX_FOG_TABLE_ENTRIES
)*sizeof(GrFog_t
));
584 if (!fxMesa
->state
|| !fxMesa
->fogTable
) {
585 if (fxMesa
->state
) free(fxMesa
->state
);
586 if (fxMesa
->fogTable
) free(fxMesa
->fogTable
);
590 if(fxMesa
->haveZBuffer
)
591 FX_grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER
);
593 #if (!FXMESA_USE_ARGB)
594 FX_grLfbWriteColorFormat(GR_COLORFORMAT_ABGR
); /* Not every Glide has this */
597 fxMesa
->glCtx
->Const
.MaxTextureLevels
=9;
598 fxMesa
->glCtx
->Const
.MaxTextureSize
=256;
599 fxMesa
->glCtx
->Const
.MaxTextureUnits
=fxMesa
->emulateTwoTMUs
? 2 : 1;
600 fxMesa
->glCtx
->NewState
|=NEW_DRVSTATE1
;
601 fxMesa
->new_state
= NEW_ALL
;
609 fxSetupDDPointers(fxMesa
->glCtx
);
610 fxDDRenderInit(fxMesa
->glCtx
);
611 fxDDInitExtensions(fxMesa
->glCtx
);
613 fxDDSetNearFar(fxMesa
->glCtx
,1.0,100.0);
615 FX_grGlideGetState((GrState
*)fxMesa
->state
);
617 /* XXX Fix me: callback not registered when main VB is created.
619 if (fxMesa
->glCtx
->VB
)
620 fxDDRegisterVB( fxMesa
->glCtx
->VB
);
622 /* XXX Fix me too: need to have the 'struct dd' prepared prior to
623 * creating the context... The below is broken if you try to insert
626 if (fxMesa
->glCtx
->NrPipelineStages
)
627 fxMesa
->glCtx
->NrPipelineStages
= fxDDRegisterPipelineStages(
628 fxMesa
->glCtx
->PipelineStage
,
629 fxMesa
->glCtx
->PipelineStage
,
630 fxMesa
->glCtx
->NrPipelineStages
);
632 /* Run the config file */
633 gl_context_initialize( fxMesa
->glCtx
);
642 void fxDDInitExtensions( GLcontext
*ctx
)
644 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
646 gl_extensions_add( ctx
, DEFAULT_ON
, "3DFX_set_global_palette", 0 );
647 gl_extensions_add( ctx
, DEFAULT_ON
, "GL_FXMESA_global_texture_lod_bias", 0);
649 if(fxMesa
->haveTwoTMUs
)
650 gl_extensions_add( ctx
, DEFAULT_ON
, "GL_EXT_texture_env_add", 0);
652 if (!fxMesa
->emulateTwoTMUs
)
653 gl_extensions_disable( ctx
, "GL_ARB_multitexture" );
657 This driver may need to move the drawing operations to a different sub
658 window. This modifies the viewport command to add our X,Y offset to all
659 drawn objects that go through the viewport transformation.
662 /************************************************************************/
663 /************************************************************************/
664 /************************************************************************/
666 /* This is a no-op, since the z-buffer is in hardware */
667 static void fxAllocDepthBuffer(GLcontext
*ctx
)
669 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
670 fprintf(stderr
,"fxmesa: fxAllocDepthBuffer()\n");
674 /************************************************************************/
675 /************************************************************************/
676 /************************************************************************/
678 /* Check if the hardware supports the current context
680 * Performs similar work to fxDDChooseRenderState() - should be merged.
682 static GLboolean
fxIsInHardware(GLcontext
*ctx
)
684 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
686 if (!ctx
->Hint
.AllowDrawMem
)
687 return GL_TRUE
; /* you'll take it and like it */
689 if((ctx
->RasterMask
& STENCIL_BIT
) ||
690 ((ctx
->Color
.BlendEnabled
) && (ctx
->Color
.BlendEquation
!=GL_FUNC_ADD_EXT
)) ||
691 ((ctx
->Color
.ColorLogicOpEnabled
) && (ctx
->Color
.LogicOp
!=GL_COPY
)) ||
692 (ctx
->Light
.Model
.ColorControl
==GL_SEPARATE_SPECULAR_COLOR
) ||
693 (!((ctx
->Color
.ColorMask
[RCOMP
]==ctx
->Color
.ColorMask
[GCOMP
]) &&
694 (ctx
->Color
.ColorMask
[GCOMP
]==ctx
->Color
.ColorMask
[BCOMP
]) &&
695 (ctx
->Color
.ColorMask
[ACOMP
]==ctx
->Color
.ColorMask
[ACOMP
])))
700 /* Unsupported texture/multitexture cases */
702 if(fxMesa
->emulateTwoTMUs
) {
703 if((ctx
->Enabled
& (TEXTURE0_3D
| TEXTURE1_3D
)) ||
704 /* Not very well written ... */
705 ((ctx
->Enabled
& (TEXTURE0_1D
| TEXTURE1_1D
)) &&
706 ((ctx
->Enabled
& (TEXTURE0_2D
| TEXTURE1_2D
))!=(TEXTURE0_2D
| TEXTURE1_2D
)))
711 if((ctx
->Texture
.ReallyEnabled
& TEXTURE0_2D
) &&
712 (ctx
->Texture
.Unit
[0].EnvMode
==GL_BLEND
)) {
716 if((ctx
->Texture
.ReallyEnabled
& TEXTURE1_2D
) &&
717 (ctx
->Texture
.Unit
[1].EnvMode
==GL_BLEND
)) {
722 if (MESA_VERBOSE
& (VERBOSE_DRIVER
|VERBOSE_TEXTURE
))
723 fprintf(stderr
, "fxMesa: fxIsInHardware, envmode is %s/%s\n",
724 gl_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
725 gl_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
727 /* KW: This was wrong (I think) and I changed it... which doesn't mean
728 * it is now correct...
730 if((ctx
->Enabled
& (TEXTURE0_1D
| TEXTURE0_2D
| TEXTURE0_3D
)) &&
731 (ctx
->Enabled
& (TEXTURE1_1D
| TEXTURE1_2D
| TEXTURE1_3D
)))
733 /* Can't use multipass to blend a multitextured triangle - fall
736 if (!fxMesa
->haveTwoTMUs
&& ctx
->Color
.BlendEnabled
) {
740 if ((ctx
->Texture
.Unit
[0].EnvMode
!=ctx
->Texture
.Unit
[1].EnvMode
) &&
741 (ctx
->Texture
.Unit
[0].EnvMode
!=GL_MODULATE
) &&
742 (ctx
->Texture
.Unit
[0].EnvMode
!=GL_REPLACE
)) /* q2, seems ok... */
744 if (MESA_VERBOSE
&VERBOSE_DRIVER
)
745 fprintf(stderr
, "fxMesa: unsupported multitex env mode\n");
750 if((ctx
->Enabled
& (TEXTURE1_1D
| TEXTURE1_2D
| TEXTURE1_3D
)) ||
751 /* Not very well written ... */
752 ((ctx
->Enabled
& TEXTURE0_1D
) &&
753 (!(ctx
->Enabled
& TEXTURE0_2D
)))
759 if((ctx
->Texture
.ReallyEnabled
& TEXTURE0_2D
) &&
760 (ctx
->Texture
.Unit
[0].EnvMode
==GL_BLEND
)) {
770 #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|NEW_PROJECTION|NEW_TEXTURE_MATRIX|NEW_USER_CLIP|NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE))
772 static void fxDDUpdateDDPointers(GLcontext
*ctx
)
774 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
775 GLuint new_state
= ctx
->NewState
;
777 if (MESA_VERBOSE
&(VERBOSE_DRIVER
|VERBOSE_STATE
))
778 fprintf(stderr
,"fxmesa: fxDDUpdateDDPointers(...)\n");
780 if (new_state
& (NEW_RASTER_OPS
|NEW_TEXTURING
))
781 fxMesa
->is_in_hardware
= fxIsInHardware(ctx
);
783 if (fxMesa
->is_in_hardware
) {
784 if (fxMesa
->new_state
)
787 if(new_state
& INTERESTED
) {
788 fxDDChooseRenderState( ctx
);
789 fxMesa
->RenderVBTables
=fxDDChooseRenderVBTables(ctx
);
790 fxMesa
->RenderVBClippedTab
=fxMesa
->RenderVBTables
[0];
791 fxMesa
->RenderVBCulledTab
=fxMesa
->RenderVBTables
[1];
792 fxMesa
->RenderVBRawTab
=fxMesa
->RenderVBTables
[2];
794 ctx
->Driver
.RasterSetup
=fxDDChooseSetupFunction(ctx
);
797 ctx
->Driver
.PointsFunc
=fxMesa
->PointsFunc
;
798 ctx
->Driver
.LineFunc
=fxMesa
->LineFunc
;
799 ctx
->Driver
.TriangleFunc
=fxMesa
->TriangleFunc
;
800 ctx
->Driver
.QuadFunc
=fxMesa
->QuadFunc
;
802 fxMesa
->render_index
= FX_FALLBACK
;
806 void fxSetupDDPointers(GLcontext
*ctx
)
808 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
809 fprintf(stderr
,"fxmesa: fxSetupDDPointers()\n");
812 ctx
->Driver
.UpdateState
=fxDDUpdateDDPointers
;
814 ctx
->Driver
.WriteDepthSpan
=fxDDWriteDepthSpan
;
815 ctx
->Driver
.WriteDepthPixels
=fxDDWriteDepthPixels
;
816 ctx
->Driver
.ReadDepthSpan
=fxDDReadDepthSpan
;
817 ctx
->Driver
.ReadDepthPixels
=fxDDReadDepthPixels
;
819 ctx
->Driver
.GetString
=fxDDGetString
;
821 ctx
->Driver
.Dither
=fxDDDither
;
823 ctx
->Driver
.NearFar
=fxDDSetNearFar
;
825 ctx
->Driver
.GetParameteri
=fxDDGetParameteri
;
827 ctx
->Driver
.ClearIndex
=NULL
;
828 ctx
->Driver
.ClearColor
=fxDDClearColor
;
829 ctx
->Driver
.Clear
=fxDDClear
;
831 ctx
->Driver
.Index
=NULL
;
832 ctx
->Driver
.Color
=fxDDSetColor
;
834 ctx
->Driver
.SetDrawBuffer
=fxDDSetDrawBuffer
;
835 ctx
->Driver
.SetReadBuffer
=fxDDSetReadBuffer
;
836 ctx
->Driver
.GetBufferSize
=fxDDBufferSize
;
838 ctx
->Driver
.Bitmap
=fxDDDrawBitMap
;
839 ctx
->Driver
.DrawPixels
=NULL
;
841 ctx
->Driver
.Finish
=fxDDFinish
;
842 ctx
->Driver
.Flush
=NULL
;
844 ctx
->Driver
.RenderStart
=NULL
;
845 ctx
->Driver
.RenderFinish
=NULL
;
847 ctx
->Driver
.TexEnv
=fxDDTexEnv
;
848 ctx
->Driver
.TexImage
=fxDDTexImg
;
849 ctx
->Driver
.TexSubImage
=fxDDTexSubImg
;
850 ctx
->Driver
.TexParameter
=fxDDTexParam
;
851 ctx
->Driver
.BindTexture
=fxDDTexBind
;
852 ctx
->Driver
.DeleteTexture
=fxDDTexDel
;
853 ctx
->Driver
.UpdateTexturePalette
=fxDDTexPalette
;
854 ctx
->Driver
.UseGlobalTexturePalette
=fxDDTexUseGlbPalette
;
856 ctx
->Driver
.RectFunc
=NULL
;
858 ctx
->Driver
.AlphaFunc
=fxDDAlphaFunc
;
859 ctx
->Driver
.BlendFunc
=fxDDBlendFunc
;
860 ctx
->Driver
.DepthFunc
=fxDDDepthFunc
;
861 ctx
->Driver
.DepthMask
=fxDDDepthMask
;
862 ctx
->Driver
.ColorMask
=fxDDColorMask
;
863 ctx
->Driver
.Fogfv
=fxDDFogfv
;
864 ctx
->Driver
.Scissor
=fxDDScissor
;
865 ctx
->Driver
.FrontFace
=fxDDFrontFace
;
866 ctx
->Driver
.CullFace
=fxDDCullFace
;
867 ctx
->Driver
.ShadeModel
=fxDDShadeModel
;
868 ctx
->Driver
.Enable
=fxDDEnable
;
870 ctx
->Driver
.RegisterVB
=fxDDRegisterVB
;
871 ctx
->Driver
.UnregisterVB
=fxDDUnregisterVB
;
873 ctx
->Driver
.RegisterPipelineStages
= fxDDRegisterPipelineStages
;
875 ctx
->Driver
.OptimizeImmediatePipeline
= 0; /* nothing done yet */
876 ctx
->Driver
.OptimizePrecalcPipeline
= 0;
878 /* if (getenv("MESA_USE_FAST") || getenv("FX_USE_FAST")) */
879 /* ctx->Driver.OptimizePrecalcPipeline = fxDDOptimizePrecalcPipeline; */
881 if (!getenv("FX_NO_FAST"))
882 ctx
->Driver
.BuildPrecalcPipeline
= fxDDBuildPrecalcPipeline
;
884 ctx
->Driver
.TriangleCaps
= DD_TRI_CULL
|DD_TRI_OFFSET
|DD_TRI_LIGHT_TWOSIDE
;
886 fxSetupDDSpanPointers(ctx
);
888 FX_CONTEXT(ctx
)->render_index
= 1; /* force an update */
889 fxDDUpdateDDPointers(ctx
);
897 * Need this to provide at least one external definition.
900 int gl_fx_dummy_function_dd(void)