📄 fxapi.c
字号:
/* * Mesa 3-D graphics library * Version: 4.0 * * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//* Authors: * David Bucciarelli * Brian Paul * Daryll Strauss * Keith Whitwell * Daniel Borca * Hiroshi Morii *//* fxapi.c - public interface to FX/Mesa functions (fxmesa.h) */#ifdef HAVE_CONFIG_H#include "conf.h"#endif#if defined(FX)#include "fxdrv.h"#include "drivers/common/driverfuncs.h"#include "framebuffer.h"#ifndef TDFX_DEBUGint TDFX_DEBUG = (0/* | VERBOSE_VARRAY *//* | VERBOSE_TEXTURE *//* | VERBOSE_IMMEDIATE *//* | VERBOSE_PIPELINE *//* | VERBOSE_DRIVER *//* | VERBOSE_STATE *//* | VERBOSE_API *//* | VERBOSE_DISPLAY_LIST *//* | VERBOSE_LIGHTING *//* | VERBOSE_PRIMS *//* | VERBOSE_VERTS */ );#endifstatic fxMesaContext fxMesaCurrentCtx = NULL;/* * Status of 3Dfx hardware initialization */static int glbGlideInitialized = 0;static int glb3DfxPresent = 0;static int glbTotNumCtx = 0;static GrHwConfiguration glbHWConfig;static int glbCurrentBoard = 0;#if defined(__WIN32__)static intcleangraphics(void){ glbTotNumCtx = 1; fxMesaDestroyContext(fxMesaCurrentCtx); return 0;}#elif defined(__linux__)static voidcleangraphics(void){ glbTotNumCtx = 1; fxMesaDestroyContext(fxMesaCurrentCtx);}static voidcleangraphics_handler(int s){ fprintf(stderr, "fxmesa: ERROR: received a not handled signal %d\n", s); cleangraphics();/* abort(); */ exit(1);}#endif/* * Query 3Dfx hardware presence/kind */static GLboolean GLAPIENTRY fxQueryHardware (void){ if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxQueryHardware()\n"); } if (!glbGlideInitialized) { grGlideInit(); glb3DfxPresent = FX_grSstQueryHardware(&glbHWConfig); glbGlideInitialized = 1;#if defined(__WIN32__) _onexit((_onexit_t) cleangraphics);#elif defined(__linux__) /* Only register handler if environment variable is not defined. */ if (!getenv("MESA_FX_NO_SIGNALS")) { atexit(cleangraphics); }#endif } return glb3DfxPresent;}/* * Select the Voodoo board to use when creating * a new context. */GLint GLAPIENTRY fxMesaSelectCurrentBoard (int n){ fxQueryHardware(); if ((n < 0) || (n >= glbHWConfig.num_sst)) return -1; return glbHWConfig.SSTs[glbCurrentBoard = n].type;}fxMesaContext GLAPIENTRY fxMesaGetCurrentContext (void){ return fxMesaCurrentCtx;}void GLAPIENTRY fxGetScreenGeometry (GLint *w, GLint *h){ GLint width = 0; GLint height = 0; if (fxMesaCurrentCtx != NULL) { width = fxMesaCurrentCtx->screen_width; height = fxMesaCurrentCtx->screen_height; } if (w != NULL) { *w = width; } if (h != NULL) { *h = height; }}/* * The 3Dfx Global Palette extension for GLQuake. * More a trick than a real extesion, use the shared global * palette extension. */extern void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint * pal); /* silence warning */void GLAPIENTRYgl3DfxSetPaletteEXT(GLuint * pal){ fxMesaContext fxMesa = fxMesaCurrentCtx; if (TDFX_DEBUG & VERBOSE_DRIVER) { int i; fprintf(stderr, "gl3DfxSetPaletteEXT(...)\n"); for (i = 0; i < 256; i++) { fprintf(stderr, "\t%x\n", pal[i]); } } if (fxMesa) { fxMesa->haveGlobalPaletteTexture = 1; grTexDownloadTable(GR_TEXTABLE_PALETTE, (GuTexPalette *) pal); }}static GrScreenResolution_t fxBestResolution (int width, int height){ static int resolutions[][3] = { { GR_RESOLUTION_320x200, 320, 200 }, { GR_RESOLUTION_320x240, 320, 240 }, { GR_RESOLUTION_400x256, 400, 256 }, { GR_RESOLUTION_512x384, 512, 384 }, { GR_RESOLUTION_640x200, 640, 200 }, { GR_RESOLUTION_640x350, 640, 350 }, { GR_RESOLUTION_640x400, 640, 400 }, { GR_RESOLUTION_640x480, 640, 480 }, { GR_RESOLUTION_800x600, 800, 600 }, { GR_RESOLUTION_960x720, 960, 720 }, { GR_RESOLUTION_856x480, 856, 480 }, { GR_RESOLUTION_512x256, 512, 256 }, { GR_RESOLUTION_1024x768, 1024, 768 }, { GR_RESOLUTION_1280x1024, 1280, 1024 }, { GR_RESOLUTION_1600x1200, 1600, 1200 }, { GR_RESOLUTION_400x300, 400, 300 }, { GR_RESOLUTION_1152x864, 1152, 864 }, { GR_RESOLUTION_1280x960, 1280, 960 }, { GR_RESOLUTION_1600x1024, 1600, 1024 }, { GR_RESOLUTION_1792x1344, 1792, 1344 }, { GR_RESOLUTION_1856x1392, 1856, 1392 }, { GR_RESOLUTION_1920x1440, 1920, 1440 }, { GR_RESOLUTION_2048x1536, 2048, 1536 }, { GR_RESOLUTION_2048x2048, 2048, 2048 } }; int i, size; int lastvalidres = GR_RESOLUTION_640x480; int min = 2048 * 2048; /* max is GR_RESOLUTION_2048x2048 */ GrResolution resTemplate = { GR_QUERY_ANY, GR_QUERY_ANY, 2 /*GR_QUERY_ANY */, GR_QUERY_ANY }; GrResolution *presSupported; fxQueryHardware(); size = grQueryResolutions(&resTemplate, NULL); presSupported = malloc(size); size /= sizeof(GrResolution); grQueryResolutions(&resTemplate, presSupported); for (i = 0; i < size; i++) { int r = presSupported[i].resolution; if ((width <= resolutions[r][1]) && (height <= resolutions[r][2])) { if (min > (resolutions[r][1] * resolutions[r][2])) { min = resolutions[r][1] * resolutions[r][2]; lastvalidres = r; } } } free(presSupported); return resolutions[lastvalidres][0];}fxMesaContext GLAPIENTRYfxMesaCreateBestContext(GLuint win, GLint width, GLint height, const GLint attribList[]){ int res = fxBestResolution(width, height); if (res == -1) { return NULL; } return fxMesaCreateContext(win, res, GR_REFRESH_60Hz, attribList);}/* * Create a new FX/Mesa context and return a handle to it. */fxMesaContext GLAPIENTRYfxMesaCreateContext(GLuint win, GrScreenResolution_t res, GrScreenRefresh_t ref, const GLint attribList[]){ fxMesaContext fxMesa = NULL; GLcontext *ctx = NULL, *shareCtx = NULL; struct dd_function_table functions; int i; const char *str; int sliaa, numSLI, samplesPerChip; struct SstCard_St *voodoo; struct tdfx_glide *Glide; GLboolean aux; GLboolean doubleBuffer; GLuint colDepth; GLuint depthSize, alphaSize, stencilSize, accumSize; GLuint redBits, greenBits, blueBits, alphaBits; GrPixelFormat_t pixFmt; if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxMesaCreateContext(...)\n"); } /* Okay, first process the user flags */ aux = GL_FALSE; doubleBuffer = GL_FALSE; colDepth = 16; depthSize = alphaSize = stencilSize = accumSize = 0; i = 0; while (attribList[i] != FXMESA_NONE) { switch (attribList[i]) { case FXMESA_COLORDEPTH: colDepth = attribList[++i]; break; case FXMESA_DOUBLEBUFFER: doubleBuffer = GL_TRUE; break; case FXMESA_ALPHA_SIZE: if ((alphaSize = attribList[++i])) { aux = GL_TRUE; } break; case FXMESA_DEPTH_SIZE: if ((depthSize = attribList[++i])) { aux = GL_TRUE; } break; case FXMESA_STENCIL_SIZE: stencilSize = attribList[++i]; break; case FXMESA_ACCUM_SIZE: accumSize = attribList[++i]; break; /* XXX ugly hack here for sharing display lists */ case FXMESA_SHARE_CONTEXT: shareCtx = (GLcontext *)attribList[++i]; break; default: fprintf(stderr, "fxMesaCreateContext: ERROR: wrong parameter (%d) passed\n", attribList[i]); return NULL; } i++; } if (!fxQueryHardware()) { str = "no Voodoo hardware!"; goto errorhandler; } grSstSelect(glbCurrentBoard); /*grEnable(GR_OPENGL_MODE_EXT);*/ /* [koolsmoky] */ voodoo = &glbHWConfig.SSTs[glbCurrentBoard]; fxMesa = (fxMesaContext)CALLOC_STRUCT(tfxMesaContext); if (!fxMesa) { str = "private context"; goto errorhandler; } if (getenv("MESA_FX_INFO")) { fxMesa->verbose = GL_TRUE; } fxMesa->type = voodoo->type; fxMesa->HavePalExt = voodoo->HavePalExt && !getenv("MESA_FX_IGNORE_PALEXT"); fxMesa->HavePixExt = voodoo->HavePixExt && !getenv("MESA_FX_IGNORE_PIXEXT"); fxMesa->HaveTexFmt = voodoo->HaveTexFmt && !getenv("MESA_FX_IGNORE_TEXFMT"); fxMesa->HaveCmbExt = voodoo->HaveCmbExt && !getenv("MESA_FX_IGNORE_CMBEXT"); fxMesa->HaveMirExt = voodoo->HaveMirExt && !getenv("MESA_FX_IGNORE_MIREXT"); fxMesa->HaveTexUma = voodoo->HaveTexUma && !getenv("MESA_FX_IGNORE_TEXUMA"); fxMesa->Glide = glbHWConfig.Glide; Glide = &fxMesa->Glide; fxMesa->HaveTexus2 = Glide->txImgQuantize && Glide->txMipQuantize && Glide->txPalToNcc && !getenv("MESA_FX_IGNORE_TEXUS2"); /* Determine if we need vertex swapping, RGB order and SLI/AA */ sliaa = 0; switch (fxMesa->type) { case GR_SSTTYPE_VOODOO: case GR_SSTTYPE_SST96: case GR_SSTTYPE_Banshee: fxMesa->bgrOrder = GL_TRUE; fxMesa->snapVertices = (getenv("MESA_FX_NOSNAP") == NULL); break; case GR_SSTTYPE_Voodoo2: fxMesa->bgrOrder = GL_TRUE; fxMesa->snapVertices = GL_FALSE; break; case GR_SSTTYPE_Voodoo4: case GR_SSTTYPE_Voodoo5: /* number of SLI units and AA Samples per chip */ if ((str = Glide->grGetRegistryOrEnvironmentStringExt("SSTH3_SLI_AA_CONFIGURATION")) != NULL) { sliaa = atoi(str); } case GR_SSTTYPE_Voodoo3: default: fxMesa->bgrOrder = GL_FALSE; fxMesa->snapVertices = GL_FALSE; break; } /* XXX todo - Add the old SLI/AA settings for Napalm. */ switch(voodoo->numChips) { case 4: /* 4 chips */ switch(sliaa) { case 8: /* 8 Sample AA */ numSLI = 1; samplesPerChip = 2; break; case 7: /* 4 Sample AA */ numSLI = 1; samplesPerChip = 1; break; case 6: /* 2 Sample AA */ numSLI = 2; samplesPerChip = 1; break; default: numSLI = 4; samplesPerChip = 1; } break; case 2: /* 2 chips */ switch(sliaa) { case 4: /* 4 Sample AA */ numSLI = 1; samplesPerChip = 2; break; case 3: /* 2 Sample AA */ numSLI = 1; samplesPerChip = 1; break; default: numSLI = 2; samplesPerChip = 1; } break; default: /* 1 chip */ switch(sliaa) { case 1: /* 2 Sample AA */ numSLI = 1; samplesPerChip = 2; break; default: numSLI = 1; samplesPerChip = 1; } } fxMesa->fsaa = samplesPerChip * voodoo->numChips / numSLI; /* 1:noFSAA, 2:2xFSAA, 4:4xFSAA, 8:8xFSAA */ switch (fxMesa->colDepth = colDepth) { case 15: redBits = 5; greenBits = 5; blueBits = 5; alphaBits = depthSize ? 1 : 8; switch(fxMesa->fsaa) { case 8: pixFmt = GR_PIXFMT_AA_8_ARGB_1555; break; case 4: pixFmt = GR_PIXFMT_AA_4_ARGB_1555; break; case 2: pixFmt = GR_PIXFMT_AA_2_ARGB_1555; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -