3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
29 * Thank you for your contribution, David!
31 * Please make note of the above copyright/license statement. If you
32 * contributed code or bug fixes to this code under the previous (GNU
33 * Library) license and object to the new license, your code will be
34 * removed at your request. Please see the Mesa docs/COPYRIGHT file
35 * for more information.
37 * Additional Mesa/3Dfx driver developers:
38 * Daryll Strauss <daryll@precisioninsight.com>
39 * Keith Whitwell <keith@precisioninsight.com>
41 * See fxapi.h for more revision/author details.
45 /* fxdd.c - 3Dfx VooDoo Mesa device driver functions */
58 #include "extensions.h"
59 #include "swrast/swrast.h"
60 #include "swrast_setup/swrast_setup.h"
62 /* These lookup table are used to extract RGB values in [0,255] from
63 * 16-bit pixel values.
65 GLubyte FX_PixelToR
[0x10000];
66 GLubyte FX_PixelToG
[0x10000];
67 GLubyte FX_PixelToB
[0x10000];
71 * Initialize the FX_PixelTo{RGB} arrays.
72 * Input: bgrOrder - if TRUE, pixels are in BGR order, else RGB order.
74 void fxInitPixelTables(fxMesaContext fxMesa
, GLboolean bgrOrder
)
78 fxMesa
->bgrOrder
=bgrOrder
;
79 for (pixel
= 0; pixel
<= 0xffff; pixel
++) {
82 r
= (pixel
& 0x001F) << 3;
83 g
= (pixel
& 0x07E0) >> 3;
84 b
= (pixel
& 0xF800) >> 8;
87 r
= (pixel
& 0xF800) >> 8;
88 g
= (pixel
& 0x07E0) >> 3;
89 b
= (pixel
& 0x001F) << 3;
91 r
= r
* 255 / 0xF8; /* fill in low-order bits */
94 FX_PixelToR
[pixel
] = r
;
95 FX_PixelToG
[pixel
] = g
;
96 FX_PixelToB
[pixel
] = b
;
101 /**********************************************************************/
102 /***** Miscellaneous functions *****/
103 /**********************************************************************/
105 /* Return buffer size information */
106 static void fxDDBufferSize(GLcontext
*ctx
, GLuint
*width
, GLuint
*height
)
108 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
110 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
111 fprintf(stderr
,"fxmesa: fxDDBufferSize(...) Start\n");
114 *width
=fxMesa
->width
;
115 *height
=fxMesa
->height
;
117 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
118 fprintf(stderr
,"fxmesa: fxDDBufferSize(...) End\n");
123 /* Set current drawing color */
124 static void fxDDSetColor(GLcontext
*ctx
, GLubyte red
, GLubyte green
,
125 GLubyte blue
, GLubyte alpha
)
127 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
129 ASSIGN_4V( col
, red
, green
, blue
, alpha
);
131 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
132 fprintf(stderr
,"fxmesa: fxDDSetColor(%d,%d,%d,%d)\n",red
,green
,blue
,alpha
);
135 fxMesa
->color
=FXCOLOR4(col
);
139 /* Implements glClearColor() */
140 static void fxDDClearColor(GLcontext
*ctx
, GLubyte red
, GLubyte green
,
141 GLubyte blue
, GLubyte alpha
)
143 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
148 ASSIGN_4V( col
, red
, green
, blue
, 255 );
150 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
151 fprintf(stderr
,"fxmesa: fxDDClearColor(%d,%d,%d,%d)\n",red
,green
,blue
,alpha
);
154 fxMesa
->clearC
=FXCOLOR4( col
);
155 fxMesa
->clearA
=alpha
;
159 /* Clear the color and/or depth buffers */
160 static GLbitfield
fxDDClear(GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
161 GLint x
, GLint y
, GLint width
, GLint height
)
163 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
164 const GLuint colorMask
= *((GLuint
*) &ctx
->Color
.ColorMask
);
165 const FxU16 clearD
= (FxU16
) (ctx
->Depth
.Clear
* 0xffff);
166 GLbitfield softwareMask
= mask
& (DD_STENCIL_BIT
| DD_ACCUM_BIT
);
168 /* we can't clear stencil or accum buffers */
169 mask
&= ~(DD_STENCIL_BIT
| DD_ACCUM_BIT
);
171 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
172 fprintf(stderr
,"fxmesa: fxDDClear(%d,%d,%d,%d)\n", (int) x
, (int) y
,
173 (int) width
, (int) height
);
176 if (colorMask
!= 0xffffffff) {
177 /* do masked color buffer clears in software */
178 softwareMask
|= (mask
& (DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
));
179 mask
&= ~(DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
);
183 * This could probably be done fancier but doing each possible case
184 * explicitly is less error prone.
187 case DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
:
188 /* back buffer & depth */
189 FX_grDepthMask(FXTRUE
);
190 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
191 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
192 if (!ctx
->Depth
.Mask
) {
193 FX_grDepthMask(FXFALSE
);
196 case DD_FRONT_LEFT_BIT
| DD_DEPTH_BIT
:
197 /* XXX it appears that the depth buffer isn't cleared when
198 * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
199 * This is a work-around/
202 FX_grDepthMask(FXTRUE
);
203 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
204 FX_grColorMask(FXFALSE
,FXFALSE
);
205 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
207 FX_grColorMask(FXTRUE
, ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveAlphaBuffer
);
208 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
209 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
211 case DD_BACK_LEFT_BIT
:
212 /* back buffer only */
213 FX_grDepthMask(FXFALSE
);
214 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
215 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
216 if (ctx
->Depth
.Mask
) {
217 FX_grDepthMask(FXTRUE
);
220 case DD_FRONT_LEFT_BIT
:
221 /* front buffer only */
222 FX_grDepthMask(FXFALSE
);
223 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
224 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
225 if (ctx
->Depth
.Mask
) {
226 FX_grDepthMask(FXTRUE
);
229 case DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
:
231 FX_grDepthMask(FXFALSE
);
232 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
233 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
234 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
235 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
236 if (ctx
->Depth
.Mask
) {
237 FX_grDepthMask(FXTRUE
);
240 case DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
:
242 FX_grDepthMask(FXFALSE
);
243 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
244 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
245 /* clear back and depth */
246 FX_grDepthMask(FXTRUE
);
247 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
248 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
249 if (!ctx
->Depth
.Mask
) {
250 FX_grDepthMask(FXFALSE
);
254 /* just the depth buffer */
255 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
256 FX_grColorMask(FXFALSE
,FXFALSE
);
257 FX_grDepthMask(FXTRUE
);
258 FX_grBufferClear(fxMesa
->clearC
, fxMesa
->clearA
, clearD
);
259 FX_grColorMask(FXTRUE
, ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveAlphaBuffer
);
260 if (ctx
->Color
.DrawDestMask
& FRONT_LEFT_BIT
)
261 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
262 if (!ctx
->Depth
.Test
|| !ctx
->Depth
.Mask
)
263 FX_grDepthMask(FXFALSE
);
274 /* Set the buffer used for drawing */
275 /* XXX support for separate read/draw buffers hasn't been tested */
276 static GLboolean
fxDDSetDrawBuffer(GLcontext
*ctx
, GLenum mode
)
278 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
280 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
281 fprintf(stderr
,"fxmesa: fxDDSetBuffer(%x)\n", (int) mode
);
284 if (mode
== GL_FRONT_LEFT
) {
285 fxMesa
->currentFB
= GR_BUFFER_FRONTBUFFER
;
286 FX_grRenderBuffer(fxMesa
->currentFB
);
289 else if (mode
== GL_BACK_LEFT
) {
290 fxMesa
->currentFB
= GR_BUFFER_BACKBUFFER
;
291 FX_grRenderBuffer(fxMesa
->currentFB
);
294 else if (mode
== GL_NONE
) {
295 FX_grColorMask(FXFALSE
,FXFALSE
);
304 /* Set the buffer used for reading */
305 /* XXX support for separate read/draw buffers hasn't been tested */
306 static void fxDDSetReadBuffer(GLcontext
*ctx
, GLframebuffer
*buffer
,
309 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
312 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
313 fprintf(stderr
,"fxmesa: fxDDSetBuffer(%x)\n", (int) mode
);
316 if (mode
== GL_FRONT_LEFT
) {
317 fxMesa
->currentFB
= GR_BUFFER_FRONTBUFFER
;
318 FX_grRenderBuffer(fxMesa
->currentFB
);
320 else if (mode
== GL_BACK_LEFT
) {
321 fxMesa
->currentFB
= GR_BUFFER_BACKBUFFER
;
322 FX_grRenderBuffer(fxMesa
->currentFB
);
328 static GLboolean
fxDDDrawBitmap(GLcontext
*ctx
, GLint px
, GLint py
,
329 GLsizei width
, GLsizei height
,
330 const struct gl_pixelstore_attrib
*unpack
,
331 const GLubyte
*bitmap
)
333 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
336 const struct gl_pixelstore_attrib
*finalUnpack
;
337 struct gl_pixelstore_attrib scissoredUnpack
;
339 /* check if there's any raster operations enabled which we can't handle */
340 if (ctx
->Color
.AlphaEnabled
||
341 ctx
->Color
.BlendEnabled
||
344 ctx
->Color
.ColorLogicOpEnabled
||
345 ctx
->Stencil
.Enabled
||
346 ctx
->Scissor
.Enabled
||
347 ( ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
&&
348 ctx
->Color
.ColorMask
[ACOMP
]) ||
349 ctx
->Color
.MultiDrawBuffer
)
353 if (ctx
->Scissor
.Enabled
) {
354 /* This is a bit tricky, but by carefully adjusting the px, py,
355 * width, height, skipPixels and skipRows values we can do
356 * scissoring without special code in the rendering loop.
358 * KW: This code is never reached, see the test above.
361 /* we'll construct a new pixelstore struct */
362 finalUnpack
= &scissoredUnpack
;
363 scissoredUnpack
= *unpack
;
364 if (scissoredUnpack
.RowLength
== 0)
365 scissoredUnpack
.RowLength
= width
;
368 if (px
< ctx
->Scissor
.X
) {
369 scissoredUnpack
.SkipPixels
+= (ctx
->Scissor
.X
- px
);
370 width
-= (ctx
->Scissor
.X
- px
);
374 if (px
+ width
>= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
) {
375 width
-= (px
+ width
- (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
));
378 if (py
< ctx
->Scissor
.Y
) {
379 scissoredUnpack
.SkipRows
+= (ctx
->Scissor
.Y
- py
);
380 height
-= (ctx
->Scissor
.Y
- py
);
384 if (py
+ height
>= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
) {
385 height
-= (py
+ height
- (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
));
388 if (width
<= 0 || height
<= 0)
389 return GL_TRUE
; /* totally scissored away */
392 finalUnpack
= unpack
;
395 /* compute pixel value */
397 GLint r
= (GLint
) (ctx
->Current
.RasterColor
[0] * 255.0f
);
398 GLint g
= (GLint
) (ctx
->Current
.RasterColor
[1] * 255.0f
);
399 GLint b
= (GLint
) (ctx
->Current
.RasterColor
[2] * 255.0f
);
400 /*GLint a = (GLint)(ctx->Current.RasterColor[3]*255.0f);*/
401 if (fxMesa
->bgrOrder
)
403 ( ((FxU16
)0xf8 & b
) << (11-3)) |
404 ( ((FxU16
)0xfc & g
) << (5-3+1)) |
405 ( ((FxU16
)0xf8 & r
) >> 3);
408 ( ((FxU16
)0xf8 & r
) << (11-3)) |
409 ( ((FxU16
)0xfc & g
) << (5-3+1)) |
410 ( ((FxU16
)0xf8 & b
) >> 3);
413 info
.size
= sizeof(info
);
414 if (!FX_grLfbLock(GR_LFB_WRITE_ONLY
,
417 GR_ORIGIN_UPPER_LEFT
,
421 fprintf(stderr
,"fx Driver: error locking the linear frame buffer\n");
427 const GLint winX
= 0;
428 const GLint winY
= fxMesa
->height
- 1;
429 /* The dest stride depends on the hardware and whether we're drawing
430 * to the front or back buffer. This compile-time test seems to do
433 const GLint dstStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
436 /* compute dest address of bottom-left pixel in bitmap */
437 GLushort
*dst
= (GLushort
*) info
.lfbPtr
438 + (winY
- py
) * dstStride
441 for (row
= 0; row
< height
; row
++) {
442 const GLubyte
*src
= (const GLubyte
*) _mesa_image_address( finalUnpack
,
443 bitmap
, width
, height
, GL_COLOR_INDEX
, GL_BITMAP
, 0, row
, 0 );
444 if (finalUnpack
->LsbFirst
) {
445 /* least significan bit first */
446 GLubyte mask
= 1U << (finalUnpack
->SkipPixels
& 0x7);
448 for (col
=0; col
<width
; col
++) {
464 /* most significan bit first */
465 GLubyte mask
= 128U >> (finalUnpack
->SkipPixels
& 0x7);
467 for (col
=0; col
<width
; col
++) {
486 FX_grLfbUnlock(GR_LFB_WRITE_ONLY
,fxMesa
->currentFB
);
491 static GLboolean
fxDDReadPixels( GLcontext
*ctx
, GLint x
, GLint y
,
492 GLsizei width
, GLsizei height
,
493 GLenum format
, GLenum type
,
494 const struct gl_pixelstore_attrib
*packing
,
497 if (ctx
->_ImageTransferState
) {
498 return GL_FALSE
; /* can't do this */
501 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
503 GLboolean result
= GL_FALSE
;
506 if (grLfbLock(GR_LFB_READ_ONLY
,
509 GR_ORIGIN_UPPER_LEFT
,
512 const GLint winX
= 0;
513 const GLint winY
= fxMesa
->height
- 1;
514 const GLint srcStride
= info
.strideInBytes
/ 2; /* stride in GLushorts */
515 const GLushort
*src
= (const GLushort
*) info
.lfbPtr
516 + (winY
- y
) * srcStride
+ (winX
+ x
);
517 GLubyte
*dst
= (GLubyte
*) _mesa_image_address(packing
, dstImage
,
518 width
, height
, format
, type
, 0, 0, 0);
519 GLint dstStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
521 if (format
== GL_RGB
&& type
== GL_UNSIGNED_BYTE
) {
522 /* convert 5R6G5B into 8R8G8B */
524 const GLint halfWidth
= width
>> 1;
525 const GLint extraPixel
= (width
& 1);
526 for (row
= 0; row
< height
; row
++) {
528 for (col
= 0; col
< halfWidth
; col
++) {
529 const GLuint pixel
= ((const GLuint
*) src
)[col
];
530 const GLint pixel0
= pixel
& 0xffff;
531 const GLint pixel1
= pixel
>> 16;
532 *d
++ = FX_PixelToR
[pixel0
];
533 *d
++ = FX_PixelToG
[pixel0
];
534 *d
++ = FX_PixelToB
[pixel0
];
535 *d
++ = FX_PixelToR
[pixel1
];
536 *d
++ = FX_PixelToG
[pixel1
];
537 *d
++ = FX_PixelToB
[pixel1
];
540 GLushort pixel
= src
[width
-1];
541 *d
++ = FX_PixelToR
[pixel
];
542 *d
++ = FX_PixelToG
[pixel
];
543 *d
++ = FX_PixelToB
[pixel
];
550 else if (format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) {
551 /* convert 5R6G5B into 8R8G8B8A */
553 const GLint halfWidth
= width
>> 1;
554 const GLint extraPixel
= (width
& 1);
555 for (row
= 0; row
< height
; row
++) {
557 for (col
= 0; col
< halfWidth
; col
++) {
558 const GLuint pixel
= ((const GLuint
*) src
)[col
];
559 const GLint pixel0
= pixel
& 0xffff;
560 const GLint pixel1
= pixel
>> 16;
561 *d
++ = FX_PixelToR
[pixel0
];
562 *d
++ = FX_PixelToG
[pixel0
];
563 *d
++ = FX_PixelToB
[pixel0
];
565 *d
++ = FX_PixelToR
[pixel1
];
566 *d
++ = FX_PixelToG
[pixel1
];
567 *d
++ = FX_PixelToB
[pixel1
];
571 const GLushort pixel
= src
[width
-1];
572 *d
++ = FX_PixelToR
[pixel
];
573 *d
++ = FX_PixelToG
[pixel
];
574 *d
++ = FX_PixelToB
[pixel
];
582 else if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
583 /* directly memcpy 5R6G5B pixels into client's buffer */
584 const GLint widthInBytes
= width
* 2;
586 for (row
= 0; row
< height
; row
++) {
587 MEMCPY(dst
, src
, widthInBytes
);
597 grLfbUnlock(GR_LFB_READ_ONLY
, fxMesa
->currentFB
);
606 static void fxDDFinish(GLcontext
*ctx
)
614 void fxDDSetNearFar(GLcontext
*ctx
, GLfloat n
, GLfloat f
)
616 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_FOG
;
617 ctx
->Driver
.RenderStart
= fxSetupFXUnits
;
620 /* KW: Put the word Mesa in the render string because quakeworld
621 * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE).
624 static const GLubyte
*fxDDGetString(GLcontext
*ctx
, GLenum name
)
631 if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
==GR_SSTTYPE_VOODOO
) {
632 GrVoodooConfig_t
*vc
=
633 &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
;
636 "Mesa Glide v0.30 Voodoo_Graphics %d "
637 "CARD/%d FB/%d TM/%d TMU/%s",
639 (vc
->sliDetect
? (vc
->fbRam
*2) : vc
->fbRam
),
640 (vc
->tmuConfig
[GR_TMU0
].tmuRam
+
641 ((vc
->nTexelfx
>1) ? vc
->tmuConfig
[GR_TMU1
].tmuRam
: 0)),
643 (vc
->sliDetect
? "SLI" : "NOSLI"));
645 else if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
==GR_SSTTYPE_SST96
) {
646 GrSst96Config_t
*sc
=
647 &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.SST96Config
;
650 "Glide v0.30 Voodoo_Rush %d "
651 "CARD/%d FB/%d TM/%d TMU/NOSLI",
654 sc
->tmuConfig
.tmuRam
,
658 strcpy(buf
, "Glide v0.30 UNKNOWN");
660 return (GLubyte
*) buf
;
668 int fxDDInitFxMesaContext( fxMesaContext fxMesa
)
671 FX_setupGrVertexLayout();
673 if (getenv("FX_EMULATE_SINGLE_TMU"))
674 fxMesa
->haveTwoTMUs
= GL_FALSE
;
676 fxMesa
->emulateTwoTMUs
= fxMesa
->haveTwoTMUs
;
678 if (!getenv("FX_DONT_FAKE_MULTITEX"))
679 fxMesa
->emulateTwoTMUs
= GL_TRUE
;
681 if(getenv("FX_GLIDE_SWAPINTERVAL"))
682 fxMesa
->swapInterval
=atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
684 fxMesa
->swapInterval
=1;
686 if(getenv("MESA_FX_SWAP_PENDING"))
687 fxMesa
->maxPendingSwapBuffers
=atoi(getenv("MESA_FX_SWAP_PENDING"));
689 fxMesa
->maxPendingSwapBuffers
=2;
691 if(getenv("MESA_FX_INFO"))
692 fxMesa
->verbose
=GL_TRUE
;
694 fxMesa
->verbose
=GL_FALSE
;
696 fxMesa
->color
=0xffffffff;
700 fxMesa
->stats
.swapBuffer
=0;
701 fxMesa
->stats
.reqTexUpload
=0;
702 fxMesa
->stats
.texUpload
=0;
703 fxMesa
->stats
.memTexUpload
=0;
705 fxMesa
->tmuSrc
=FX_TMU_NONE
;
706 fxMesa
->lastUnitsMode
=FX_UM_NONE
;
711 fxMesa
->unitsState
.alphaTestEnabled
=GL_FALSE
;
712 fxMesa
->unitsState
.alphaTestFunc
=GR_CMP_ALWAYS
;
713 fxMesa
->unitsState
.alphaTestRefValue
=0;
715 fxMesa
->unitsState
.blendEnabled
=GL_FALSE
;
716 fxMesa
->unitsState
.blendSrcFuncRGB
=GR_BLEND_ONE
;
717 fxMesa
->unitsState
.blendDstFuncRGB
=GR_BLEND_ZERO
;
718 fxMesa
->unitsState
.blendSrcFuncAlpha
=GR_BLEND_ONE
;
719 fxMesa
->unitsState
.blendDstFuncAlpha
=GR_BLEND_ZERO
;
721 fxMesa
->unitsState
.depthTestEnabled
=GL_FALSE
;
722 fxMesa
->unitsState
.depthMask
=GL_TRUE
;
723 fxMesa
->unitsState
.depthTestFunc
=GR_CMP_LESS
;
725 FX_grColorMask(FXTRUE
, fxMesa
->haveAlphaBuffer
? FXTRUE
: FXFALSE
);
726 if(fxMesa
->haveDoubleBuffer
) {
727 fxMesa
->currentFB
=GR_BUFFER_BACKBUFFER
;
728 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER
);
730 fxMesa
->currentFB
=GR_BUFFER_FRONTBUFFER
;
731 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
734 fxMesa
->state
= NULL
;
735 fxMesa
->fogTable
= NULL
;
737 fxMesa
->state
= malloc(FX_grGetInteger(FX_GLIDE_STATE_SIZE
));
738 fxMesa
->fogTable
= malloc(FX_grGetInteger(FX_FOG_TABLE_ENTRIES
)*sizeof(GrFog_t
));
740 if (!fxMesa
->state
|| !fxMesa
->fogTable
) {
741 if (fxMesa
->state
) free(fxMesa
->state
);
742 if (fxMesa
->fogTable
) free(fxMesa
->fogTable
);
746 if(fxMesa
->haveZBuffer
)
747 FX_grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER
);
749 #if (!FXMESA_USE_ARGB)
750 FX_grLfbWriteColorFormat(GR_COLORFORMAT_ABGR
); /* Not every Glide has this */
753 fxMesa
->textureAlign
=FX_grGetInteger(FX_TEXTURE_ALIGN
);
754 fxMesa
->glCtx
->Const
.MaxTextureLevels
=9;
755 fxMesa
->glCtx
->Const
.MaxTextureSize
=256;
756 fxMesa
->glCtx
->Const
.MaxTextureUnits
=fxMesa
->emulateTwoTMUs
? 2 : 1;
757 fxMesa
->new_state
= _NEW_ALL
;
764 /* Initialize the software rasterizer and helper modules.
766 _swrast_CreateContext( fxMesa
->glCtx
);
767 _swsetup_CreateContext( fxMesa
->glCtx
);
770 fxSetupDDPointers(fxMesa
->glCtx
);
771 fxDDInitExtensions(fxMesa
->glCtx
);
773 fxDDSetNearFar(fxMesa
->glCtx
,1.0,100.0);
775 FX_grGlideGetState((GrState
*)fxMesa
->state
);
777 /* XXX Fix me: callback not registered when main VB is created.
779 if (fxMesa
->glCtx
->VB
)
780 fxDDRegisterVB( fxMesa
->glCtx
->VB
);
782 /* XXX Fix me too: need to have the 'struct dd' prepared prior to
783 * creating the context... The below is broken if you try to insert
786 if (fxMesa
->glCtx
->NrPipelineStages
)
787 fxMesa
->glCtx
->NrPipelineStages
= fxDDRegisterPipelineStages(
788 fxMesa
->glCtx
->PipelineStage
,
789 fxMesa
->glCtx
->PipelineStage
,
790 fxMesa
->glCtx
->NrPipelineStages
);
792 /* Run the config file */
793 _mesa_context_initialize( fxMesa
->glCtx
);
801 void fxDDInitExtensions( GLcontext
*ctx
)
803 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
805 gl_extensions_disable(ctx
, "GL_EXT_blend_logic_op");
806 gl_extensions_disable(ctx
, "GL_EXT_blend_minmax");
807 gl_extensions_disable(ctx
, "GL_EXT_blend_subtract");
808 gl_extensions_disable(ctx
, "GL_EXT_blend_color");
809 gl_extensions_disable(ctx
, "GL_EXT_fog_coord");
811 gl_extensions_add(ctx
, GL_TRUE
, "3DFX_set_global_palette", 0);
813 if (!fxMesa
->haveTwoTMUs
)
814 gl_extensions_disable(ctx
, "GL_EXT_texture_env_add");
816 if (!fxMesa
->emulateTwoTMUs
)
817 gl_extensions_disable(ctx
, "GL_ARB_multitexture");
821 /************************************************************************/
822 /************************************************************************/
823 /************************************************************************/
825 /* Check if the hardware supports the current context
827 * Performs similar work to fxDDChooseRenderState() - should be merged.
829 static GLboolean
fxIsInHardware(GLcontext
*ctx
)
831 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
833 if (ctx
->RenderMode
!= GL_RENDER
)
836 if (!ctx
->Hint
.AllowDrawMem
)
837 return GL_TRUE
; /* you'll take it and like it */
839 if (ctx
->Stencil
.Enabled
||
840 ctx
->Color
.MultiDrawBuffer
||
841 ((ctx
->Color
.BlendEnabled
) && (ctx
->Color
.BlendEquation
!=GL_FUNC_ADD_EXT
)) ||
842 ((ctx
->Color
.ColorLogicOpEnabled
) && (ctx
->Color
.LogicOp
!=GL_COPY
)) ||
843 (ctx
->Light
.Model
.ColorControl
==GL_SEPARATE_SPECULAR_COLOR
) ||
844 (!((ctx
->Color
.ColorMask
[RCOMP
]==ctx
->Color
.ColorMask
[GCOMP
]) &&
845 (ctx
->Color
.ColorMask
[GCOMP
]==ctx
->Color
.ColorMask
[BCOMP
]) &&
846 (ctx
->Color
.ColorMask
[ACOMP
]==ctx
->Color
.ColorMask
[ACOMP
])))
851 /* Unsupported texture/multitexture cases */
853 if(fxMesa
->emulateTwoTMUs
) {
854 if((ctx
->_Enabled
& (TEXTURE0_3D
| TEXTURE1_3D
)) ||
855 /* Not very well written ... */
856 ((ctx
->_Enabled
& (TEXTURE0_1D
| TEXTURE1_1D
)) &&
857 ((ctx
->_Enabled
& (TEXTURE0_2D
| TEXTURE1_2D
))!=(TEXTURE0_2D
| TEXTURE1_2D
)))
862 if (ctx
->Texture
._ReallyEnabled
& TEXTURE0_2D
) {
863 if (ctx
->Texture
.Unit
[0].EnvMode
== GL_BLEND
&&
864 (ctx
->Texture
._ReallyEnabled
& TEXTURE1_2D
||
865 ctx
->Texture
.Unit
[0].EnvColor
[0] != 0 ||
866 ctx
->Texture
.Unit
[0].EnvColor
[1] != 0 ||
867 ctx
->Texture
.Unit
[0].EnvColor
[2] != 0 ||
868 ctx
->Texture
.Unit
[0].EnvColor
[3] != 1)) {
871 if (ctx
->Texture
.Unit
[0]._Current
->Image
[0]->Border
> 0)
875 if (ctx
->Texture
._ReallyEnabled
& TEXTURE1_2D
) {
876 if (ctx
->Texture
.Unit
[1].EnvMode
== GL_BLEND
)
878 if (ctx
->Texture
.Unit
[0]._Current
->Image
[0]->Border
> 0)
882 if (MESA_VERBOSE
& (VERBOSE_DRIVER
|VERBOSE_TEXTURE
))
883 fprintf(stderr
, "fxMesa: fxIsInHardware, envmode is %s/%s\n",
884 gl_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
885 gl_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
887 /* KW: This was wrong (I think) and I changed it... which doesn't mean
888 * it is now correct...
890 if((ctx
->_Enabled
& (TEXTURE0_1D
| TEXTURE0_2D
| TEXTURE0_3D
)) &&
891 (ctx
->_Enabled
& (TEXTURE1_1D
| TEXTURE1_2D
| TEXTURE1_3D
)))
893 /* Can't use multipass to blend a multitextured triangle - fall
896 if (!fxMesa
->haveTwoTMUs
&& ctx
->Color
.BlendEnabled
) {
900 if ((ctx
->Texture
.Unit
[0].EnvMode
!=ctx
->Texture
.Unit
[1].EnvMode
) &&
901 (ctx
->Texture
.Unit
[0].EnvMode
!=GL_MODULATE
) &&
902 (ctx
->Texture
.Unit
[0].EnvMode
!=GL_REPLACE
)) /* q2, seems ok... */
904 if (MESA_VERBOSE
&VERBOSE_DRIVER
)
905 fprintf(stderr
, "fxMesa: unsupported multitex env mode\n");
910 if((ctx
->_Enabled
& (TEXTURE1_1D
| TEXTURE1_2D
| TEXTURE1_3D
)) ||
911 /* Not very well written ... */
912 ((ctx
->_Enabled
& TEXTURE0_1D
) &&
913 (!(ctx
->_Enabled
& TEXTURE0_2D
)))
919 if((ctx
->Texture
._ReallyEnabled
& TEXTURE0_2D
) &&
920 (ctx
->Texture
.Unit
[0].EnvMode
==GL_BLEND
)) {
929 static void fxDDUpdateDDPointers(GLcontext
*ctx
)
931 GLuint new_state
= ctx
->NewState
;
933 _swrast_InvalidateState( ctx
, new_state
);
934 _swsetup_InvalidateState( ctx
, new_state
);
936 if (new_state
& (_FX_NEW_IS_IN_HARDWARE
|
937 _FX_NEW_RENDERSTATE
|
938 _FX_NEW_SETUP_FUNCTION
))
940 fxMesaContext fxMesa
=(fxMesaContext
)ctx
->DriverCtx
;
942 if (new_state
& _FX_NEW_IS_IN_HARDWARE
)
943 fxMesa
->is_in_hardware
= fxIsInHardware(ctx
);
945 if (fxMesa
->new_state
)
948 if (new_state
& _FX_NEW_RENDERSTATE
)
949 fxDDChooseRenderState( ctx
);
951 if (new_state
& _FX_NEW_SETUP_FUNCTION
)
952 ctx
->Driver
.RasterSetup
= fxDDChooseSetupFunction(ctx
);
958 void fxSetupDDPointers(GLcontext
*ctx
)
960 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
961 fprintf(stderr
,"fxmesa: fxSetupDDPointers()\n");
964 ctx
->Driver
.UpdateStateNotify
= ~0;
965 ctx
->Driver
.UpdateState
=fxDDUpdateDDPointers
;
967 ctx
->Driver
.WriteDepthSpan
=fxDDWriteDepthSpan
;
968 ctx
->Driver
.WriteDepthPixels
=fxDDWriteDepthPixels
;
969 ctx
->Driver
.ReadDepthSpan
=fxDDReadDepthSpan
;
970 ctx
->Driver
.ReadDepthPixels
=fxDDReadDepthPixels
;
972 ctx
->Driver
.GetString
=fxDDGetString
;
974 ctx
->Driver
.NearFar
=fxDDSetNearFar
;
976 ctx
->Driver
.ClearIndex
=NULL
;
977 ctx
->Driver
.ClearColor
=fxDDClearColor
;
978 ctx
->Driver
.Clear
=fxDDClear
;
980 ctx
->Driver
.Index
=NULL
;
981 ctx
->Driver
.Color
=fxDDSetColor
;
983 ctx
->Driver
.SetDrawBuffer
=fxDDSetDrawBuffer
;
984 ctx
->Driver
.SetReadBuffer
=fxDDSetReadBuffer
;
985 ctx
->Driver
.GetBufferSize
=fxDDBufferSize
;
987 ctx
->Driver
.Bitmap
=fxDDDrawBitmap
;
988 ctx
->Driver
.DrawPixels
=NULL
;
989 ctx
->Driver
.ReadPixels
=fxDDReadPixels
;
991 ctx
->Driver
.Finish
=fxDDFinish
;
992 ctx
->Driver
.Flush
=NULL
;
994 ctx
->Driver
.RenderStart
=NULL
;
995 ctx
->Driver
.RenderFinish
=NULL
;
997 ctx
->Driver
.TexImage2D
= fxDDTexImage2D
;
998 ctx
->Driver
.TexSubImage2D
= fxDDTexSubImage2D
;
999 ctx
->Driver
.GetTexImage
= fxDDGetTexImage
;
1000 ctx
->Driver
.TexEnv
=fxDDTexEnv
;
1001 ctx
->Driver
.TexParameter
=fxDDTexParam
;
1002 ctx
->Driver
.BindTexture
=fxDDTexBind
;
1003 ctx
->Driver
.DeleteTexture
=fxDDTexDel
;
1004 ctx
->Driver
.UpdateTexturePalette
=fxDDTexPalette
;
1006 ctx
->Driver
.RectFunc
=NULL
;
1008 ctx
->Driver
.AlphaFunc
=fxDDAlphaFunc
;
1009 ctx
->Driver
.BlendFunc
=fxDDBlendFunc
;
1010 ctx
->Driver
.DepthFunc
=fxDDDepthFunc
;
1011 ctx
->Driver
.DepthMask
=fxDDDepthMask
;
1012 ctx
->Driver
.ColorMask
=fxDDColorMask
;
1013 ctx
->Driver
.Fogfv
=fxDDFogfv
;
1014 ctx
->Driver
.Scissor
=fxDDScissor
;
1015 ctx
->Driver
.FrontFace
=fxDDFrontFace
;
1016 ctx
->Driver
.CullFace
=fxDDCullFace
;
1017 ctx
->Driver
.ShadeModel
=fxDDShadeModel
;
1018 ctx
->Driver
.Enable
=fxDDEnable
;
1020 ctx
->Driver
.RegisterVB
=fxDDRegisterVB
;
1021 ctx
->Driver
.UnregisterVB
=fxDDUnregisterVB
;
1023 ctx
->Driver
.RegisterPipelineStages
= fxDDRegisterPipelineStages
;
1025 if (!getenv("FX_NO_FAST"))
1026 ctx
->Driver
.BuildPrecalcPipeline
= fxDDBuildPrecalcPipeline
;
1028 fxSetupDDSpanPointers(ctx
);
1029 fxDDUpdateDDPointers(ctx
);
1037 * Need this to provide at least one external definition.
1040 int gl_fx_dummy_function_dd(void)