1 /* -*- mode: C; tab-width:8; -*- */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 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.
53 static fxMesaContext fxMesaCurrentCtx
=NULL
;
56 * Status of 3Dfx hardware initialization
59 static int glbGlideInitialized
=0;
60 static int glb3DfxPresent
=0;
61 static int glbTotNumCtx
=0;
63 GrHwConfiguration glbHWConfig
;
64 int glbCurrentBoard
=0;
67 #if defined(__WIN32__)
68 static int cleangraphics(void)
71 fxMesaDestroyContext(fxMesaCurrentCtx
);
75 #elif defined(__linux__)
76 static void cleangraphics(void)
79 fxMesaDestroyContext(fxMesaCurrentCtx
);
82 static void cleangraphics_handler(int s
)
84 fprintf(stderr
,"fxmesa: Received a not handled signal %d\n",s
);
94 * Select the Voodoo board to use when creating
97 GLboolean GLAPIENTRY
fxMesaSelectCurrentBoard(int n
)
101 if((n
<0) || (n
>=glbHWConfig
.num_sst
))
110 fxMesaContext GLAPIENTRY
fxMesaGetCurrentContext(void)
112 return fxMesaCurrentCtx
;
117 * The 3Dfx Global Palette extension for GLQuake.
118 * More a trick than a real extesion, use the shared global
121 extern void GLAPIENTRY
gl3DfxSetPaletteEXT(GLuint
*pal
); /* silence warning */
122 void GLAPIENTRY
gl3DfxSetPaletteEXT(GLuint
*pal
)
124 fxMesaContext fxMesa
=fxMesaCurrentCtx
;
126 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
129 fprintf(stderr
,"fxmesa: gl3DfxSetPaletteEXT()\n");
132 fprintf(stderr
,"%x\n",pal
[i
]);
136 fxMesa
->haveGlobalPaletteTexture
=1;
138 FX_grTexDownloadTable(GR_TMU0
,GR_TEXTABLE_PALETTE
,(GuTexPalette
*)pal
);
139 if (fxMesa
->haveTwoTMUs
)
140 FX_grTexDownloadTable(GR_TMU1
,GR_TEXTABLE_PALETTE
,(GuTexPalette
*)pal
);
145 static GrScreenResolution_t
fxBestResolution(int width
, int height
, int aux
)
147 static int resolutions
[][5]={
148 { 320, 200, GR_RESOLUTION_320x200
, 2, 2 },
149 { 320, 240, GR_RESOLUTION_320x240
, 2, 2 },
150 { 512, 384, GR_RESOLUTION_512x384
, 2, 2 },
151 { 640, 400, GR_RESOLUTION_640x400
, 2, 2 },
152 { 640, 480, GR_RESOLUTION_640x480
, 2, 2 },
153 { 800, 600, GR_RESOLUTION_800x600
, 4, 2 },
154 { 960, 720, GR_RESOLUTION_960x720
, 6, 4 }
155 #ifdef GR_RESOLUTION_1024x768
156 ,{ 1024, 768, GR_RESOLUTION_1024x768
, 8, 4 }
158 #ifdef GR_RESOLUTION_1280x1024
159 ,{ 1280, 1024, GR_RESOLUTION_1280x1024
, 8, 8 }
161 #ifdef GR_RESOLUTION_1600x1200
162 ,{ 1600, 1200, GR_RESOLUTION_1600x1200
, 16, 8 }
165 int NUM_RESOLUTIONS
= sizeof(resolutions
) / (sizeof(int)*5);
167 GrScreenResolution_t lastvalidres
=resolutions
[4][2];
171 if(glbHWConfig
.SSTs
[glbCurrentBoard
].type
==GR_SSTTYPE_VOODOO
) {
172 fbmem
=glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
.fbRam
;
174 if(glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
.sliDetect
)
176 } else if(glbHWConfig
.SSTs
[glbCurrentBoard
].type
==GR_SSTTYPE_SST96
)
177 fbmem
=glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.SST96Config
.fbRam
;
181 /* A work around for BZFlag */
183 if((width
==1) && (height
==1)) {
188 for(i
=0;i
<NUM_RESOLUTIONS
;i
++)
189 if(resolutions
[i
][4-aux
]<=fbmem
) {
190 if((width
<=resolutions
[i
][0]) && (height
<=resolutions
[i
][1]))
191 return resolutions
[i
][2];
193 lastvalidres
=resolutions
[i
][2];
200 fxMesaContext GLAPIENTRY
fxMesaCreateBestContext(GLuint win
,GLint width
, GLint height
,
201 const GLint attribList
[])
203 GrScreenRefresh_t refresh
;
206 refresh
=GR_REFRESH_75Hz
;
208 if(getenv("SST_SCREENREFRESH")) {
209 if(!strcmp(getenv("SST_SCREENREFRESH"),"60"))
210 refresh
=GR_REFRESH_60Hz
;
211 if(!strcmp(getenv("SST_SCREENREFRESH"),"70"))
212 refresh
=GR_REFRESH_70Hz
;
213 if(!strcmp(getenv("SST_SCREENREFRESH"),"72"))
214 refresh
=GR_REFRESH_72Hz
;
215 if(!strcmp(getenv("SST_SCREENREFRESH"),"75"))
216 refresh
=GR_REFRESH_75Hz
;
217 if(!strcmp(getenv("SST_SCREENREFRESH"),"80"))
218 refresh
=GR_REFRESH_80Hz
;
219 if(!strcmp(getenv("SST_SCREENREFRESH"),"85"))
220 refresh
=GR_REFRESH_85Hz
;
221 if(!strcmp(getenv("SST_SCREENREFRESH"),"90"))
222 refresh
=GR_REFRESH_90Hz
;
223 if(!strcmp(getenv("SST_SCREENREFRESH"),"100"))
224 refresh
=GR_REFRESH_100Hz
;
225 if(!strcmp(getenv("SST_SCREENREFRESH"),"120"))
226 refresh
=GR_REFRESH_120Hz
;
230 for(i
=0;attribList
[i
]!=FXMESA_NONE
;i
++)
231 if((attribList
[i
]==FXMESA_ALPHA_SIZE
) ||
232 (attribList
[i
]==FXMESA_DEPTH_SIZE
)) {
233 if(attribList
[++i
]>0) {
239 res
=fxBestResolution(width
,height
,aux
);
241 return fxMesaCreateContext(win
,res
,refresh
,attribList
);
248 signal(SIGINT
,SIG_IGN
);
249 signal(SIGHUP
,SIG_IGN
);
250 signal(SIGPIPE
,SIG_IGN
);
251 signal(SIGFPE
,SIG_IGN
);
252 signal(SIGBUS
,SIG_IGN
);
253 signal(SIGILL
,SIG_IGN
);
254 signal(SIGSEGV
,SIG_IGN
);
255 signal(SIGTERM
,SIG_IGN
);
260 * Create a new FX/Mesa context and return a handle to it.
262 fxMesaContext GLAPIENTRY
fxMesaCreateContext(GLuint win
,
263 GrScreenResolution_t res
,
264 GrScreenRefresh_t ref
,
265 const GLint attribList
[])
267 fxMesaContext fxMesa
= NULL
;
270 GLboolean doubleBuffer
=GL_FALSE
;
271 GLboolean alphaBuffer
=GL_FALSE
;
272 GLboolean verbose
=GL_FALSE
;
276 GLcontext
*shareCtx
= NULL
;
278 /*FX_GrContext_t glideContext = 0;*/
283 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
284 fprintf(stderr
,"fxmesa: fxMesaCreateContext() Start\n");
287 if(getenv("MESA_FX_INFO"))
292 while(attribList
[i
]!=FXMESA_NONE
) {
293 switch (attribList
[i
]) {
294 case FXMESA_DOUBLEBUFFER
:
295 doubleBuffer
=GL_TRUE
;
297 case FXMESA_ALPHA_SIZE
:
299 alphaBuffer
=attribList
[i
]>0;
303 case FXMESA_DEPTH_SIZE
:
305 depthSize
=attribList
[i
];
311 case FXMESA_STENCIL_SIZE
:
313 stencilSize
=attribList
[i
];
315 case FXMESA_ACCUM_SIZE
:
317 accumSize
=attribList
[i
];
319 /* XXX ugly hack here for sharing display lists */
320 #define FXMESA_SHARE_CONTEXT 990099 /* keep in sync with xmesa1.c! */
321 case FXMESA_SHARE_CONTEXT
:
324 const void *vPtr
= &attribList
[i
];
325 GLcontext
**ctx
= (GLcontext
**) vPtr
;
330 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
331 fprintf(stderr
,"fxmesa: fxMesaCreateContext() End (defualt)\n");
338 /* A workaround for Linux GLQuake */
339 if(depthSize
&& alphaBuffer
)
342 if ((type
=fxQueryHardware()) < 0) {
343 fprintf(stderr
,"fx Driver: ERROR no Voodoo1/2 Graphics or Voodoo Rush !\n");
347 if(type
==GR_SSTTYPE_VOODOO
)
350 grSstSelect(glbCurrentBoard
);
352 fxMesa
=(fxMesaContext
)calloc(1,sizeof(struct tfxMesaContext
));
358 if(glbHWConfig
.SSTs
[glbCurrentBoard
].type
==GR_SSTTYPE_VOODOO
)
359 fxMesa
->haveTwoTMUs
=(glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
.nTexelfx
> 1);
360 else if(glbHWConfig
.SSTs
[glbCurrentBoard
].type
==GR_SSTTYPE_SST96
)
361 fxMesa
->haveTwoTMUs
=(glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.SST96Config
.nTexelfx
> 1);
363 fxMesa
->haveTwoTMUs
=GL_FALSE
;
365 fxMesa
->haveDoubleBuffer
=doubleBuffer
;
366 fxMesa
->haveAlphaBuffer
=alphaBuffer
;
367 fxMesa
->haveGlobalPaletteTexture
=GL_FALSE
;
368 fxMesa
->haveZBuffer
=depthSize
? 1 : 0;
369 fxMesa
->verbose
=verbose
;
370 fxMesa
->board
=glbCurrentBoard
;
373 fxMesa
->glideContext
= FX_grSstWinOpen((FxU32
)win
,res
,ref
,
379 GR_ORIGIN_LOWER_LEFT
,
381 if (!fxMesa
->glideContext
){
382 errorstr
= "grSstWinOpen";
387 * Pixel tables are use during pixel read-back
388 * Either initialize them for RGB or BGR order.
391 useBGR
= GL_FALSE
; /* Force RGB pixel order */
392 system
= "FXMESA_USE_ARGB";
394 if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
== GR_SSTTYPE_VOODOO
) {
395 /* jk991130 - Voodoo 3s don't use BGR. Query the # of TMUs
396 * as Voodoo3s have 2 TMUs on board, Banshee has only 1
397 * bk000413 - another suggestion from Joseph Kain is using
398 * VendorID 0x121a for all 3dfx boards
399 * DeviceID VG 1/V2 2/VB 3/V3 5
400 * For now we cehck for known BGR devices, and presume
401 * everything else to be a V3/RGB.
403 GrVoodooConfig_t
*voodoo
;
404 voodoo
= &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
;
406 if (voodoo
->nTexelfx
== 1) {
407 /* Voodoo1 or Banshee */
411 else if (voodoo
->nTexelfx
== 2 &&
412 voodoo
->fbiRev
== 260 &&
413 voodoo
->tmuConfig
[0].tmuRev
== 4 &&
414 (voodoo
->tmuConfig
[0].tmuRam
== 2 ||
415 voodoo
->tmuConfig
[0].tmuRam
== 4)) {
420 else if (voodoo
->nTexelfx
== 2 &&
421 voodoo
->fbiRev
== 2 &&
422 voodoo
->tmuConfig
[0].tmuRev
== 1 &&
423 voodoo
->tmuConfig
[0].tmuRam
== 4) {
424 /* Quantum3D Obsidian 50/100 */
426 system
= "Quantum3D Obsidian";
430 * (voodoo->nTexelfx == 2 &&
431 * voodoo->fbiRev == 0 &&
432 * voodoo->tmuConfig[0].tmuRev == 148441048 &&
433 * voodoo->tmuConfig[0].tmuRam == 3)
435 * (voodoo->nTexelfx == 2 &&
436 * voodoo->fbiRev == 69634 &&
437 * voodoo->tmuConfig[0].tmuRev == 69634 &&
438 * voodoo->tmuConfig[0].tmuRam == 2 )
441 /* Presumed Voodoo3 */
445 if (getenv("MESA_FX_INFO")) {
446 printf("Voodoo: Texelfx: %d / FBI Rev.: %d / TMU Rev.: %d / TMU RAM: %d\n",
449 voodoo
->tmuConfig
[0].tmuRev
,
450 voodoo
->tmuConfig
[0].tmuRam
);
454 useBGR
= GL_FALSE
; /* use RGB pixel order otherwise */
455 system
= "non-voodoo";
457 #endif /*FXMESA_USE_ARGB*/
459 if (getenv("MESA_FX_INFO"))
460 printf("Voodoo pixel order: %s (%s)\n", useBGR
? "BGR" : "RGB", system
);
462 fxInitPixelTables(fxMesa
, useBGR
);
464 fxMesa
->width
=FX_grSstScreenWidth();
465 fxMesa
->height
=FX_grSstScreenHeight();
467 fxMesa
->clipMinX
= 0;
468 fxMesa
->clipMaxX
= fxMesa
->width
;
469 fxMesa
->clipMinY
= 0;
470 fxMesa
->clipMaxY
= fxMesa
->height
;
472 fxMesa
->screen_width
= fxMesa
->width
;
473 fxMesa
->screen_height
= fxMesa
->height
;
475 fxMesa
->new_state
= ~0;
478 fprintf(stderr
,"Voodoo Glide screen size: %dx%d\n",
479 (int)FX_grSstScreenWidth(),(int)FX_grSstScreenHeight());
481 fxMesa
->glVis
=_mesa_create_visual(GL_TRUE
, /* RGB mode */
483 GL_FALSE
, /* stereo */
484 5,6,5,0, /* RGBA bits */
486 depthSize
, /* depth_size */
487 stencilSize
, /* stencil_size */
488 accumSize
, accumSize
, accumSize
, accumSize
,
490 if (!fxMesa
->glVis
) {
491 errorstr
= "_mesa_create_visual";
495 ctx
= fxMesa
->glCtx
=_mesa_create_context(fxMesa
->glVis
,
496 shareCtx
, /* share list context */
497 (void *) fxMesa
, GL_TRUE
);
499 errorstr
= "_mesa_create_context";
504 if (!fxDDInitFxMesaContext( fxMesa
)) {
505 errorstr
= "fxDDInitFxMesaContext failed";
510 fxMesa
->glBuffer
=_mesa_create_framebuffer(fxMesa
->glVis
,
511 GL_FALSE
, /* no software depth */
512 fxMesa
->glVis
->StencilBits
> 0,
513 fxMesa
->glVis
->AccumRedBits
> 0,
514 fxMesa
->glVis
->AlphaBits
> 0 );
515 if (!fxMesa
->glBuffer
) {
516 errorstr
= "_mesa_create_framebuffer";
522 /* install signal handlers */
523 #if defined(__linux__)
524 /* Only install if environment var. is not set. */
525 if (fxMesa
->glCtx
->CatchSignals
&& !getenv("MESA_FX_NO_SIGNALS")) {
526 signal(SIGINT
,cleangraphics_handler
);
527 signal(SIGHUP
,cleangraphics_handler
);
528 signal(SIGPIPE
,cleangraphics_handler
);
529 signal(SIGFPE
,cleangraphics_handler
);
530 signal(SIGBUS
,cleangraphics_handler
);
531 signal(SIGILL
,cleangraphics_handler
);
532 signal(SIGSEGV
,cleangraphics_handler
);
533 signal(SIGTERM
,cleangraphics_handler
);
537 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
538 fprintf(stderr
,"fxmesa: fxMesaCreateContext() End\n");
545 if (fxMesa
->glideContext
)
546 FX_grSstWinClose(fxMesa
->glideContext
);
547 fxMesa
->glideContext
= 0;
551 if (fxMesa
->fogTable
)
552 free(fxMesa
->fogTable
);
553 if (fxMesa
->glBuffer
)
554 _mesa_destroy_framebuffer(fxMesa
->glBuffer
);
556 _mesa_destroy_visual(fxMesa
->glVis
);
558 _mesa_destroy_context(fxMesa
->glCtx
);
562 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
563 fprintf(stderr
,"fxmesa: fxMesaCreateContext() End (%s)\n",errorstr
);
570 * Function to set the new window size in the context (mainly for the Voodoo Rush)
572 void GLAPIENTRY
fxMesaUpdateScreenSize(fxMesaContext fxMesa
)
574 fxMesa
->width
=FX_grSstScreenWidth();
575 fxMesa
->height
=FX_grSstScreenHeight();
580 * Destroy the given FX/Mesa context.
582 void GLAPIENTRY
fxMesaDestroyContext(fxMesaContext fxMesa
)
584 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
585 fprintf(stderr
,"fxmesa: fxMesaDestroyContext()\n");
591 if(fxMesa
->verbose
) {
592 fprintf(stderr
,"Misc Stats:\n");
593 fprintf(stderr
," # swap buffer: %u\n",fxMesa
->stats
.swapBuffer
);
595 if(!fxMesa
->stats
.swapBuffer
)
596 fxMesa
->stats
.swapBuffer
=1;
598 fprintf(stderr
,"Textures Stats:\n");
599 fprintf(stderr
," Free texture memory on TMU0: %d:\n",fxMesa
->freeTexMem
[FX_TMU0
]);
600 if(fxMesa
->haveTwoTMUs
)
601 fprintf(stderr
," Free texture memory on TMU1: %d:\n",fxMesa
->freeTexMem
[FX_TMU1
]);
602 fprintf(stderr
," # request to TMM to upload a texture objects: %u\n",
603 fxMesa
->stats
.reqTexUpload
);
604 fprintf(stderr
," # request to TMM to upload a texture objects per swapbuffer: %.2f\n",
605 fxMesa
->stats
.reqTexUpload
/(float)fxMesa
->stats
.swapBuffer
);
606 fprintf(stderr
," # texture objects uploaded: %u\n",
607 fxMesa
->stats
.texUpload
);
608 fprintf(stderr
," # texture objects uploaded per swapbuffer: %.2f\n",
609 fxMesa
->stats
.texUpload
/(float)fxMesa
->stats
.swapBuffer
);
610 fprintf(stderr
," # MBs uploaded to texture memory: %.2f\n",
611 fxMesa
->stats
.memTexUpload
/(float)(1<<20));
612 fprintf(stderr
," # MBs uploaded to texture memory per swapbuffer: %.2f\n",
613 (fxMesa
->stats
.memTexUpload
/(float)fxMesa
->stats
.swapBuffer
)/(float)(1<<20));
618 fxDDDestroyFxMesaContext(fxMesa
);
619 _mesa_destroy_visual(fxMesa
->glVis
);
620 _mesa_destroy_context(fxMesa
->glCtx
);
621 _mesa_destroy_framebuffer(fxMesa
->glBuffer
);
624 FX_grSstWinClose(fxMesa
->glideContext
);
628 if(fxMesa
==fxMesaCurrentCtx
)
629 fxMesaCurrentCtx
=NULL
;
634 * Make the specified FX/Mesa context the current one.
636 void GLAPIENTRY
fxMesaMakeCurrent(fxMesaContext fxMesa
)
638 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
639 fprintf(stderr
,"fxmesa: fxMesaMakeCurrent(...) Start\n");
643 _mesa_make_current(NULL
,NULL
);
644 fxMesaCurrentCtx
=NULL
;
646 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
647 fprintf(stderr
,"fxmesa: fxMesaMakeCurrent(NULL) End\n");
653 /* if this context is already the current one, we can return early */
654 if (fxMesaCurrentCtx
== fxMesa
655 && fxMesaCurrentCtx
->glCtx
== _mesa_get_current_context()) {
656 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
657 fprintf(stderr
,"fxmesa: fxMesaMakeCurrent(fxMesaCurrentCtx==fxMesa) End\n");
664 grGlideGetState((GrState
*)fxMesaCurrentCtx
->state
);
666 fxMesaCurrentCtx
=fxMesa
;
668 grSstSelect(fxMesa
->board
);
669 grGlideSetState((GrState
*)fxMesa
->state
);
671 _mesa_make_current(fxMesa
->glCtx
,fxMesa
->glBuffer
);
673 fxSetupDDPointers(fxMesa
->glCtx
);
675 /* The first time we call MakeCurrent we set the initial viewport size */
676 if(fxMesa
->glCtx
->Viewport
.Width
==0)
677 gl_Viewport(fxMesa
->glCtx
,0,0,fxMesa
->width
,fxMesa
->height
);
679 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
680 fprintf(stderr
,"fxmesa: fxMesaMakeCurrent(...) End\n");
686 static void QueryCounters(void)
688 static GLuint prevPassed
= 0;
689 static GLuint prevFailed
= 0;
690 GLuint failed
, passed
;
693 FX_grSstPerfStats(&st
);
694 failed
= st
.zFuncFail
- st
.aFuncFail
- st
.chromaFail
;
695 passed
= st
.pixelsIn
- failed
;
696 printf("failed: %d passed: %d\n", failed
- prevFailed
, passed
- prevPassed
);
705 * Swap front/back buffers for current context if double buffered.
707 void GLAPIENTRY
fxMesaSwapBuffers(void)
709 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
710 fprintf(stderr
,"fxmesa: ------------------------------- fxMesaSwapBuffers() -------------------------------\n");
713 if(fxMesaCurrentCtx
) {
714 _mesa_swapbuffers( fxMesaCurrentCtx
->glCtx
);
716 if(fxMesaCurrentCtx
->haveDoubleBuffer
) {
718 grBufferSwap(fxMesaCurrentCtx
->swapInterval
);
721 * Don't allow swap buffer commands to build up!
723 while(FX_grGetInteger(FX_PENDING_BUFFERSWAPS
)>fxMesaCurrentCtx
->maxPendingSwapBuffers
)
724 /* The driver is able to sleep when waiting for the completation
725 of multiple swapbuffer operations instead of wasting
726 CPU time (NOTE: you must uncomment the following line in the
727 in order to enable this option) */
731 fxMesaCurrentCtx
->stats
.swapBuffer
++;
738 * Query 3Dfx hardware presence/kind
740 int GLAPIENTRY
fxQueryHardware(void)
742 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
743 fprintf(stderr
,"fxmesa: fxQueryHardware() Start\n");
746 if (!glbGlideInitialized
) {
748 if (FX_grSstQueryHardware(&glbHWConfig
)) {
749 grSstSelect(glbCurrentBoard
);
752 if (getenv("MESA_FX_INFO")) {
755 FX_grGlideGetVersion(buf
);
756 fprintf(stderr
, "Voodoo Using Glide V%s\n", buf
);
757 fprintf(stderr
, "Voodoo Number of boards: %d\n", glbHWConfig
.num_sst
);
759 if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
== GR_SSTTYPE_VOODOO
) {
760 GrVoodooConfig_t
*voodoo
;
761 voodoo
= &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.VoodooConfig
;
763 fprintf(stderr
, "Voodoo Framebuffer RAM: %d\n",
764 voodoo
->sliDetect
? (voodoo
->fbRam
*2) : voodoo
->fbRam
);
765 fprintf(stderr
, "Voodoo Number of TMUs: %d\n", voodoo
->nTexelfx
);
766 fprintf(stderr
, "Voodoo fbRam: %d\n", voodoo
->fbRam
);
767 fprintf(stderr
, "Voodoo fbiRev: %d\n", voodoo
->fbiRev
);
769 fprintf(stderr
,"Voodoo SLI detected: %d\n", voodoo
->sliDetect
);
771 else if (glbHWConfig
.SSTs
[glbCurrentBoard
].type
== GR_SSTTYPE_SST96
) {
772 GrSst96Config_t
*sst96
;
773 sst96
= &glbHWConfig
.SSTs
[glbCurrentBoard
].sstBoard
.SST96Config
;
774 fprintf(stderr
, "Voodoo Framebuffer RAM: %d\n", sst96
->fbRam
);
775 fprintf(stderr
, "Voodoo Number of TMUs: %d\n", sst96
->nTexelfx
);
784 glbGlideInitialized
= 1;
786 #if defined(__WIN32__)
787 onexit((_onexit_t
)cleangraphics
);
788 #elif defined(__linux__)
789 /* Only register handler if environment variable is not defined. */
790 if (!getenv("MESA_FX_NO_SIGNALS")) {
791 atexit(cleangraphics
);
796 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
797 fprintf(stderr
,"fxmesa: fxQueryHardware() End (voodooo)\n");
800 return glbHWConfig
.SSTs
[glbCurrentBoard
].type
;
805 * Shutdown Glide library
807 void GLAPIENTRY
fxCloseHardware(void)
809 if (glbGlideInitialized
) {
810 if (getenv("MESA_FX_INFO")) {
813 FX_grSstPerfStats(&st
);
814 fprintf(stderr
,"Pixels Stats:\n");
815 fprintf(stderr
," # pixels processed (minus buffer clears): %u\n",(unsigned)st
.pixelsIn
);
816 fprintf(stderr
," # pixels not drawn due to chroma key test failure: %u\n",(unsigned)st
.chromaFail
);
817 fprintf(stderr
," # pixels not drawn due to depth test failure: %u\n",(unsigned)st
.zFuncFail
);
818 fprintf(stderr
," # pixels not drawn due to alpha test failure: %u\n",(unsigned)st
.aFuncFail
);
819 fprintf(stderr
," # pixels drawn (including buffer clears and LFB writes): %u\n",(unsigned)st
.pixelsOut
);
822 if (glbTotNumCtx
== 0) {
824 glbGlideInitialized
= 0;
834 * Need this to provide at least one external definition.
836 extern int gl_fx_dummy_function_api(void);
837 int gl_fx_dummy_function_api(void)