1 /* $Id: fxapi.c,v 1.35 2002/10/24 23:57:23 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 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.
35 /* fxapi.c - public interface to FX/Mesa functions (fxmesa.h) */
45 static fxMesaContext fxMesaCurrentCtx
= NULL
;
48 * Status of 3Dfx hardware initialization
51 static int glbGlideInitialized
= 0;
52 static int glb3DfxPresent
= 0;
53 static int glbTotNumCtx
= 0;
55 GrHwConfiguration glbHWConfig
;
56 int glbCurrentBoard
= 0;
59 #if defined(__WIN32__)
64 fxMesaDestroyContext(fxMesaCurrentCtx
);
68 #elif defined(__linux__)
73 fxMesaDestroyContext(fxMesaCurrentCtx
);
77 cleangraphics_handler(int s
)
79 fprintf(stderr
, "fxmesa: Received a not handled signal %d\n", s
);
89 * Select the Voodoo board to use when creating
93 fxMesaSelectCurrentBoard(int n
)
97 if ((n
< 0) || (n
>= glbHWConfig
.num_sst
))
106 fxMesaContext GLAPIENTRY
107 fxMesaGetCurrentContext(void)
109 return fxMesaCurrentCtx
;
114 * The 3Dfx Global Palette extension for GLQuake.
115 * More a trick than a real extesion, use the shared global
118 extern void GLAPIENTRY
gl3DfxSetPaletteEXT(GLuint
* pal
); /* silence warning */
120 gl3DfxSetPaletteEXT(GLuint
* pal
)
122 fxMesaContext fxMesa
= fxMesaCurrentCtx
;
124 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
127 fprintf(stderr
, "fxmesa: gl3DfxSetPaletteEXT()\n");
129 for (i
= 0; i
< 256; i
++)
130 fprintf(stderr
, "%x\n", pal
[i
]);
134 fxMesa
->haveGlobalPaletteTexture
= 1;
136 FX_grTexDownloadTable(GR_TMU0
, GR_TEXTABLE_PALETTE
,
137 (GuTexPalette
*) pal
);
138 if (fxMesa
->haveTwoTMUs
)
139 FX_grTexDownloadTable(GR_TMU1
, GR_TEXTABLE_PALETTE
,
140 (GuTexPalette
*) pal
);
145 static GrScreenResolution_t
146 fxBestResolution(int width
, int height
, int aux
)
148 static int resolutions
[][5] = {
149 {320, 200, GR_RESOLUTION_320x200
, 2, 2},
150 {320, 240, GR_RESOLUTION_320x240
, 2, 2},
151 {512, 384, GR_RESOLUTION_512x384
, 2, 2},
152 {640, 400, GR_RESOLUTION_640x400
, 2, 2},
153 {640, 480, GR_RESOLUTION_640x480
, 2, 2},
154 {800, 600, GR_RESOLUTION_800x600
, 4, 2},
155 {960, 720, GR_RESOLUTION_960x720
, 6, 4}
156 #ifdef GR_RESOLUTION_1024x768
157 , {1024, 768, GR_RESOLUTION_1024x768
, 8, 4}
159 #ifdef GR_RESOLUTION_1280x1024
160 , {1280, 1024, GR_RESOLUTION_1280x1024
, 8, 8}
162 #ifdef GR_RESOLUTION_1600x1200
163 , {1600, 1200, GR_RESOLUTION_1600x1200
, 16, 8}
166 int NUM_RESOLUTIONS
= sizeof(resolutions
) / (sizeof(int) * 5);
168 GrScreenResolution_t lastvalidres
= resolutions
[4][2];
172 if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
== GR_SSTTYPE_VOODOO
) {
173 fbmem
= glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
.fbRam
;
175 if (glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
.sliDetect
)
178 else if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
== GR_SSTTYPE_SST96
)
179 fbmem
= glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.SST96Config
.fbRam
;
183 /* A work around for BZFlag */
185 if ((width
== 1) && (height
== 1)) {
190 for (i
= 0; i
< NUM_RESOLUTIONS
; i
++)
191 if (resolutions
[i
][4 - aux
] <= fbmem
) {
192 if ((width
<= resolutions
[i
][0]) && (height
<= resolutions
[i
][1]))
193 return resolutions
[i
][2];
195 lastvalidres
= resolutions
[i
][2];
202 fxMesaContext GLAPIENTRY
203 fxMesaCreateBestContext(GLuint win
, GLint width
, GLint height
,
204 const GLint attribList
[])
206 GrScreenRefresh_t refresh
;
209 refresh
= GR_REFRESH_75Hz
;
211 if (getenv("SST_SCREENREFRESH")) {
212 if (!strcmp(getenv("SST_SCREENREFRESH"), "60"))
213 refresh
= GR_REFRESH_60Hz
;
214 if (!strcmp(getenv("SST_SCREENREFRESH"), "70"))
215 refresh
= GR_REFRESH_70Hz
;
216 if (!strcmp(getenv("SST_SCREENREFRESH"), "72"))
217 refresh
= GR_REFRESH_72Hz
;
218 if (!strcmp(getenv("SST_SCREENREFRESH"), "75"))
219 refresh
= GR_REFRESH_75Hz
;
220 if (!strcmp(getenv("SST_SCREENREFRESH"), "80"))
221 refresh
= GR_REFRESH_80Hz
;
222 if (!strcmp(getenv("SST_SCREENREFRESH"), "85"))
223 refresh
= GR_REFRESH_85Hz
;
224 if (!strcmp(getenv("SST_SCREENREFRESH"), "90"))
225 refresh
= GR_REFRESH_90Hz
;
226 if (!strcmp(getenv("SST_SCREENREFRESH"), "100"))
227 refresh
= GR_REFRESH_100Hz
;
228 if (!strcmp(getenv("SST_SCREENREFRESH"), "120"))
229 refresh
= GR_REFRESH_120Hz
;
233 for (i
= 0; attribList
[i
] != FXMESA_NONE
; i
++)
234 if ((attribList
[i
] == FXMESA_ALPHA_SIZE
) ||
235 (attribList
[i
] == FXMESA_DEPTH_SIZE
)) {
236 if (attribList
[++i
] > 0) {
242 res
= fxBestResolution(width
, height
, aux
);
244 return fxMesaCreateContext(win
, res
, refresh
, attribList
);
252 signal(SIGINT
, SIG_IGN
);
253 signal(SIGHUP
, SIG_IGN
);
254 signal(SIGPIPE
, SIG_IGN
);
255 signal(SIGFPE
, SIG_IGN
);
256 signal(SIGBUS
, SIG_IGN
);
257 signal(SIGILL
, SIG_IGN
);
258 signal(SIGSEGV
, SIG_IGN
);
259 signal(SIGTERM
, SIG_IGN
);
264 * Create a new FX/Mesa context and return a handle to it.
266 fxMesaContext GLAPIENTRY
267 fxMesaCreateContext(GLuint win
,
268 GrScreenResolution_t res
,
269 GrScreenRefresh_t ref
, const GLint attribList
[])
271 fxMesaContext fxMesa
= NULL
;
274 GLboolean doubleBuffer
= GL_FALSE
;
275 GLboolean alphaBuffer
= GL_FALSE
;
276 GLboolean verbose
= GL_FALSE
;
278 GLint stencilSize
= 0;
280 GLcontext
*shareCtx
= NULL
;
282 /*FX_GrContext_t glideContext = 0; */
287 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
288 fprintf(stderr
, "fxmesa: fxMesaCreateContext() Start\n");
291 if (getenv("MESA_FX_INFO"))
296 while (attribList
[i
] != FXMESA_NONE
) {
297 switch (attribList
[i
]) {
298 case FXMESA_DOUBLEBUFFER
:
299 doubleBuffer
= GL_TRUE
;
301 case FXMESA_ALPHA_SIZE
:
303 alphaBuffer
= attribList
[i
] > 0;
307 case FXMESA_DEPTH_SIZE
:
309 depthSize
= attribList
[i
];
315 case FXMESA_STENCIL_SIZE
:
317 stencilSize
= attribList
[i
];
319 case FXMESA_ACCUM_SIZE
:
321 accumSize
= attribList
[i
];
323 /* XXX ugly hack here for sharing display lists */
324 #define FXMESA_SHARE_CONTEXT 990099 /* keep in sync with xmesa1.c! */
325 case FXMESA_SHARE_CONTEXT
:
328 const void *vPtr
= &attribList
[i
];
329 GLcontext
**ctx
= (GLcontext
**) vPtr
;
334 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
335 fprintf(stderr
, "fxmesa: fxMesaCreateContext() End (defualt)\n");
342 /* A workaround for Linux GLQuake */
343 if (depthSize
&& alphaBuffer
)
346 if ((type
= fxQueryHardware()) < 0) {
348 "fx Driver: ERROR no Voodoo1/2 Graphics or Voodoo Rush !\n");
352 if (type
== GR_SSTTYPE_VOODOO
)
355 grSstSelect(glbCurrentBoard
);
357 fxMesa
= (fxMesaContext
) calloc(1, sizeof(struct tfxMesaContext
));
363 if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
== GR_SSTTYPE_VOODOO
)
364 fxMesa
->haveTwoTMUs
=
365 (glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
.nTexelfx
>
367 else if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
== GR_SSTTYPE_SST96
)
368 fxMesa
->haveTwoTMUs
=
369 (glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.SST96Config
.nTexelfx
>
372 fxMesa
->haveTwoTMUs
= GL_FALSE
;
374 fxMesa
->haveDoubleBuffer
= doubleBuffer
;
375 fxMesa
->haveAlphaBuffer
= alphaBuffer
;
376 fxMesa
->haveGlobalPaletteTexture
= GL_FALSE
;
377 fxMesa
->haveZBuffer
= depthSize
? 1 : 0;
378 fxMesa
->verbose
= verbose
;
379 fxMesa
->board
= glbCurrentBoard
;
382 fxMesa
->glideContext
= FX_grSstWinOpen((FxU32
) win
, res
, ref
,
383 #ifdef FXMESA_USE_ARGB
388 GR_ORIGIN_LOWER_LEFT
, 2, aux
);
389 if (!fxMesa
->glideContext
) {
390 errorstr
= "grSstWinOpen";
395 * Pixel tables are used during pixel read-back
396 * Either initialize them for RGB or BGR order.
397 * Also determine if we need vertex snapping.
400 fxMesa
->snapVertices
= GL_TRUE
; /* play it safe */
402 #ifdef FXMESA_USE_ARGB
403 useBGR
= GL_FALSE
; /* Force RGB pixel order */
404 system
= "FXMESA_USE_ARGB";
406 if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
== GR_SSTTYPE_VOODOO
) {
407 /* jk991130 - Voodoo 3s don't use BGR. Query the # of TMUs
408 * as Voodoo3s have 2 TMUs on board, Banshee has only 1
409 * bk000413 - another suggestion from Joseph Kain is using
410 * VendorID 0x121a for all 3dfx boards
411 * DeviceID VG 1/V2 2/VB 3/V3 5
412 * For now we cehck for known BGR devices, and presume
413 * everything else to be a V3/RGB.
415 GrVoodooConfig_t
*voodoo
;
416 voodoo
= &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
;
418 if (voodoo
->nTexelfx
== 1) {
419 /* Voodoo1 or Banshee */
423 else if (voodoo
->nTexelfx
== 2 &&
424 voodoo
->fbiRev
== 260 &&
425 voodoo
->tmuConfig
[0].tmuRev
== 4 &&
426 (voodoo
->tmuConfig
[0].tmuRam
== 2 ||
427 voodoo
->tmuConfig
[0].tmuRam
== 4)) {
431 fxMesa
->snapVertices
= GL_FALSE
;
433 else if (voodoo
->nTexelfx
== 2 &&
434 voodoo
->fbiRev
== 2 &&
435 voodoo
->tmuConfig
[0].tmuRev
== 1 &&
436 voodoo
->tmuConfig
[0].tmuRam
== 4) {
437 /* Quantum3D Obsidian 50/100 */
439 system
= "Quantum3D Obsidian";
443 * (voodoo->nTexelfx == 2 &&
444 * voodoo->fbiRev == 0 &&
445 * voodoo->tmuConfig[0].tmuRev == 148441048 &&
446 * voodoo->tmuConfig[0].tmuRam == 3)
448 * (voodoo->nTexelfx == 2 &&
449 * voodoo->fbiRev == 69634 &&
450 * voodoo->tmuConfig[0].tmuRev == 69634 &&
451 * voodoo->tmuConfig[0].tmuRam == 2 )
454 /* Presumed Voodoo3 */
457 fxMesa
->snapVertices
= GL_FALSE
;
461 "Voodoo: Texelfx: %d / FBI Rev.: %d / TMU Rev.: %d / TMU RAM: %d\n",
462 voodoo
->nTexelfx
, voodoo
->fbiRev
, voodoo
->tmuConfig
[0].tmuRev
,
463 voodoo
->tmuConfig
[0].tmuRam
);
467 useBGR
= GL_FALSE
; /* use RGB pixel order otherwise */
468 system
= "non-voodoo";
469 fxMesa
->snapVertices
= GL_FALSE
;
471 #endif /*FXMESA_USE_ARGB */
474 fprintf(stderr
, "Voodoo pixel order: %s (%s)\n",
475 useBGR
? "BGR" : "RGB", system
);
476 fprintf(stderr
, "Vertex snapping: %d\n", fxMesa
->snapVertices
);
479 fxInitPixelTables(fxMesa
, useBGR
);
481 fxMesa
->width
= FX_grSstScreenWidth();
482 fxMesa
->height
= FX_grSstScreenHeight();
484 fxMesa
->clipMinX
= 0;
485 fxMesa
->clipMaxX
= fxMesa
->width
;
486 fxMesa
->clipMinY
= 0;
487 fxMesa
->clipMaxY
= fxMesa
->height
;
489 fxMesa
->screen_width
= fxMesa
->width
;
490 fxMesa
->screen_height
= fxMesa
->height
;
492 fxMesa
->new_state
= ~0;
495 fprintf(stderr
, "Voodoo Glide screen size: %dx%d\n",
496 (int) FX_grSstScreenWidth(), (int) FX_grSstScreenHeight());
498 fxMesa
->glVis
= _mesa_create_visual(GL_TRUE
, /* RGB mode */
499 doubleBuffer
, GL_FALSE
, /* stereo */
500 5, 6, 5, 0, /* RGBA bits */
502 depthSize
, /* depth_size */
503 stencilSize
, /* stencil_size */
504 accumSize
, accumSize
, accumSize
,
506 if (!fxMesa
->glVis
) {
507 errorstr
= "_mesa_create_visual";
511 ctx
= fxMesa
->glCtx
= _mesa_create_context(fxMesa
->glVis
,
513 (void *) fxMesa
, GL_TRUE
);
515 errorstr
= "_mesa_create_context";
520 if (!fxDDInitFxMesaContext(fxMesa
)) {
521 errorstr
= "fxDDInitFxMesaContext failed";
526 fxMesa
->glBuffer
= _mesa_create_framebuffer(fxMesa
->glVis
, GL_FALSE
, /* no software depth */
527 fxMesa
->glVis
->stencilBits
> 0,
528 fxMesa
->glVis
->accumRedBits
>
530 fxMesa
->glVis
->alphaBits
> 0);
531 if (!fxMesa
->glBuffer
) {
532 errorstr
= "_mesa_create_framebuffer";
538 /* install signal handlers */
539 #if defined(__linux__)
540 /* Only install if environment var. is not set. */
541 if (fxMesa
->glCtx
->CatchSignals
&& !getenv("MESA_FX_NO_SIGNALS")) {
542 signal(SIGINT
, cleangraphics_handler
);
543 signal(SIGHUP
, cleangraphics_handler
);
544 signal(SIGPIPE
, cleangraphics_handler
);
545 signal(SIGFPE
, cleangraphics_handler
);
546 signal(SIGBUS
, cleangraphics_handler
);
547 signal(SIGILL
, cleangraphics_handler
);
548 signal(SIGSEGV
, cleangraphics_handler
);
549 signal(SIGTERM
, cleangraphics_handler
);
553 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
554 fprintf(stderr
, "fxmesa: fxMesaCreateContext() End\n");
561 if (fxMesa
->glideContext
)
562 FX_grSstWinClose(fxMesa
->glideContext
);
563 fxMesa
->glideContext
= 0;
567 if (fxMesa
->fogTable
)
568 free(fxMesa
->fogTable
);
569 if (fxMesa
->glBuffer
)
570 _mesa_destroy_framebuffer(fxMesa
->glBuffer
);
572 _mesa_destroy_visual(fxMesa
->glVis
);
574 _mesa_destroy_context(fxMesa
->glCtx
);
578 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
579 fprintf(stderr
, "fxmesa: fxMesaCreateContext() End (%s)\n", errorstr
);
586 * Function to set the new window size in the context (mainly for the Voodoo Rush)
589 fxMesaUpdateScreenSize(fxMesaContext fxMesa
)
591 fxMesa
->width
= FX_grSstScreenWidth();
592 fxMesa
->height
= FX_grSstScreenHeight();
597 * Destroy the given FX/Mesa context.
600 fxMesaDestroyContext(fxMesaContext fxMesa
)
602 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
603 fprintf(stderr
, "fxmesa: fxMesaDestroyContext()\n");
609 if (fxMesa
->verbose
) {
610 fprintf(stderr
, "Misc Stats:\n");
611 fprintf(stderr
, " # swap buffer: %u\n", fxMesa
->stats
.swapBuffer
);
613 if (!fxMesa
->stats
.swapBuffer
)
614 fxMesa
->stats
.swapBuffer
= 1;
616 fprintf(stderr
, "Textures Stats:\n");
617 fprintf(stderr
, " Free texture memory on TMU0: %d:\n",
618 fxMesa
->freeTexMem
[FX_TMU0
]);
619 if (fxMesa
->haveTwoTMUs
)
620 fprintf(stderr
, " Free texture memory on TMU1: %d:\n",
621 fxMesa
->freeTexMem
[FX_TMU1
]);
622 fprintf(stderr
, " # request to TMM to upload a texture objects: %u\n",
623 fxMesa
->stats
.reqTexUpload
);
625 " # request to TMM to upload a texture objects per swapbuffer: %.2f\n",
626 fxMesa
->stats
.reqTexUpload
/ (float) fxMesa
->stats
.swapBuffer
);
627 fprintf(stderr
, " # texture objects uploaded: %u\n",
628 fxMesa
->stats
.texUpload
);
629 fprintf(stderr
, " # texture objects uploaded per swapbuffer: %.2f\n",
630 fxMesa
->stats
.texUpload
/ (float) fxMesa
->stats
.swapBuffer
);
631 fprintf(stderr
, " # MBs uploaded to texture memory: %.2f\n",
632 fxMesa
->stats
.memTexUpload
/ (float) (1 << 20));
634 " # MBs uploaded to texture memory per swapbuffer: %.2f\n",
635 (fxMesa
->stats
.memTexUpload
/
636 (float) fxMesa
->stats
.swapBuffer
) / (float) (1 << 20));
641 fxDDDestroyFxMesaContext(fxMesa
);
642 _mesa_destroy_visual(fxMesa
->glVis
);
643 _mesa_destroy_context(fxMesa
->glCtx
);
644 _mesa_destroy_framebuffer(fxMesa
->glBuffer
);
647 FX_grSstWinClose(fxMesa
->glideContext
);
651 if (fxMesa
== fxMesaCurrentCtx
)
652 fxMesaCurrentCtx
= NULL
;
657 * Make the specified FX/Mesa context the current one.
660 fxMesaMakeCurrent(fxMesaContext fxMesa
)
662 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
663 fprintf(stderr
, "fxmesa: fxMesaMakeCurrent(...) Start\n");
667 _mesa_make_current(NULL
, NULL
);
668 fxMesaCurrentCtx
= NULL
;
670 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
671 fprintf(stderr
, "fxmesa: fxMesaMakeCurrent(NULL) End\n");
677 /* if this context is already the current one, we can return early */
678 if (fxMesaCurrentCtx
== fxMesa
679 && fxMesaCurrentCtx
->glCtx
== _mesa_get_current_context()) {
680 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
682 "fxmesa: fxMesaMakeCurrent(fxMesaCurrentCtx==fxMesa) End\n");
688 if (fxMesaCurrentCtx
)
689 grGlideGetState((GrState
*) fxMesaCurrentCtx
->state
);
691 fxMesaCurrentCtx
= fxMesa
;
693 grSstSelect(fxMesa
->board
);
694 grGlideSetState((GrState
*) fxMesa
->state
);
696 _mesa_make_current(fxMesa
->glCtx
, fxMesa
->glBuffer
);
698 fxSetupDDPointers(fxMesa
->glCtx
);
700 /* The first time we call MakeCurrent we set the initial viewport size */
701 if (fxMesa
->glCtx
->Viewport
.Width
== 0)
702 _mesa_set_viewport(fxMesa
->glCtx
, 0, 0, fxMesa
->width
, fxMesa
->height
);
704 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
705 fprintf(stderr
, "fxmesa: fxMesaMakeCurrent(...) End\n");
714 static GLuint prevPassed
= 0;
715 static GLuint prevFailed
= 0;
716 GLuint failed
, passed
;
719 FX_grSstPerfStats(&st
);
720 failed
= st
.zFuncFail
- st
.aFuncFail
- st
.chromaFail
;
721 passed
= st
.pixelsIn
- failed
;
722 printf("failed: %d passed: %d\n", failed
- prevFailed
,
723 passed
- prevPassed
);
732 * Swap front/back buffers for current context if double buffered.
735 fxMesaSwapBuffers(void)
737 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
739 "fxmesa: ------------------------------- fxMesaSwapBuffers() -------------------------------\n");
742 if (fxMesaCurrentCtx
) {
743 _mesa_notifySwapBuffers(fxMesaCurrentCtx
->glCtx
);
745 if (fxMesaCurrentCtx
->haveDoubleBuffer
) {
747 grBufferSwap(fxMesaCurrentCtx
->swapInterval
);
750 * Don't allow swap buffer commands to build up!
752 while (FX_grGetInteger(FX_PENDING_BUFFERSWAPS
) >
753 fxMesaCurrentCtx
->maxPendingSwapBuffers
)
754 /* The driver is able to sleep when waiting for the completation
755 of multiple swapbuffer operations instead of wasting
756 CPU time (NOTE: you must uncomment the following line in the
757 in order to enable this option) */
761 fxMesaCurrentCtx
->stats
.swapBuffer
++;
768 * Query 3Dfx hardware presence/kind
771 fxQueryHardware(void)
773 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
774 fprintf(stderr
, "fxmesa: fxQueryHardware() Start\n");
777 if (!glbGlideInitialized
) {
779 if (FX_grSstQueryHardware(&glbHWConfig
)) {
780 grSstSelect(glbCurrentBoard
);
783 if (getenv("MESA_FX_INFO")) {
786 FX_grGlideGetVersion(buf
);
787 fprintf(stderr
, "Voodoo Using Glide V%s\n", buf
);
788 fprintf(stderr
, "Voodoo Number of boards: %d\n",
789 glbHWConfig
.num_sst
);
791 if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
== GR_SSTTYPE_VOODOO
) {
792 GrVoodooConfig_t
*voodoo
;
794 &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
;
796 fprintf(stderr
, "Voodoo Framebuffer RAM: %d\n",
797 voodoo
->sliDetect
? (voodoo
->fbRam
*
799 fprintf(stderr
, "Voodoo Number of TMUs: %d\n",
801 fprintf(stderr
, "Voodoo fbRam: %d\n", voodoo
->fbRam
);
802 fprintf(stderr
, "Voodoo fbiRev: %d\n", voodoo
->fbiRev
);
804 fprintf(stderr
, "Voodoo SLI detected: %d\n",
807 else if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
==
809 GrSst96Config_t
*sst96
;
811 &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.SST96Config
;
812 fprintf(stderr
, "Voodoo Framebuffer RAM: %d\n", sst96
->fbRam
);
813 fprintf(stderr
, "Voodoo Number of TMUs: %d\n",
823 glbGlideInitialized
= 1;
825 #if defined(__WIN32__)
826 onexit((_onexit_t
) cleangraphics
);
827 #elif defined(__linux__)
828 /* Only register handler if environment variable is not defined. */
829 if (!getenv("MESA_FX_NO_SIGNALS")) {
830 atexit(cleangraphics
);
835 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
836 fprintf(stderr
, "fxmesa: fxQueryHardware() End (voodooo)\n");
839 return glbHWConfig
.SSTs
[glbCurrentBoard
].type
;
844 * Shutdown Glide library
847 fxCloseHardware(void)
849 if (glbGlideInitialized
) {
850 if (getenv("MESA_FX_INFO")) {
853 FX_grSstPerfStats(&st
);
854 fprintf(stderr
, "Pixels Stats:\n");
855 fprintf(stderr
, " # pixels processed (minus buffer clears): %u\n",
856 (unsigned) st
.pixelsIn
);
858 " # pixels not drawn due to chroma key test failure: %u\n",
859 (unsigned) st
.chromaFail
);
861 " # pixels not drawn due to depth test failure: %u\n",
862 (unsigned) st
.zFuncFail
);
864 " # pixels not drawn due to alpha test failure: %u\n",
865 (unsigned) st
.aFuncFail
);
867 " # pixels drawn (including buffer clears and LFB writes): %u\n",
868 (unsigned) st
.pixelsOut
);
871 if (glbTotNumCtx
== 0) {
873 glbGlideInitialized
= 0;
883 * Need this to provide at least one external definition.
885 extern int gl_fx_dummy_function_api(void);
887 gl_fx_dummy_function_api(void)