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"
49 /* | VERBOSE_VARRAY */
50 /* | VERBOSE_TEXTURE */
51 /* | VERBOSE_IMMEDIATE */
52 /* | VERBOSE_PIPELINE */
53 /* | VERBOSE_DRIVER */
56 /* | VERBOSE_DISPLAY_LIST */
57 /* | VERBOSE_LIGHTING */
63 static fxMesaContext fxMesaCurrentCtx
= NULL
;
66 * Status of 3Dfx hardware initialization
69 static int glbGlideInitialized
= 0;
70 static int glb3DfxPresent
= 0;
71 static int glbTotNumCtx
= 0;
73 static GrHwConfiguration glbHWConfig
;
74 static int glbCurrentBoard
= 0;
77 #if defined(__WIN32__)
82 fxMesaDestroyContext(fxMesaCurrentCtx
);
86 #elif defined(__linux__)
91 fxMesaDestroyContext(fxMesaCurrentCtx
);
95 cleangraphics_handler(int s
)
97 fprintf(stderr
, "fxmesa: ERROR: received a not handled signal %d\n", s
);
107 * Query 3Dfx hardware presence/kind
109 static GLboolean GLAPIENTRY
fxQueryHardware (void)
111 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
112 fprintf(stderr
, "fxQueryHardware()\n");
115 if (!glbGlideInitialized
) {
117 glb3DfxPresent
= FX_grSstQueryHardware(&glbHWConfig
);
119 glbGlideInitialized
= 1;
121 #if defined(__WIN32__)
122 _onexit((_onexit_t
) cleangraphics
);
123 #elif defined(__linux__)
124 /* Only register handler if environment variable is not defined. */
125 if (!getenv("MESA_FX_NO_SIGNALS")) {
126 atexit(cleangraphics
);
131 return glb3DfxPresent
;
136 * Select the Voodoo board to use when creating
139 GLint GLAPIENTRY
fxMesaSelectCurrentBoard (int n
)
143 if ((n
< 0) || (n
>= glbHWConfig
.num_sst
))
146 return glbHWConfig
.SSTs
[glbCurrentBoard
= n
].type
;
150 fxMesaContext GLAPIENTRY
fxMesaGetCurrentContext (void)
152 return fxMesaCurrentCtx
;
156 void GLAPIENTRY
fxGetScreenGeometry (GLint
*w
, GLint
*h
)
161 if (fxMesaCurrentCtx
!= NULL
) {
162 width
= fxMesaCurrentCtx
->screen_width
;
163 height
= fxMesaCurrentCtx
->screen_height
;
176 * The 3Dfx Global Palette extension for GLQuake.
177 * More a trick than a real extesion, use the shared global
180 extern void GLAPIENTRY
gl3DfxSetPaletteEXT(GLuint
* pal
); /* silence warning */
182 gl3DfxSetPaletteEXT(GLuint
* pal
)
184 fxMesaContext fxMesa
= fxMesaCurrentCtx
;
186 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
189 fprintf(stderr
, "gl3DfxSetPaletteEXT(...)\n");
191 for (i
= 0; i
< 256; i
++) {
192 fprintf(stderr
, "\t%x\n", pal
[i
]);
197 fxMesa
->haveGlobalPaletteTexture
= 1;
199 grTexDownloadTable(GR_TEXTABLE_PALETTE
, (GuTexPalette
*) pal
);
204 static GrScreenResolution_t
fxBestResolution (int width
, int height
)
206 static int resolutions
[][3] = {
207 { GR_RESOLUTION_320x200
, 320, 200 },
208 { GR_RESOLUTION_320x240
, 320, 240 },
209 { GR_RESOLUTION_400x256
, 400, 256 },
210 { GR_RESOLUTION_512x384
, 512, 384 },
211 { GR_RESOLUTION_640x200
, 640, 200 },
212 { GR_RESOLUTION_640x350
, 640, 350 },
213 { GR_RESOLUTION_640x400
, 640, 400 },
214 { GR_RESOLUTION_640x480
, 640, 480 },
215 { GR_RESOLUTION_800x600
, 800, 600 },
216 { GR_RESOLUTION_960x720
, 960, 720 },
217 { GR_RESOLUTION_856x480
, 856, 480 },
218 { GR_RESOLUTION_512x256
, 512, 256 },
219 { GR_RESOLUTION_1024x768
, 1024, 768 },
220 { GR_RESOLUTION_1280x1024
, 1280, 1024 },
221 { GR_RESOLUTION_1600x1200
, 1600, 1200 },
222 { GR_RESOLUTION_400x300
, 400, 300 },
223 { GR_RESOLUTION_1152x864
, 1152, 864 },
224 { GR_RESOLUTION_1280x960
, 1280, 960 },
225 { GR_RESOLUTION_1600x1024
, 1600, 1024 },
226 { GR_RESOLUTION_1792x1344
, 1792, 1344 },
227 { GR_RESOLUTION_1856x1392
, 1856, 1392 },
228 { GR_RESOLUTION_1920x1440
, 1920, 1440 },
229 { GR_RESOLUTION_2048x1536
, 2048, 1536 },
230 { GR_RESOLUTION_2048x2048
, 2048, 2048 }
234 int lastvalidres
= GR_RESOLUTION_640x480
;
235 int min
= 2048 * 2048; /* max is GR_RESOLUTION_2048x2048 */
236 GrResolution resTemplate
= {
242 GrResolution
*presSupported
;
246 size
= grQueryResolutions(&resTemplate
, NULL
);
247 presSupported
= malloc(size
);
249 size
/= sizeof(GrResolution
);
250 grQueryResolutions(&resTemplate
, presSupported
);
252 for (i
= 0; i
< size
; i
++) {
253 int r
= presSupported
[i
].resolution
;
254 if ((width
<= resolutions
[r
][1]) && (height
<= resolutions
[r
][2])) {
255 if (min
> (resolutions
[r
][1] * resolutions
[r
][2])) {
256 min
= resolutions
[r
][1] * resolutions
[r
][2];
264 return resolutions
[lastvalidres
][0];
268 fxMesaContext GLAPIENTRY
269 fxMesaCreateBestContext(GLuint win
, GLint width
, GLint height
,
270 const GLint attribList
[])
272 int res
= fxBestResolution(width
, height
);
278 return fxMesaCreateContext(win
, res
, GR_REFRESH_60Hz
, attribList
);
283 * Create a new FX/Mesa context and return a handle to it.
285 fxMesaContext GLAPIENTRY
286 fxMesaCreateContext(GLuint win
,
287 GrScreenResolution_t res
,
288 GrScreenRefresh_t ref
, const GLint attribList
[])
290 fxMesaContext fxMesa
= NULL
;
291 GLcontext
*ctx
= NULL
, *shareCtx
= NULL
;
292 struct dd_function_table functions
;
296 int sliaa
, numSLI
, samplesPerChip
;
297 struct SstCard_St
*voodoo
;
298 struct tdfx_glide
*Glide
;
301 GLboolean doubleBuffer
;
303 GLuint depthSize
, alphaSize
, stencilSize
, accumSize
;
304 GLuint redBits
, greenBits
, blueBits
, alphaBits
;
305 GrPixelFormat_t pixFmt
;
307 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
308 fprintf(stderr
, "fxMesaCreateContext(...)\n");
311 /* Okay, first process the user flags */
313 doubleBuffer
= GL_FALSE
;
315 depthSize
= alphaSize
= stencilSize
= accumSize
= 0;
318 while (attribList
[i
] != FXMESA_NONE
) {
319 switch (attribList
[i
]) {
320 case FXMESA_COLORDEPTH
:
321 colDepth
= attribList
[++i
];
323 case FXMESA_DOUBLEBUFFER
:
324 doubleBuffer
= GL_TRUE
;
326 case FXMESA_ALPHA_SIZE
:
327 if ((alphaSize
= attribList
[++i
])) {
331 case FXMESA_DEPTH_SIZE
:
332 if ((depthSize
= attribList
[++i
])) {
336 case FXMESA_STENCIL_SIZE
:
337 stencilSize
= attribList
[++i
];
339 case FXMESA_ACCUM_SIZE
:
340 accumSize
= attribList
[++i
];
342 /* XXX ugly hack here for sharing display lists */
343 case FXMESA_SHARE_CONTEXT
:
344 shareCtx
= (GLcontext
*)attribList
[++i
];
347 fprintf(stderr
, "fxMesaCreateContext: ERROR: wrong parameter (%d) passed\n", attribList
[i
]);
353 if (!fxQueryHardware()) {
354 str
= "no Voodoo hardware!";
358 grSstSelect(glbCurrentBoard
);
359 /*grEnable(GR_OPENGL_MODE_EXT);*/ /* [koolsmoky] */
360 voodoo
= &glbHWConfig
.SSTs
[glbCurrentBoard
];
362 fxMesa
= (fxMesaContext
)CALLOC_STRUCT(tfxMesaContext
);
364 str
= "private context";
368 if (getenv("MESA_FX_INFO")) {
369 fxMesa
->verbose
= GL_TRUE
;
372 fxMesa
->type
= voodoo
->type
;
373 fxMesa
->HavePalExt
= voodoo
->HavePalExt
&& !getenv("MESA_FX_IGNORE_PALEXT");
374 fxMesa
->HavePixExt
= voodoo
->HavePixExt
&& !getenv("MESA_FX_IGNORE_PIXEXT");
375 fxMesa
->HaveTexFmt
= voodoo
->HaveTexFmt
&& !getenv("MESA_FX_IGNORE_TEXFMT");
376 fxMesa
->HaveCmbExt
= voodoo
->HaveCmbExt
&& !getenv("MESA_FX_IGNORE_CMBEXT");
377 fxMesa
->HaveMirExt
= voodoo
->HaveMirExt
&& !getenv("MESA_FX_IGNORE_MIREXT");
378 fxMesa
->HaveTexUma
= voodoo
->HaveTexUma
&& !getenv("MESA_FX_IGNORE_TEXUMA");
379 fxMesa
->Glide
= glbHWConfig
.Glide
;
380 Glide
= &fxMesa
->Glide
;
381 fxMesa
->HaveTexus2
= Glide
->txImgQuantize
&&
382 Glide
->txMipQuantize
&&
383 Glide
->txPalToNcc
&& !getenv("MESA_FX_IGNORE_TEXUS2");
385 /* Determine if we need vertex swapping, RGB order and SLI/AA */
387 switch (fxMesa
->type
) {
388 case GR_SSTTYPE_VOODOO
:
389 case GR_SSTTYPE_SST96
:
390 case GR_SSTTYPE_Banshee
:
391 fxMesa
->bgrOrder
= GL_TRUE
;
392 fxMesa
->snapVertices
= (getenv("MESA_FX_NOSNAP") == NULL
);
394 case GR_SSTTYPE_Voodoo2
:
395 fxMesa
->bgrOrder
= GL_TRUE
;
396 fxMesa
->snapVertices
= GL_FALSE
;
398 case GR_SSTTYPE_Voodoo4
:
399 case GR_SSTTYPE_Voodoo5
:
400 /* number of SLI units and AA Samples per chip */
401 if ((str
= Glide
->grGetRegistryOrEnvironmentStringExt("SSTH3_SLI_AA_CONFIGURATION")) != NULL
) {
404 case GR_SSTTYPE_Voodoo3
:
406 fxMesa
->bgrOrder
= GL_FALSE
;
407 fxMesa
->snapVertices
= GL_FALSE
;
410 /* XXX todo - Add the old SLI/AA settings for Napalm. */
411 switch(voodoo
->numChips
) {
412 case 4: /* 4 chips */
414 case 8: /* 8 Sample AA */
418 case 7: /* 4 Sample AA */
422 case 6: /* 2 Sample AA */
431 case 2: /* 2 chips */
433 case 4: /* 4 Sample AA */
437 case 3: /* 2 Sample AA */
446 default: /* 1 chip */
448 case 1: /* 2 Sample AA */
458 fxMesa
->fsaa
= samplesPerChip
* voodoo
->numChips
/ numSLI
; /* 1:noFSAA, 2:2xFSAA, 4:4xFSAA, 8:8xFSAA */
460 switch (fxMesa
->colDepth
= colDepth
) {
465 alphaBits
= depthSize
? 1 : 8;
466 switch(fxMesa
->fsaa
) {
468 pixFmt
= GR_PIXFMT_AA_8_ARGB_1555
;
471 pixFmt
= GR_PIXFMT_AA_4_ARGB_1555
;
474 pixFmt
= GR_PIXFMT_AA_2_ARGB_1555
;
477 pixFmt
= GR_PIXFMT_ARGB_1555
;
484 alphaBits
= depthSize
? 0 : 8;
485 switch(fxMesa
->fsaa
) {
487 pixFmt
= GR_PIXFMT_AA_8_RGB_565
;
490 pixFmt
= GR_PIXFMT_AA_4_RGB_565
;
493 pixFmt
= GR_PIXFMT_AA_2_RGB_565
;
496 pixFmt
= GR_PIXFMT_RGB_565
;
500 fxMesa
->colDepth
= 32;
506 switch(fxMesa
->fsaa
) {
508 pixFmt
= GR_PIXFMT_AA_8_ARGB_8888
;
511 pixFmt
= GR_PIXFMT_AA_4_ARGB_8888
;
514 pixFmt
= GR_PIXFMT_AA_2_ARGB_8888
;
517 pixFmt
= GR_PIXFMT_ARGB_8888
;
526 * 1. we don't bother setting/checking AUX for stencil, because we'll decide
527 * later whether we have HW stencil, based on depth buffer (thus AUX is
529 * 2. when both DEPTH and ALPHA are enabled, depth should win. However, it is
530 * not clear whether 15bpp and 32bpp require AUX alpha buffer. Furthermore,
531 * alpha buffering is required only if destination alpha is used in alpha
532 * blending; alpha blending modes that do not use destination alpha can be
533 * used w/o alpha buffer.
534 * 3. `alphaBits' is what we can provide
535 * `alphaSize' is what app requests
536 * if we cannot provide enough bits for alpha buffer, we should fallback to
537 * SW alpha. However, setting `alphaBits' to `alphaSize' might confuse some
538 * of the span functions...
541 fxMesa
->haveHwAlpha
= GL_FALSE
;
542 if (alphaSize
&& (alphaSize
<= alphaBits
)) {
543 alphaSize
= alphaBits
;
544 fxMesa
->haveHwAlpha
= GL_TRUE
;
547 fxMesa
->haveHwStencil
= (fxMesa
->HavePixExt
&& stencilSize
&& depthSize
== 24);
549 fxMesa
->haveZBuffer
= depthSize
> 0;
550 fxMesa
->haveDoubleBuffer
= doubleBuffer
;
551 fxMesa
->haveGlobalPaletteTexture
= GL_FALSE
;
552 fxMesa
->board
= glbCurrentBoard
;
554 fxMesa
->haveTwoTMUs
= (voodoo
->nTexelfx
> 1);
556 if ((str
= Glide
->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_NUM_TMU"))) {
557 if (atoi(str
) <= 1) {
558 fxMesa
->haveTwoTMUs
= GL_FALSE
;
562 if ((str
= Glide
->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_SWAPPENDINGCOUNT"))) {
563 fxMesa
->maxPendingSwapBuffers
= atoi(str
);
564 if (fxMesa
->maxPendingSwapBuffers
> 3) {
565 fxMesa
->maxPendingSwapBuffers
= 3;
566 } else if (fxMesa
->maxPendingSwapBuffers
< 0) {
567 fxMesa
->maxPendingSwapBuffers
= 0;
570 fxMesa
->maxPendingSwapBuffers
= 2;
573 if ((str
= Glide
->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_SWAPINTERVAL"))) {
574 fxMesa
->swapInterval
= atoi(str
);
576 fxMesa
->swapInterval
= 0;
580 if (fxMesa
->HavePixExt
) {
581 fxMesa
->glideContext
= Glide
->grSstWinOpenExt((FxU32
)win
, res
, ref
,
582 GR_COLORFORMAT_ABGR
, GR_ORIGIN_LOWER_LEFT
,
585 } else if (pixFmt
== GR_PIXFMT_RGB_565
) {
586 fxMesa
->glideContext
= grSstWinOpen((FxU32
)win
, res
, ref
,
587 GR_COLORFORMAT_ABGR
, GR_ORIGIN_LOWER_LEFT
,
590 fxMesa
->glideContext
= 0;
593 if (!fxMesa
->glideContext
) {
594 str
= "grSstWinOpen";
599 fxMesa
->screen_width
= FX_grSstScreenWidth();
600 fxMesa
->screen_height
= FX_grSstScreenHeight();
602 /* window inside screen */
603 fxMesa
->width
= fxMesa
->screen_width
;
604 fxMesa
->height
= fxMesa
->screen_height
;
606 /* scissor inside window */
607 fxMesa
->clipMinX
= 0;
608 fxMesa
->clipMaxX
= fxMesa
->width
;
609 fxMesa
->clipMinY
= 0;
610 fxMesa
->clipMaxY
= fxMesa
->height
;
612 if (fxMesa
->verbose
) {
615 /* Not that it matters, but tmuRam and fbRam change after grSstWinOpen. */
616 tmuRam
= voodoo
->tmuConfig
[GR_TMU0
].tmuRam
;
617 fbRam
= voodoo
->fbRam
;
619 grGet(GR_MEMORY_TMU
, 4, &tmuRam
);
620 grGet(GR_MEMORY_FB
, 4, &fbRam
);
623 fprintf(stderr
, "Voodoo Using Glide %s\n", grGetString(GR_VERSION
));
624 fprintf(stderr
, "Voodoo Board: %d/%d, %s, %d GPU\n",
627 grGetString(GR_HARDWARE
),
629 fprintf(stderr
, "Voodoo Memory: FB = %ld, TM = %d x %ld\n",
633 fprintf(stderr
, "Voodoo Screen: %dx%d:%d %s, %svertex snapping\n",
634 fxMesa
->screen_width
,
635 fxMesa
->screen_height
,
637 fxMesa
->bgrOrder
? "BGR" : "RGB",
638 fxMesa
->snapVertices
? "" : "no ");
641 sprintf(fxMesa
->rendererString
, "Mesa %s v0.61 %s%s",
642 grGetString(GR_RENDERER
),
643 grGetString(GR_HARDWARE
),
644 ((fxMesa
->type
< GR_SSTTYPE_Voodoo4
) && (voodoo
->numChips
> 1)) ? " SLI" : "");
646 fxMesa
->glVis
= _mesa_create_visual(GL_TRUE
, /* RGB mode */
648 GL_FALSE
, /* stereo */
649 redBits
, /* RGBA.R bits */
650 greenBits
, /* RGBA.G bits */
651 blueBits
, /* RGBA.B bits */
652 alphaSize
, /* RGBA.A bits */
654 depthSize
, /* depth_size */
655 stencilSize
, /* stencil_size */
659 alphaSize
? accumSize
: 0,
661 if (!fxMesa
->glVis
) {
662 str
= "_mesa_create_visual";
666 _mesa_init_driver_functions(&functions
);
667 ctx
= fxMesa
->glCtx
= _mesa_create_context(fxMesa
->glVis
, shareCtx
,
668 &functions
, (void *) fxMesa
);
670 str
= "_mesa_create_context";
675 if (!fxDDInitFxMesaContext(fxMesa
)) {
676 str
= "fxDDInitFxMesaContext";
681 fxMesa
->glBuffer
= _mesa_create_framebuffer(fxMesa
->glVis
,
682 GL_FALSE
, /* no software depth */
683 stencilSize
&& !fxMesa
->haveHwStencil
,
684 fxMesa
->glVis
->accumRedBits
> 0,
685 alphaSize
&& !fxMesa
->haveHwAlpha
);
686 if (!fxMesa
->glBuffer
) {
687 str
= "_mesa_create_framebuffer";
693 /* install signal handlers */
694 #if defined(__linux__)
695 /* Only install if environment var. is not set. */
696 if (!getenv("MESA_FX_NO_SIGNALS")) {
697 signal(SIGINT
, cleangraphics_handler
);
698 signal(SIGHUP
, cleangraphics_handler
);
699 signal(SIGPIPE
, cleangraphics_handler
);
700 signal(SIGFPE
, cleangraphics_handler
);
701 signal(SIGBUS
, cleangraphics_handler
);
702 signal(SIGILL
, cleangraphics_handler
);
703 signal(SIGSEGV
, cleangraphics_handler
);
704 signal(SIGTERM
, cleangraphics_handler
);
712 if (fxMesa
->glideContext
) {
713 grSstWinClose(fxMesa
->glideContext
);
714 fxMesa
->glideContext
= 0;
720 if (fxMesa
->fogTable
) {
721 FREE(fxMesa
->fogTable
);
723 if (fxMesa
->glBuffer
) {
724 _mesa_destroy_framebuffer(fxMesa
->glBuffer
);
727 _mesa_destroy_visual(fxMesa
->glVis
);
730 _mesa_destroy_context(fxMesa
->glCtx
);
735 fprintf(stderr
, "fxMesaCreateContext: ERROR: %s\n", str
);
741 * Function to set the new window size in the context (mainly for the Voodoo Rush)
744 fxMesaUpdateScreenSize(fxMesaContext fxMesa
)
746 fxMesa
->width
= FX_grSstScreenWidth();
747 fxMesa
->height
= FX_grSstScreenHeight();
752 * Destroy the given FX/Mesa context.
755 fxMesaDestroyContext(fxMesaContext fxMesa
)
757 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
758 fprintf(stderr
, "fxMesaDestroyContext(...)\n");
764 if (fxMesa
->verbose
) {
765 fprintf(stderr
, "Misc Stats:\n");
766 fprintf(stderr
, " # swap buffer: %u\n", fxMesa
->stats
.swapBuffer
);
768 if (!fxMesa
->stats
.swapBuffer
)
769 fxMesa
->stats
.swapBuffer
= 1;
771 fprintf(stderr
, "Textures Stats:\n");
772 fprintf(stderr
, " Free texture memory on TMU0: %d\n",
773 fxMesa
->freeTexMem
[FX_TMU0
]);
774 if (fxMesa
->haveTwoTMUs
)
775 fprintf(stderr
, " Free texture memory on TMU1: %d\n",
776 fxMesa
->freeTexMem
[FX_TMU1
]);
777 fprintf(stderr
, " # request to TMM to upload a texture objects: %u\n",
778 fxMesa
->stats
.reqTexUpload
);
780 " # request to TMM to upload a texture objects per swapbuffer: %.2f\n",
781 fxMesa
->stats
.reqTexUpload
/ (float) fxMesa
->stats
.swapBuffer
);
782 fprintf(stderr
, " # texture objects uploaded: %u\n",
783 fxMesa
->stats
.texUpload
);
784 fprintf(stderr
, " # texture objects uploaded per swapbuffer: %.2f\n",
785 fxMesa
->stats
.texUpload
/ (float) fxMesa
->stats
.swapBuffer
);
786 fprintf(stderr
, " # MBs uploaded to texture memory: %.2f\n",
787 fxMesa
->stats
.memTexUpload
/ (float) (1 << 20));
789 " # MBs uploaded to texture memory per swapbuffer: %.2f\n",
790 (fxMesa
->stats
.memTexUpload
/
791 (float) fxMesa
->stats
.swapBuffer
) / (float) (1 << 20));
796 if (!glbTotNumCtx
&& getenv("MESA_FX_INFO")) {
799 FX_grSstPerfStats(&st
);
801 fprintf(stderr
, "Pixels Stats:\n");
802 fprintf(stderr
, " # pixels processed (minus buffer clears): %u\n",
803 (unsigned) st
.pixelsIn
);
804 fprintf(stderr
, " # pixels not drawn due to chroma key test failure: %u\n",
805 (unsigned) st
.chromaFail
);
806 fprintf(stderr
, " # pixels not drawn due to depth test failure: %u\n",
807 (unsigned) st
.zFuncFail
);
809 " # pixels not drawn due to alpha test failure: %u\n",
810 (unsigned) st
.aFuncFail
);
811 fprintf(stderr
, " # pixels drawn (including buffer clears and LFB writes): %u\n",
812 (unsigned) st
.pixelsOut
);
815 /* close the hardware first,
816 * so we can debug atexit problems (memory leaks, etc).
818 grSstWinClose(fxMesa
->glideContext
);
821 fxDDDestroyFxMesaContext(fxMesa
); /* must be before _mesa_destroy_context */
822 _mesa_destroy_visual(fxMesa
->glVis
);
823 _mesa_destroy_context(fxMesa
->glCtx
);
824 _mesa_destroy_framebuffer(fxMesa
->glBuffer
);
825 fxTMClose(fxMesa
); /* must be after _mesa_destroy_context */
829 if (fxMesa
== fxMesaCurrentCtx
)
830 fxMesaCurrentCtx
= NULL
;
835 * Make the specified FX/Mesa context the current one.
838 fxMesaMakeCurrent(fxMesaContext fxMesa
)
841 _mesa_make_current(NULL
, NULL
);
842 fxMesaCurrentCtx
= NULL
;
844 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
845 fprintf(stderr
, "fxMesaMakeCurrent(NULL)\n");
851 /* if this context is already the current one, we can return early */
852 if (fxMesaCurrentCtx
== fxMesa
853 && fxMesaCurrentCtx
->glCtx
== _mesa_get_current_context()) {
854 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
855 fprintf(stderr
, "fxMesaMakeCurrent(NOP)\n");
861 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
862 fprintf(stderr
, "fxMesaMakeCurrent(...)\n");
865 if (fxMesaCurrentCtx
)
866 grGlideGetState((GrState
*) fxMesaCurrentCtx
->state
);
868 fxMesaCurrentCtx
= fxMesa
;
870 grSstSelect(fxMesa
->board
);
871 grGlideSetState((GrState
*) fxMesa
->state
);
873 _mesa_make_current(fxMesa
->glCtx
, fxMesa
->glBuffer
);
875 fxSetupDDPointers(fxMesa
->glCtx
);
877 /* The first time we call MakeCurrent we set the initial viewport size */
878 if (fxMesa
->glCtx
->Viewport
.Width
== 0)
879 _mesa_set_viewport(fxMesa
->glCtx
, 0, 0, fxMesa
->width
, fxMesa
->height
);
884 * Swap front/back buffers for current context if double buffered.
887 fxMesaSwapBuffers(void)
889 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
890 fprintf(stderr
, "fxMesaSwapBuffers()\n");
893 if (fxMesaCurrentCtx
) {
894 _mesa_notifySwapBuffers(fxMesaCurrentCtx
->glCtx
);
896 if (fxMesaCurrentCtx
->haveDoubleBuffer
) {
898 grBufferSwap(fxMesaCurrentCtx
->swapInterval
);
902 * Don't allow swap buffer commands to build up!
904 while (FX_grGetInteger(GR_PENDING_BUFFERSWAPS
) >
905 fxMesaCurrentCtx
->maxPendingSwapBuffers
)
906 /* The driver is able to sleep when waiting for the completation
907 of multiple swapbuffer operations instead of wasting
908 CPU time (NOTE: you must uncomment the following line in the
909 in order to enable this option) */
914 fxMesaCurrentCtx
->stats
.swapBuffer
++;
921 * Shutdown Glide library
924 fxCloseHardware(void)
926 if (glbGlideInitialized
) {
927 if (glbTotNumCtx
== 0) {
929 glbGlideInitialized
= 0;
939 * Need this to provide at least one external definition.
941 extern int gl_fx_dummy_function_api(void);
943 gl_fx_dummy_function_api(void)