2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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 shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 /* fxapi.c - public interface to FX/Mesa functions (fxmesa.h) */
45 #include "drivers/common/driverfuncs.h"
46 #include "framebuffer.h"
50 /* | VERBOSE_VARRAY */
51 /* | VERBOSE_TEXTURE */
52 /* | VERBOSE_IMMEDIATE */
53 /* | VERBOSE_PIPELINE */
54 /* | VERBOSE_DRIVER */
57 /* | VERBOSE_DISPLAY_LIST */
58 /* | VERBOSE_LIGHTING */
64 static fxMesaContext fxMesaCurrentCtx
= NULL
;
67 * Status of 3Dfx hardware initialization
70 static int glbGlideInitialized
= 0;
71 static int glb3DfxPresent
= 0;
72 static int glbTotNumCtx
= 0;
74 static GrHwConfiguration glbHWConfig
;
75 static int glbCurrentBoard
= 0;
78 #if defined(__WIN32__)
83 fxMesaDestroyContext(fxMesaCurrentCtx
);
87 #elif defined(__linux__)
92 fxMesaDestroyContext(fxMesaCurrentCtx
);
96 cleangraphics_handler(int s
)
98 fprintf(stderr
, "fxmesa: ERROR: received a not handled signal %d\n", s
);
108 * Query 3Dfx hardware presence/kind
110 static GLboolean GLAPIENTRY
fxQueryHardware (void)
112 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
113 fprintf(stderr
, "fxQueryHardware()\n");
116 if (!glbGlideInitialized
) {
118 glb3DfxPresent
= FX_grSstQueryHardware(&glbHWConfig
);
120 glbGlideInitialized
= 1;
122 #if defined(__WIN32__)
123 _onexit((_onexit_t
) cleangraphics
);
124 #elif defined(__linux__)
125 /* Only register handler if environment variable is not defined. */
126 if (!getenv("MESA_FX_NO_SIGNALS")) {
127 atexit(cleangraphics
);
132 return glb3DfxPresent
;
137 * Select the Voodoo board to use when creating
140 GLint GLAPIENTRY
fxMesaSelectCurrentBoard (int n
)
144 if ((n
< 0) || (n
>= glbHWConfig
.num_sst
))
147 return glbHWConfig
.SSTs
[glbCurrentBoard
= n
].type
;
151 fxMesaContext GLAPIENTRY
fxMesaGetCurrentContext (void)
153 return fxMesaCurrentCtx
;
157 void GLAPIENTRY
fxGetScreenGeometry (GLint
*w
, GLint
*h
)
162 if (fxMesaCurrentCtx
!= NULL
) {
163 width
= fxMesaCurrentCtx
->screen_width
;
164 height
= fxMesaCurrentCtx
->screen_height
;
177 * The 3Dfx Global Palette extension for GLQuake.
178 * More a trick than a real extesion, use the shared global
181 extern void GLAPIENTRY
gl3DfxSetPaletteEXT(GLuint
* pal
); /* silence warning */
183 gl3DfxSetPaletteEXT(GLuint
* pal
)
185 fxMesaContext fxMesa
= fxMesaCurrentCtx
;
187 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
190 fprintf(stderr
, "gl3DfxSetPaletteEXT(...)\n");
192 for (i
= 0; i
< 256; i
++) {
193 fprintf(stderr
, "\t%x\n", pal
[i
]);
198 fxMesa
->haveGlobalPaletteTexture
= 1;
200 grTexDownloadTable(GR_TEXTABLE_PALETTE
, (GuTexPalette
*) pal
);
205 static GrScreenResolution_t
fxBestResolution (int width
, int height
)
207 static int resolutions
[][3] = {
208 { GR_RESOLUTION_320x200
, 320, 200 },
209 { GR_RESOLUTION_320x240
, 320, 240 },
210 { GR_RESOLUTION_400x256
, 400, 256 },
211 { GR_RESOLUTION_512x384
, 512, 384 },
212 { GR_RESOLUTION_640x200
, 640, 200 },
213 { GR_RESOLUTION_640x350
, 640, 350 },
214 { GR_RESOLUTION_640x400
, 640, 400 },
215 { GR_RESOLUTION_640x480
, 640, 480 },
216 { GR_RESOLUTION_800x600
, 800, 600 },
217 { GR_RESOLUTION_960x720
, 960, 720 },
218 { GR_RESOLUTION_856x480
, 856, 480 },
219 { GR_RESOLUTION_512x256
, 512, 256 },
220 { GR_RESOLUTION_1024x768
, 1024, 768 },
221 { GR_RESOLUTION_1280x1024
, 1280, 1024 },
222 { GR_RESOLUTION_1600x1200
, 1600, 1200 },
223 { GR_RESOLUTION_400x300
, 400, 300 },
224 { GR_RESOLUTION_1152x864
, 1152, 864 },
225 { GR_RESOLUTION_1280x960
, 1280, 960 },
226 { GR_RESOLUTION_1600x1024
, 1600, 1024 },
227 { GR_RESOLUTION_1792x1344
, 1792, 1344 },
228 { GR_RESOLUTION_1856x1392
, 1856, 1392 },
229 { GR_RESOLUTION_1920x1440
, 1920, 1440 },
230 { GR_RESOLUTION_2048x1536
, 2048, 1536 },
231 { GR_RESOLUTION_2048x2048
, 2048, 2048 }
235 int lastvalidres
= GR_RESOLUTION_640x480
;
236 int min
= 2048 * 2048; /* max is GR_RESOLUTION_2048x2048 */
237 GrResolution resTemplate
= {
243 GrResolution
*presSupported
;
247 size
= grQueryResolutions(&resTemplate
, NULL
);
248 presSupported
= malloc(size
);
250 size
/= sizeof(GrResolution
);
251 grQueryResolutions(&resTemplate
, presSupported
);
253 for (i
= 0; i
< size
; i
++) {
254 int r
= presSupported
[i
].resolution
;
255 if ((width
<= resolutions
[r
][1]) && (height
<= resolutions
[r
][2])) {
256 if (min
> (resolutions
[r
][1] * resolutions
[r
][2])) {
257 min
= resolutions
[r
][1] * resolutions
[r
][2];
265 return resolutions
[lastvalidres
][0];
269 fxMesaContext GLAPIENTRY
270 fxMesaCreateBestContext(GLuint win
, GLint width
, GLint height
,
271 const GLint attribList
[])
273 int res
= fxBestResolution(width
, height
);
279 return fxMesaCreateContext(win
, res
, GR_REFRESH_60Hz
, attribList
);
284 * Create a new FX/Mesa context and return a handle to it.
286 fxMesaContext GLAPIENTRY
287 fxMesaCreateContext(GLuint win
,
288 GrScreenResolution_t res
,
289 GrScreenRefresh_t ref
, const GLint attribList
[])
291 fxMesaContext fxMesa
= NULL
;
292 GLcontext
*ctx
= NULL
, *shareCtx
= NULL
;
293 struct dd_function_table functions
;
297 int sliaa
, numSLI
, samplesPerChip
;
298 struct SstCard_St
*voodoo
;
299 struct tdfx_glide
*Glide
;
302 GLboolean doubleBuffer
;
304 GLuint depthSize
, alphaSize
, stencilSize
, accumSize
;
305 GLuint redBits
, greenBits
, blueBits
, alphaBits
;
306 GrPixelFormat_t pixFmt
;
308 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
309 fprintf(stderr
, "fxMesaCreateContext(...)\n");
312 /* Okay, first process the user flags */
314 doubleBuffer
= GL_FALSE
;
316 depthSize
= alphaSize
= stencilSize
= accumSize
= 0;
319 while (attribList
[i
] != FXMESA_NONE
) {
320 switch (attribList
[i
]) {
321 case FXMESA_COLORDEPTH
:
322 colDepth
= attribList
[++i
];
324 case FXMESA_DOUBLEBUFFER
:
325 doubleBuffer
= GL_TRUE
;
327 case FXMESA_ALPHA_SIZE
:
328 if ((alphaSize
= attribList
[++i
])) {
332 case FXMESA_DEPTH_SIZE
:
333 if ((depthSize
= attribList
[++i
])) {
337 case FXMESA_STENCIL_SIZE
:
338 stencilSize
= attribList
[++i
];
340 case FXMESA_ACCUM_SIZE
:
341 accumSize
= attribList
[++i
];
343 /* XXX ugly hack here for sharing display lists */
344 case FXMESA_SHARE_CONTEXT
:
345 shareCtx
= (GLcontext
*)attribList
[++i
];
348 fprintf(stderr
, "fxMesaCreateContext: ERROR: wrong parameter (%d) passed\n", attribList
[i
]);
354 if (!fxQueryHardware()) {
355 str
= "no Voodoo hardware!";
359 grSstSelect(glbCurrentBoard
);
360 /*grEnable(GR_OPENGL_MODE_EXT);*/ /* [koolsmoky] */
361 voodoo
= &glbHWConfig
.SSTs
[glbCurrentBoard
];
363 fxMesa
= (fxMesaContext
)CALLOC_STRUCT(tfxMesaContext
);
365 str
= "private context";
369 if (getenv("MESA_FX_INFO")) {
370 fxMesa
->verbose
= GL_TRUE
;
373 fxMesa
->type
= voodoo
->type
;
374 fxMesa
->HavePalExt
= voodoo
->HavePalExt
&& !getenv("MESA_FX_IGNORE_PALEXT");
375 fxMesa
->HavePixExt
= voodoo
->HavePixExt
&& !getenv("MESA_FX_IGNORE_PIXEXT");
376 fxMesa
->HaveTexFmt
= voodoo
->HaveTexFmt
&& !getenv("MESA_FX_IGNORE_TEXFMT");
377 fxMesa
->HaveCmbExt
= voodoo
->HaveCmbExt
&& !getenv("MESA_FX_IGNORE_CMBEXT");
378 fxMesa
->HaveMirExt
= voodoo
->HaveMirExt
&& !getenv("MESA_FX_IGNORE_MIREXT");
379 fxMesa
->HaveTexUma
= voodoo
->HaveTexUma
&& !getenv("MESA_FX_IGNORE_TEXUMA");
380 fxMesa
->Glide
= glbHWConfig
.Glide
;
381 Glide
= &fxMesa
->Glide
;
382 fxMesa
->HaveTexus2
= Glide
->txImgQuantize
&&
383 Glide
->txMipQuantize
&&
384 Glide
->txPalToNcc
&& !getenv("MESA_FX_IGNORE_TEXUS2");
386 /* Determine if we need vertex swapping, RGB order and SLI/AA */
388 switch (fxMesa
->type
) {
389 case GR_SSTTYPE_VOODOO
:
390 case GR_SSTTYPE_SST96
:
391 case GR_SSTTYPE_Banshee
:
392 fxMesa
->bgrOrder
= GL_TRUE
;
393 fxMesa
->snapVertices
= (getenv("MESA_FX_NOSNAP") == NULL
);
395 case GR_SSTTYPE_Voodoo2
:
396 fxMesa
->bgrOrder
= GL_TRUE
;
397 fxMesa
->snapVertices
= GL_FALSE
;
399 case GR_SSTTYPE_Voodoo4
:
400 case GR_SSTTYPE_Voodoo5
:
401 /* number of SLI units and AA Samples per chip */
402 if ((str
= Glide
->grGetRegistryOrEnvironmentStringExt("SSTH3_SLI_AA_CONFIGURATION")) != NULL
) {
405 case GR_SSTTYPE_Voodoo3
:
407 fxMesa
->bgrOrder
= GL_FALSE
;
408 fxMesa
->snapVertices
= GL_FALSE
;
411 /* XXX todo - Add the old SLI/AA settings for Napalm. */
412 switch(voodoo
->numChips
) {
413 case 4: /* 4 chips */
415 case 8: /* 8 Sample AA */
419 case 7: /* 4 Sample AA */
423 case 6: /* 2 Sample AA */
432 case 2: /* 2 chips */
434 case 4: /* 4 Sample AA */
438 case 3: /* 2 Sample AA */
447 default: /* 1 chip */
449 case 1: /* 2 Sample AA */
459 fxMesa
->fsaa
= samplesPerChip
* voodoo
->numChips
/ numSLI
; /* 1:noFSAA, 2:2xFSAA, 4:4xFSAA, 8:8xFSAA */
461 switch (fxMesa
->colDepth
= colDepth
) {
466 alphaBits
= depthSize
? 1 : 8;
467 switch(fxMesa
->fsaa
) {
469 pixFmt
= GR_PIXFMT_AA_8_ARGB_1555
;
472 pixFmt
= GR_PIXFMT_AA_4_ARGB_1555
;
475 pixFmt
= GR_PIXFMT_AA_2_ARGB_1555
;
478 pixFmt
= GR_PIXFMT_ARGB_1555
;
485 alphaBits
= depthSize
? 0 : 8;
486 switch(fxMesa
->fsaa
) {
488 pixFmt
= GR_PIXFMT_AA_8_RGB_565
;
491 pixFmt
= GR_PIXFMT_AA_4_RGB_565
;
494 pixFmt
= GR_PIXFMT_AA_2_RGB_565
;
497 pixFmt
= GR_PIXFMT_RGB_565
;
501 fxMesa
->colDepth
= 32;
507 switch(fxMesa
->fsaa
) {
509 pixFmt
= GR_PIXFMT_AA_8_ARGB_8888
;
512 pixFmt
= GR_PIXFMT_AA_4_ARGB_8888
;
515 pixFmt
= GR_PIXFMT_AA_2_ARGB_8888
;
518 pixFmt
= GR_PIXFMT_ARGB_8888
;
527 * 1. we don't bother setting/checking AUX for stencil, because we'll decide
528 * later whether we have HW stencil, based on depth buffer (thus AUX is
530 * 2. when both DEPTH and ALPHA are enabled, depth should win. However, it is
531 * not clear whether 15bpp and 32bpp require AUX alpha buffer. Furthermore,
532 * alpha buffering is required only if destination alpha is used in alpha
533 * blending; alpha blending modes that do not use destination alpha can be
534 * used w/o alpha buffer.
535 * 3. `alphaBits' is what we can provide
536 * `alphaSize' is what app requests
537 * if we cannot provide enough bits for alpha buffer, we should fallback to
538 * SW alpha. However, setting `alphaBits' to `alphaSize' might confuse some
539 * of the span functions...
542 fxMesa
->haveHwAlpha
= GL_FALSE
;
543 if (alphaSize
&& (alphaSize
<= alphaBits
)) {
544 alphaSize
= alphaBits
;
545 fxMesa
->haveHwAlpha
= GL_TRUE
;
548 fxMesa
->haveHwStencil
= (fxMesa
->HavePixExt
&& stencilSize
&& depthSize
== 24);
550 fxMesa
->haveZBuffer
= depthSize
> 0;
551 fxMesa
->haveDoubleBuffer
= doubleBuffer
;
552 fxMesa
->haveGlobalPaletteTexture
= GL_FALSE
;
553 fxMesa
->board
= glbCurrentBoard
;
555 fxMesa
->haveTwoTMUs
= (voodoo
->nTexelfx
> 1);
557 if ((str
= Glide
->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_NUM_TMU"))) {
558 if (atoi(str
) <= 1) {
559 fxMesa
->haveTwoTMUs
= GL_FALSE
;
563 if ((str
= Glide
->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_SWAPPENDINGCOUNT"))) {
564 fxMesa
->maxPendingSwapBuffers
= atoi(str
);
565 if (fxMesa
->maxPendingSwapBuffers
> 6) {
566 fxMesa
->maxPendingSwapBuffers
= 6;
567 } else if (fxMesa
->maxPendingSwapBuffers
< 0) {
568 fxMesa
->maxPendingSwapBuffers
= 0;
571 fxMesa
->maxPendingSwapBuffers
= 2;
574 if ((str
= Glide
->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_SWAPINTERVAL"))) {
575 fxMesa
->swapInterval
= atoi(str
);
577 fxMesa
->swapInterval
= 0;
581 if (fxMesa
->HavePixExt
) {
582 fxMesa
->glideContext
= Glide
->grSstWinOpenExt((FxU32
)win
, res
, ref
,
583 GR_COLORFORMAT_ABGR
, GR_ORIGIN_LOWER_LEFT
,
586 } else if (pixFmt
== GR_PIXFMT_RGB_565
) {
587 fxMesa
->glideContext
= grSstWinOpen((FxU32
)win
, res
, ref
,
588 GR_COLORFORMAT_ABGR
, GR_ORIGIN_LOWER_LEFT
,
591 fxMesa
->glideContext
= 0;
594 if (!fxMesa
->glideContext
) {
595 str
= "grSstWinOpen";
600 fxMesa
->screen_width
= FX_grSstScreenWidth();
601 fxMesa
->screen_height
= FX_grSstScreenHeight();
603 /* window inside screen */
604 fxMesa
->width
= fxMesa
->screen_width
;
605 fxMesa
->height
= fxMesa
->screen_height
;
607 /* scissor inside window */
608 fxMesa
->clipMinX
= 0;
609 fxMesa
->clipMaxX
= fxMesa
->width
;
610 fxMesa
->clipMinY
= 0;
611 fxMesa
->clipMaxY
= fxMesa
->height
;
613 if (fxMesa
->verbose
) {
616 /* Not that it matters, but tmuRam and fbRam change after grSstWinOpen. */
617 tmuRam
= voodoo
->tmuConfig
[GR_TMU0
].tmuRam
;
618 fbRam
= voodoo
->fbRam
;
620 grGet(GR_MEMORY_TMU
, 4, &tmuRam
);
621 grGet(GR_MEMORY_FB
, 4, &fbRam
);
624 fprintf(stderr
, "Voodoo Using Glide %s\n", grGetString(GR_VERSION
));
625 fprintf(stderr
, "Voodoo Board: %d/%d, %s, %d GPU\n",
628 grGetString(GR_HARDWARE
),
630 fprintf(stderr
, "Voodoo Memory: FB = %ld, TM = %d x %ld\n",
634 fprintf(stderr
, "Voodoo Screen: %dx%d:%d %s, %svertex snapping\n",
635 fxMesa
->screen_width
,
636 fxMesa
->screen_height
,
638 fxMesa
->bgrOrder
? "BGR" : "RGB",
639 fxMesa
->snapVertices
? "" : "no ");
642 sprintf(fxMesa
->rendererString
, "Mesa %s v0.63 %s%s",
643 grGetString(GR_RENDERER
),
644 grGetString(GR_HARDWARE
),
645 ((fxMesa
->type
< GR_SSTTYPE_Voodoo4
) && (voodoo
->numChips
> 1)) ? " SLI" : "");
647 fxMesa
->glVis
= _mesa_create_visual(GL_TRUE
, /* RGB mode */
649 GL_FALSE
, /* stereo */
650 redBits
, /* RGBA.R bits */
651 greenBits
, /* RGBA.G bits */
652 blueBits
, /* RGBA.B bits */
653 alphaSize
, /* RGBA.A bits */
655 depthSize
, /* depth_size */
656 stencilSize
, /* stencil_size */
660 alphaSize
? accumSize
: 0,
662 if (!fxMesa
->glVis
) {
663 str
= "_mesa_create_visual";
667 _mesa_init_driver_functions(&functions
);
668 ctx
= fxMesa
->glCtx
= _mesa_create_context(fxMesa
->glVis
, shareCtx
,
669 &functions
, (void *) fxMesa
);
671 str
= "_mesa_create_context";
676 if (!fxDDInitFxMesaContext(fxMesa
)) {
677 str
= "fxDDInitFxMesaContext";
682 fxMesa
->glBuffer
= _mesa_create_framebuffer(fxMesa
->glVis
);
684 /* XXX this is a complete mess :(
685 * _mesa_add_soft_renderbuffers
688 GL_FALSE
, /* no software depth */
689 stencilSize
&& !fxMesa
->haveHwStencil
,
690 fxMesa
->glVis
->accumRedBits
> 0,
691 alphaSize
&& !fxMesa
->haveHwAlpha
);
693 if (!fxMesa
->glBuffer
) {
694 str
= "_mesa_create_framebuffer";
700 /* install signal handlers */
701 #if defined(__linux__)
702 /* Only install if environment var. is not set. */
703 if (!getenv("MESA_FX_NO_SIGNALS")) {
704 signal(SIGINT
, cleangraphics_handler
);
705 signal(SIGHUP
, cleangraphics_handler
);
706 signal(SIGPIPE
, cleangraphics_handler
);
707 signal(SIGFPE
, cleangraphics_handler
);
708 signal(SIGBUS
, cleangraphics_handler
);
709 signal(SIGILL
, cleangraphics_handler
);
710 signal(SIGSEGV
, cleangraphics_handler
);
711 signal(SIGTERM
, cleangraphics_handler
);
719 if (fxMesa
->glideContext
) {
720 grSstWinClose(fxMesa
->glideContext
);
721 fxMesa
->glideContext
= 0;
727 if (fxMesa
->fogTable
) {
728 FREE(fxMesa
->fogTable
);
730 if (fxMesa
->glBuffer
) {
731 _mesa_unreference_framebuffer(&fxMesa
->glBuffer
);
734 _mesa_destroy_visual(fxMesa
->glVis
);
737 _mesa_destroy_context(fxMesa
->glCtx
);
742 fprintf(stderr
, "fxMesaCreateContext: ERROR: %s\n", str
);
748 * Function to set the new window size in the context (mainly for the Voodoo Rush)
751 fxMesaUpdateScreenSize(fxMesaContext fxMesa
)
753 fxMesa
->width
= FX_grSstScreenWidth();
754 fxMesa
->height
= FX_grSstScreenHeight();
759 * Destroy the given FX/Mesa context.
762 fxMesaDestroyContext(fxMesaContext fxMesa
)
764 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
765 fprintf(stderr
, "fxMesaDestroyContext(...)\n");
771 if (fxMesa
->verbose
) {
772 fprintf(stderr
, "Misc Stats:\n");
773 fprintf(stderr
, " # swap buffer: %u\n", fxMesa
->stats
.swapBuffer
);
775 if (!fxMesa
->stats
.swapBuffer
)
776 fxMesa
->stats
.swapBuffer
= 1;
778 fprintf(stderr
, "Textures Stats:\n");
779 fprintf(stderr
, " Free texture memory on TMU0: %d\n",
780 fxMesa
->freeTexMem
[FX_TMU0
]);
781 if (fxMesa
->haveTwoTMUs
)
782 fprintf(stderr
, " Free texture memory on TMU1: %d\n",
783 fxMesa
->freeTexMem
[FX_TMU1
]);
784 fprintf(stderr
, " # request to TMM to upload a texture objects: %u\n",
785 fxMesa
->stats
.reqTexUpload
);
787 " # request to TMM to upload a texture objects per swapbuffer: %.2f\n",
788 fxMesa
->stats
.reqTexUpload
/ (float) fxMesa
->stats
.swapBuffer
);
789 fprintf(stderr
, " # texture objects uploaded: %u\n",
790 fxMesa
->stats
.texUpload
);
791 fprintf(stderr
, " # texture objects uploaded per swapbuffer: %.2f\n",
792 fxMesa
->stats
.texUpload
/ (float) fxMesa
->stats
.swapBuffer
);
793 fprintf(stderr
, " # MBs uploaded to texture memory: %.2f\n",
794 fxMesa
->stats
.memTexUpload
/ (float) (1 << 20));
796 " # MBs uploaded to texture memory per swapbuffer: %.2f\n",
797 (fxMesa
->stats
.memTexUpload
/
798 (float) fxMesa
->stats
.swapBuffer
) / (float) (1 << 20));
803 if (!glbTotNumCtx
&& getenv("MESA_FX_INFO")) {
806 FX_grSstPerfStats(&st
);
808 fprintf(stderr
, "Pixels Stats:\n");
809 fprintf(stderr
, " # pixels processed (minus buffer clears): %u\n",
810 (unsigned) st
.pixelsIn
);
811 fprintf(stderr
, " # pixels not drawn due to chroma key test failure: %u\n",
812 (unsigned) st
.chromaFail
);
813 fprintf(stderr
, " # pixels not drawn due to depth test failure: %u\n",
814 (unsigned) st
.zFuncFail
);
816 " # pixels not drawn due to alpha test failure: %u\n",
817 (unsigned) st
.aFuncFail
);
818 fprintf(stderr
, " # pixels drawn (including buffer clears and LFB writes): %u\n",
819 (unsigned) st
.pixelsOut
);
822 /* close the hardware first,
823 * so we can debug atexit problems (memory leaks, etc).
825 grSstWinClose(fxMesa
->glideContext
);
828 fxDDDestroyFxMesaContext(fxMesa
); /* must be before _mesa_destroy_context */
829 _mesa_destroy_visual(fxMesa
->glVis
);
830 _mesa_destroy_context(fxMesa
->glCtx
);
831 _mesa_unreference_framebuffer(&fxMesa
->glBuffer
);
832 fxTMClose(fxMesa
); /* must be after _mesa_destroy_context */
836 if (fxMesa
== fxMesaCurrentCtx
)
837 fxMesaCurrentCtx
= NULL
;
842 * Make the specified FX/Mesa context the current one.
845 fxMesaMakeCurrent(fxMesaContext fxMesa
)
848 _mesa_make_current(NULL
, NULL
, NULL
);
849 fxMesaCurrentCtx
= NULL
;
851 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
852 fprintf(stderr
, "fxMesaMakeCurrent(NULL)\n");
858 /* if this context is already the current one, we can return early */
859 if (fxMesaCurrentCtx
== fxMesa
860 && fxMesaCurrentCtx
->glCtx
== _mesa_get_current_context()) {
861 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
862 fprintf(stderr
, "fxMesaMakeCurrent(NOP)\n");
868 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
869 fprintf(stderr
, "fxMesaMakeCurrent(...)\n");
872 if (fxMesaCurrentCtx
)
873 grGlideGetState((GrState
*) fxMesaCurrentCtx
->state
);
875 fxMesaCurrentCtx
= fxMesa
;
877 grSstSelect(fxMesa
->board
);
878 grGlideSetState((GrState
*) fxMesa
->state
);
880 _mesa_make_current(fxMesa
->glCtx
, fxMesa
->glBuffer
, fxMesa
->glBuffer
);
882 fxSetupDDPointers(fxMesa
->glCtx
);
887 * Swap front/back buffers for current context if double buffered.
890 fxMesaSwapBuffers(void)
892 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
893 fprintf(stderr
, "fxMesaSwapBuffers()\n");
896 if (fxMesaCurrentCtx
) {
897 _mesa_notifySwapBuffers(fxMesaCurrentCtx
->glCtx
);
899 if (fxMesaCurrentCtx
->haveDoubleBuffer
) {
901 grBufferSwap(fxMesaCurrentCtx
->swapInterval
);
905 * Don't allow swap buffer commands to build up!
907 while (FX_grGetInteger(GR_PENDING_BUFFERSWAPS
) >
908 fxMesaCurrentCtx
->maxPendingSwapBuffers
)
909 /* The driver is able to sleep when waiting for the completation
910 of multiple swapbuffer operations instead of wasting
911 CPU time (NOTE: you must uncomment the following line in the
912 in order to enable this option) */
917 fxMesaCurrentCtx
->stats
.swapBuffer
++;
924 * Shutdown Glide library
927 fxCloseHardware(void)
929 if (glbGlideInitialized
) {
930 if (glbTotNumCtx
== 0) {
932 glbGlideInitialized
= 0;
942 * Need this to provide at least one external definition.
944 extern int gl_fx_dummy_function_api(void);
946 gl_fx_dummy_function_api(void)