📄 fxapi.c
字号:
default: pixFmt = GR_PIXFMT_ARGB_1555; } break; case 16: redBits = 5; greenBits = 6; blueBits = 5; alphaBits = depthSize ? 0 : 8; switch(fxMesa->fsaa) { case 8: pixFmt = GR_PIXFMT_AA_8_RGB_565; break; case 4: pixFmt = GR_PIXFMT_AA_4_RGB_565; break; case 2: pixFmt = GR_PIXFMT_AA_2_RGB_565; break; default: pixFmt = GR_PIXFMT_RGB_565; } break; case 24: fxMesa->colDepth = 32; case 32: redBits = 8; greenBits = 8; blueBits = 8; alphaBits = 8; switch(fxMesa->fsaa) { case 8: pixFmt = GR_PIXFMT_AA_8_ARGB_8888; break; case 4: pixFmt = GR_PIXFMT_AA_4_ARGB_8888; break; case 2: pixFmt = GR_PIXFMT_AA_2_ARGB_8888; break; default: pixFmt = GR_PIXFMT_ARGB_8888; } break; default: str = "pixelFormat"; goto errorhandler; } /* Tips: * 1. we don't bother setting/checking AUX for stencil, because we'll decide * later whether we have HW stencil, based on depth buffer (thus AUX is * properly set) * 2. when both DEPTH and ALPHA are enabled, depth should win. However, it is * not clear whether 15bpp and 32bpp require AUX alpha buffer. Furthermore, * alpha buffering is required only if destination alpha is used in alpha * blending; alpha blending modes that do not use destination alpha can be * used w/o alpha buffer. * 3. `alphaBits' is what we can provide * `alphaSize' is what app requests * if we cannot provide enough bits for alpha buffer, we should fallback to * SW alpha. However, setting `alphaBits' to `alphaSize' might confuse some * of the span functions... */ fxMesa->haveHwAlpha = GL_FALSE; if (alphaSize && (alphaSize <= alphaBits)) { alphaSize = alphaBits; fxMesa->haveHwAlpha = GL_TRUE; } fxMesa->haveHwStencil = (fxMesa->HavePixExt && stencilSize && depthSize == 24); fxMesa->haveZBuffer = depthSize > 0; fxMesa->haveDoubleBuffer = doubleBuffer; fxMesa->haveGlobalPaletteTexture = GL_FALSE; fxMesa->board = glbCurrentBoard; fxMesa->haveTwoTMUs = (voodoo->nTexelfx > 1); if ((str = Glide->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_NUM_TMU"))) { if (atoi(str) <= 1) { fxMesa->haveTwoTMUs = GL_FALSE; } } if ((str = Glide->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_SWAPPENDINGCOUNT"))) { fxMesa->maxPendingSwapBuffers = atoi(str); if (fxMesa->maxPendingSwapBuffers > 6) { fxMesa->maxPendingSwapBuffers = 6; } else if (fxMesa->maxPendingSwapBuffers < 0) { fxMesa->maxPendingSwapBuffers = 0; } } else { fxMesa->maxPendingSwapBuffers = 2; } if ((str = Glide->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_SWAPINTERVAL"))) { fxMesa->swapInterval = atoi(str); } else { fxMesa->swapInterval = 0; } BEGIN_BOARD_LOCK(); if (fxMesa->HavePixExt) { fxMesa->glideContext = Glide->grSstWinOpenExt((FxU32)win, res, ref, GR_COLORFORMAT_ABGR, GR_ORIGIN_LOWER_LEFT, pixFmt, 2, aux); } else if (pixFmt == GR_PIXFMT_RGB_565) { fxMesa->glideContext = grSstWinOpen((FxU32)win, res, ref, GR_COLORFORMAT_ABGR, GR_ORIGIN_LOWER_LEFT, 2, aux); } else { fxMesa->glideContext = 0; } END_BOARD_LOCK(); if (!fxMesa->glideContext) { str = "grSstWinOpen"; goto errorhandler; } /* screen */ fxMesa->screen_width = FX_grSstScreenWidth(); fxMesa->screen_height = FX_grSstScreenHeight(); /* window inside screen */ fxMesa->width = fxMesa->screen_width; fxMesa->height = fxMesa->screen_height; /* scissor inside window */ fxMesa->clipMinX = 0; fxMesa->clipMaxX = fxMesa->width; fxMesa->clipMinY = 0; fxMesa->clipMaxY = fxMesa->height; if (fxMesa->verbose) { FxI32 tmuRam, fbRam; /* Not that it matters, but tmuRam and fbRam change after grSstWinOpen. */ tmuRam = voodoo->tmuConfig[GR_TMU0].tmuRam; fbRam = voodoo->fbRam; BEGIN_BOARD_LOCK(); grGet(GR_MEMORY_TMU, 4, &tmuRam); grGet(GR_MEMORY_FB, 4, &fbRam); END_BOARD_LOCK(); fprintf(stderr, "Voodoo Using Glide %s\n", grGetString(GR_VERSION)); fprintf(stderr, "Voodoo Board: %d/%d, %s, %d GPU\n", fxMesa->board + 1, glbHWConfig.num_sst, grGetString(GR_HARDWARE), voodoo->numChips); fprintf(stderr, "Voodoo Memory: FB = %ld, TM = %d x %ld\n", fbRam, voodoo->nTexelfx, tmuRam); fprintf(stderr, "Voodoo Screen: %dx%d:%d %s, %svertex snapping\n", fxMesa->screen_width, fxMesa->screen_height, colDepth, fxMesa->bgrOrder ? "BGR" : "RGB", fxMesa->snapVertices ? "" : "no "); } sprintf(fxMesa->rendererString, "Mesa %s v0.63 %s%s", grGetString(GR_RENDERER), grGetString(GR_HARDWARE), ((fxMesa->type < GR_SSTTYPE_Voodoo4) && (voodoo->numChips > 1)) ? " SLI" : ""); fxMesa->glVis = _mesa_create_visual(GL_TRUE, /* RGB mode */ doubleBuffer, GL_FALSE, /* stereo */ redBits, /* RGBA.R bits */ greenBits, /* RGBA.G bits */ blueBits, /* RGBA.B bits */ alphaSize, /* RGBA.A bits */ 0, /* index bits */ depthSize, /* depth_size */ stencilSize, /* stencil_size */ accumSize, accumSize, accumSize, alphaSize ? accumSize : 0, 1); if (!fxMesa->glVis) { str = "_mesa_create_visual"; goto errorhandler; } _mesa_init_driver_functions(&functions); ctx = fxMesa->glCtx = _mesa_create_context(fxMesa->glVis, shareCtx, &functions, (void *) fxMesa); if (!ctx) { str = "_mesa_create_context"; goto errorhandler; } if (!fxDDInitFxMesaContext(fxMesa)) { str = "fxDDInitFxMesaContext"; goto errorhandler; } fxMesa->glBuffer = _mesa_create_framebuffer(fxMesa->glVis);#if 0/* XXX this is a complete mess :( * _mesa_add_soft_renderbuffers * driNewRenderbuffer */ GL_FALSE, /* no software depth */ stencilSize && !fxMesa->haveHwStencil, fxMesa->glVis->accumRedBits > 0, alphaSize && !fxMesa->haveHwAlpha);#endif if (!fxMesa->glBuffer) { str = "_mesa_create_framebuffer"; goto errorhandler; } glbTotNumCtx++; /* install signal handlers */#if defined(__linux__) /* Only install if environment var. is not set. */ if (!getenv("MESA_FX_NO_SIGNALS")) { signal(SIGINT, cleangraphics_handler); signal(SIGHUP, cleangraphics_handler); signal(SIGPIPE, cleangraphics_handler); signal(SIGFPE, cleangraphics_handler); signal(SIGBUS, cleangraphics_handler); signal(SIGILL, cleangraphics_handler); signal(SIGSEGV, cleangraphics_handler); signal(SIGTERM, cleangraphics_handler); }#endif return fxMesa;errorhandler: if (fxMesa) { if (fxMesa->glideContext) { grSstWinClose(fxMesa->glideContext); fxMesa->glideContext = 0; } if (fxMesa->state) { FREE(fxMesa->state); } if (fxMesa->fogTable) { FREE(fxMesa->fogTable); } if (fxMesa->glBuffer) { _mesa_unreference_framebuffer(&fxMesa->glBuffer); } if (fxMesa->glVis) { _mesa_destroy_visual(fxMesa->glVis); } if (fxMesa->glCtx) { _mesa_destroy_context(fxMesa->glCtx); } FREE(fxMesa); } fprintf(stderr, "fxMesaCreateContext: ERROR: %s\n", str); return NULL;}/* * Function to set the new window size in the context (mainly for the Voodoo Rush) */void GLAPIENTRYfxMesaUpdateScreenSize(fxMesaContext fxMesa){ fxMesa->width = FX_grSstScreenWidth(); fxMesa->height = FX_grSstScreenHeight();}/* * Destroy the given FX/Mesa context. */void GLAPIENTRYfxMesaDestroyContext(fxMesaContext fxMesa){ if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxMesaDestroyContext(...)\n"); } if (!fxMesa) return; if (fxMesa->verbose) { fprintf(stderr, "Misc Stats:\n"); fprintf(stderr, " # swap buffer: %u\n", fxMesa->stats.swapBuffer); if (!fxMesa->stats.swapBuffer) fxMesa->stats.swapBuffer = 1; fprintf(stderr, "Textures Stats:\n"); fprintf(stderr, " Free texture memory on TMU0: %d\n", fxMesa->freeTexMem[FX_TMU0]); if (fxMesa->haveTwoTMUs) fprintf(stderr, " Free texture memory on TMU1: %d\n", fxMesa->freeTexMem[FX_TMU1]); fprintf(stderr, " # request to TMM to upload a texture objects: %u\n", fxMesa->stats.reqTexUpload); fprintf(stderr, " # request to TMM to upload a texture objects per swapbuffer: %.2f\n", fxMesa->stats.reqTexUpload / (float) fxMesa->stats.swapBuffer); fprintf(stderr, " # texture objects uploaded: %u\n", fxMesa->stats.texUpload); fprintf(stderr, " # texture objects uploaded per swapbuffer: %.2f\n", fxMesa->stats.texUpload / (float) fxMesa->stats.swapBuffer); fprintf(stderr, " # MBs uploaded to texture memory: %.2f\n", fxMesa->stats.memTexUpload / (float) (1 << 20)); fprintf(stderr, " # MBs uploaded to texture memory per swapbuffer: %.2f\n", (fxMesa->stats.memTexUpload / (float) fxMesa->stats.swapBuffer) / (float) (1 << 20)); } glbTotNumCtx--; if (!glbTotNumCtx && getenv("MESA_FX_INFO")) { GrSstPerfStats_t st; FX_grSstPerfStats(&st); fprintf(stderr, "Pixels Stats:\n"); fprintf(stderr, " # pixels processed (minus buffer clears): %u\n", (unsigned) st.pixelsIn); fprintf(stderr, " # pixels not drawn due to chroma key test failure: %u\n", (unsigned) st.chromaFail); fprintf(stderr, " # pixels not drawn due to depth test failure: %u\n", (unsigned) st.zFuncFail); fprintf(stderr, " # pixels not drawn due to alpha test failure: %u\n", (unsigned) st.aFuncFail); fprintf(stderr, " # pixels drawn (including buffer clears and LFB writes): %u\n", (unsigned) st.pixelsOut); } /* close the hardware first, * so we can debug atexit problems (memory leaks, etc). */ grSstWinClose(fxMesa->glideContext); fxCloseHardware(); fxDDDestroyFxMesaContext(fxMesa); /* must be before _mesa_destroy_context */ _mesa_destroy_visual(fxMesa->glVis); _mesa_destroy_context(fxMesa->glCtx); _mesa_unreference_framebuffer(&fxMesa->glBuffer); fxTMClose(fxMesa); /* must be after _mesa_destroy_context */ FREE(fxMesa); if (fxMesa == fxMesaCurrentCtx) fxMesaCurrentCtx = NULL;}/* * Make the specified FX/Mesa context the current one. */void GLAPIENTRYfxMesaMakeCurrent(fxMesaContext fxMesa){ if (!fxMesa) { _mesa_make_current(NULL, NULL, NULL); fxMesaCurrentCtx = NULL; if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxMesaMakeCurrent(NULL)\n"); } return; } /* if this context is already the current one, we can return early */ if (fxMesaCurrentCtx == fxMesa && fxMesaCurrentCtx->glCtx == _mesa_get_current_context()) { if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxMesaMakeCurrent(NOP)\n"); } return; } if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxMesaMakeCurrent(...)\n"); } if (fxMesaCurrentCtx) grGlideGetState((GrState *) fxMesaCurrentCtx->state); fxMesaCurrentCtx = fxMesa; grSstSelect(fxMesa->board); grGlideSetState((GrState *) fxMesa->state); _mesa_make_current(fxMesa->glCtx, fxMesa->glBuffer, fxMesa->glBuffer); fxSetupDDPointers(fxMesa->glCtx);}/* * Swap front/back buffers for current context if double buffered. */void GLAPIENTRYfxMesaSwapBuffers(void){ if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxMesaSwapBuffers()\n"); } if (fxMesaCurrentCtx) { _mesa_notifySwapBuffers(fxMesaCurrentCtx->glCtx); if (fxMesaCurrentCtx->haveDoubleBuffer) { grBufferSwap(fxMesaCurrentCtx->swapInterval);#if 0 /* * Don't allow swap buffer commands to build up! */ while (FX_grGetInteger(GR_PENDING_BUFFERSWAPS) > fxMesaCurrentCtx->maxPendingSwapBuffers) /* The driver is able to sleep when waiting for the completation of multiple swapbuffer operations instead of wasting CPU time (NOTE: you must uncomment the following line in the in order to enable this option) */ /* usleep(10000); */ ;#endif fxMesaCurrentCtx->stats.swapBuffer++; } }}/* * Shutdown Glide library */void GLAPIENTRYfxCloseHardware(void){ if (glbGlideInitialized) { if (glbTotNumCtx == 0) { grGlideShutdown(); glbGlideInitialized = 0; } }}#else/* * Need this to provide at least one external definition. */extern int gl_fx_dummy_function_api(void);intgl_fx_dummy_function_api(void){ return 0;}#endif /* FX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -