diff options
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/glide')
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxapi.c | 951 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdd.c | 2197 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddspan.c | 663 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddtex.c | 1849 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdrv.h | 771 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.c | 2309 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.h | 382 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.c | 269 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.h | 228 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.c | 2217 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.h | 850 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtexman.c | 874 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtris.c | 1834 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvb.c | 838 | ||||
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvbtmp.h | 369 |
15 files changed, 16601 insertions, 0 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxapi.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxapi.c new file mode 100644 index 000000000..e535e739b --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxapi.c @@ -0,0 +1,951 @@ +/* + * 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_DEBUG +int 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 */ + ); +#endif + +static 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 int +cleangraphics(void) +{ + glbTotNumCtx = 1; + fxMesaDestroyContext(fxMesaCurrentCtx); + + return 0; +} +#elif defined(__linux__) +static void +cleangraphics(void) +{ + glbTotNumCtx = 1; + fxMesaDestroyContext(fxMesaCurrentCtx); +} + +static void +cleangraphics_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 GLAPIENTRY +gl3DfxSetPaletteEXT(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 GLAPIENTRY +fxMesaCreateBestContext(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 GLAPIENTRY +fxMesaCreateContext(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; + 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_destroy_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 GLAPIENTRY +fxMesaUpdateScreenSize(fxMesaContext fxMesa) +{ + fxMesa->width = FX_grSstScreenWidth(); + fxMesa->height = FX_grSstScreenHeight(); +} + + +/* + * Destroy the given FX/Mesa context. + */ +void GLAPIENTRY +fxMesaDestroyContext(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_destroy_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 GLAPIENTRY +fxMesaMakeCurrent(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 GLAPIENTRY +fxMesaSwapBuffers(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 GLAPIENTRY +fxCloseHardware(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); +int +gl_fx_dummy_function_api(void) +{ + return 0; +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdd.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdd.c new file mode 100644 index 000000000..4e9df208b --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdd.c @@ -0,0 +1,2197 @@ +/* + * Mesa 3-D graphics library + * Version: 5.1 + * + * Copyright (C) 1999-2003 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 + */ + +/* fxdd.c - 3Dfx VooDoo Mesa device driver functions */ + + +#ifdef HAVE_CONFIG_H +#include "conf.h" +#endif + +#if defined(FX) + +#include "image.h" +#include "mtypes.h" +#include "fxdrv.h" +#include "buffers.h" +#include "enums.h" +#include "extensions.h" +#include "macros.h" +#include "texstore.h" +#include "teximage.h" +#include "swrast/swrast.h" +#include "swrast/s_context.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "array_cache/acache.h" + + + +/* lookup table for scaling 4 bit colors up to 8 bits */ +GLuint FX_rgb_scale_4[16] = { + 0, 17, 34, 51, 68, 85, 102, 119, + 136, 153, 170, 187, 204, 221, 238, 255 +}; + +/* lookup table for scaling 5 bit colors up to 8 bits */ +GLuint FX_rgb_scale_5[32] = { + 0, 8, 16, 25, 33, 41, 49, 58, + 66, 74, 82, 90, 99, 107, 115, 123, + 132, 140, 148, 156, 165, 173, 181, 189, + 197, 206, 214, 222, 230, 239, 247, 255 +}; + +/* lookup table for scaling 6 bit colors up to 8 bits */ +GLuint FX_rgb_scale_6[64] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 45, 49, 53, 57, 61, + 65, 69, 73, 77, 81, 85, 89, 93, + 97, 101, 105, 109, 113, 117, 121, 125, + 130, 134, 138, 142, 146, 150, 154, 158, + 162, 166, 170, 174, 178, 182, 186, 190, + 194, 198, 202, 206, 210, 215, 219, 223, + 227, 231, 235, 239, 243, 247, 251, 255 +}; + + +/* + * Disable color by masking out R, G, B, A + */ +static void fxDisableColor (fxMesaContext fxMesa) +{ + if (fxMesa->colDepth == 32) { + /* 32bpp mode */ + fxMesa->Glide.grColorMaskExt(FXFALSE, FXFALSE, FXFALSE, FXFALSE); + } else { + /* 15/16 bpp mode */ + grColorMask(FXFALSE, FXFALSE); + } +} + + +/**********************************************************************/ +/***** Miscellaneous functions *****/ +/**********************************************************************/ + +/* Return buffer size information */ +static void +fxDDGetBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx && FX_CONTEXT(ctx)) { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDGetBufferSize(...)\n"); + } + + *width = fxMesa->width; + *height = fxMesa->height; + } +} + + +static void +fxDDViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* poll for window size change and realloc software Z/stencil/etc if needed */ + _mesa_ResizeBuffersMESA(); +} + + +/* Implements glClearColor() */ +static void +fxDDClearColor(GLcontext * ctx, const GLfloat color[4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLubyte col[4]; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDClearColor(%f, %f, %f, %f)\n", + color[0], color[1], color[2], color[3]); + } + + CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]); + + fxMesa->clearC = FXCOLOR4(col); + fxMesa->clearA = col[3]; +} + + +/* Clear the color and/or depth buffers */ +static void fxDDClear( GLcontext *ctx, + GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM); + const GLuint stencil_size = fxMesa->haveHwStencil ? ctx->Visual.stencilBits : 0; + const FxU32 clearD = (FxU32) (ctx->DrawBuffer->_DepthMaxF * ctx->Depth.Clear); + const FxU8 clearS = (FxU8) (ctx->Stencil.Clear & 0xff); + + if ( TDFX_DEBUG & MESA_VERBOSE ) { + fprintf( stderr, "fxDDClear( %d, %d, %d, %d )\n", + (int) x, (int) y, (int) width, (int) height ); + } + + /* we can't clear accum buffers nor stereo */ + mask &= ~(BUFFER_BIT_ACCUM | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT); + + /* Need this check to respond to certain HW updates */ + if (fxMesa->new_state & (FX_NEW_SCISSOR | FX_NEW_COLOR_MASK)) { + fxSetupScissor(ctx); + fxSetupColorMask(ctx); + fxMesa->new_state &= ~(FX_NEW_SCISSOR | FX_NEW_COLOR_MASK); + } + + /* + * As per GL spec, color masking should be obeyed when clearing + */ + if (ctx->Visual.greenBits != 8) { + /* can only do color masking if running in 24/32bpp on Napalm */ + if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] || + ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) { + softwareMask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)); + mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); + } + } + + if (fxMesa->haveHwStencil) { + /* + * If we want to clear stencil, it must be enabled + * in the HW, even if the stencil test is not enabled + * in the OGL state. + */ + BEGIN_BOARD_LOCK(); + if (mask & BUFFER_BIT_STENCIL) { + fxMesa->Glide.grStencilMaskExt(fxMesa->unitsState.stencilWriteMask); + /* set stencil ref value = desired clear value */ + fxMesa->Glide.grStencilFuncExt(GR_CMP_ALWAYS, clearS, 0xff); + fxMesa->Glide.grStencilOpExt(GR_STENCILOP_REPLACE, + GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE); + grEnable(GR_STENCIL_MODE_EXT); + } + else { + grDisable(GR_STENCIL_MODE_EXT); + } + END_BOARD_LOCK(); + } else if (mask & BUFFER_BIT_STENCIL) { + softwareMask |= (mask & (BUFFER_BIT_STENCIL)); + mask &= ~(BUFFER_BIT_STENCIL); + } + + /* + * This may be ugly, but it's needed in order to work around a number + * of Glide bugs. + */ + BEGIN_CLIP_LOOP(); + { + /* + * This could probably be done fancier but doing each possible case + * explicitly is less error prone. + */ + switch (mask & ~BUFFER_BIT_STENCIL) { + case BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH: + /* back buffer & depth */ + grDepthMask(FXTRUE); + grRenderBuffer(GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) { + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + } + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + break; + case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_DEPTH: + /* XXX it appears that the depth buffer isn't cleared when + * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set. + * This is a work-around/ + */ + /* clear depth */ + grDepthMask(FXTRUE); + fxDisableColor(fxMesa); + grRenderBuffer(GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + fxSetupColorMask(ctx); + grDepthMask(FXFALSE); + /* clear front */ + grRenderBuffer(GR_BUFFER_FRONTBUFFER); + if (stencil_size > 0) + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + break; + case BUFFER_BIT_BACK_LEFT: + /* back buffer only */ + grDepthMask(FXFALSE); + grRenderBuffer(GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + break; + case BUFFER_BIT_FRONT_LEFT: + /* front buffer only */ + grDepthMask(FXFALSE); + grRenderBuffer(GR_BUFFER_FRONTBUFFER); + if (stencil_size > 0) + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + break; + case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT: + /* front and back */ + grDepthMask(FXFALSE); + grRenderBuffer(GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + grRenderBuffer(GR_BUFFER_FRONTBUFFER); + if (stencil_size > 0) + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + break; + case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH: + /* clear back and depth */ + grDepthMask(FXTRUE); + grRenderBuffer(GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + /* clear front */ + grDepthMask(FXFALSE); + grRenderBuffer(GR_BUFFER_FRONTBUFFER); + if (stencil_size > 0) + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + break; + case BUFFER_BIT_DEPTH: + /* just the depth buffer */ + grDepthMask(FXTRUE); + fxDisableColor(fxMesa); + grRenderBuffer(GR_BUFFER_BACKBUFFER); + if (stencil_size > 0) + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + else + grBufferClear(fxMesa->clearC, + fxMesa->clearA, + clearD); + fxSetupColorMask(ctx); + break; + default: + /* clear no color buffers or depth buffer but might clear stencil */ + if ((stencil_size > 0) && (mask & BUFFER_BIT_STENCIL)) { + /* XXX need this RenderBuffer call to work around Glide bug */ + grDepthMask(FXFALSE); + grRenderBuffer(GR_BUFFER_BACKBUFFER); + fxDisableColor(fxMesa); + fxMesa->Glide.grBufferClearExt(fxMesa->clearC, + fxMesa->clearA, + clearD, clearS); + fxSetupColorMask(ctx); + } + } + } + END_CLIP_LOOP(); + + if (fxMesa->haveHwStencil) { + /* We changed the stencil state above. Restore it! */ + fxSetupStencil(ctx); + } + fxSetupDepthTest(ctx); + grRenderBuffer(fxMesa->currentFB); + + if (softwareMask) + _swrast_Clear( ctx, softwareMask, all, x, y, width, height ); +} + + +/* Set the buffer used for drawing */ +/* XXX support for separate read/draw buffers hasn't been tested */ +/* XXX GL_NONE disables color, but fails to correctly maintain state */ +static void +fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDSetDrawBuffer(%x)\n", (int)mode); + } + + if (mode == GL_FRONT_LEFT) { + fxMesa->currentFB = GR_BUFFER_FRONTBUFFER; + grRenderBuffer(fxMesa->currentFB); + } + else if (mode == GL_BACK_LEFT) { + fxMesa->currentFB = GR_BUFFER_BACKBUFFER; + grRenderBuffer(fxMesa->currentFB); + } + else if (mode == GL_NONE) { + fxDisableColor(fxMesa); + } + else { + /* we'll need a software fallback */ + /* XXX not implemented */ + } + + /* update s/w fallback state */ + _swrast_DrawBuffer(ctx, mode); +} + + +static void +fxDDDrawBitmap2 (GLcontext *ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GrLfbInfo_t info; + GrLfbWriteMode_t mode; + FxU16 color; + const struct gl_pixelstore_attrib *finalUnpack; + struct gl_pixelstore_attrib scissoredUnpack; + + /* check if there's any raster operations enabled which we can't handle */ + if (swrast->_RasterMask & (ALPHATEST_BIT | + /*BLEND_BIT |*/ /* blending ok, through pixpipe */ + DEPTH_BIT | /* could be done with RGB:DEPTH */ + FOG_BIT | /* could be done with RGB:DEPTH */ + LOGIC_OP_BIT | + /*CLIP_BIT |*/ /* clipping ok, below */ + STENCIL_BIT | + MASKING_BIT | + MULTI_DRAW_BIT | + OCCLUSION_BIT | /* nope! at least not yet */ + TEXTURE_BIT | + FRAGPROG_BIT)) { + _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap); + return; + } + + /* make sure the pixelpipe is configured correctly */ + fxSetupFXUnits(ctx); + + /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */ + if (ctx->Scissor.Enabled) { + /* This is a bit tricky, but by carefully adjusting the px, py, + * width, height, skipPixels and skipRows values we can do + * scissoring without special code in the rendering loop. + */ + + /* we'll construct a new pixelstore struct */ + finalUnpack = &scissoredUnpack; + scissoredUnpack = *unpack; + if (scissoredUnpack.RowLength == 0) + scissoredUnpack.RowLength = width; + + /* clip left */ + if (px < ctx->Scissor.X) { + scissoredUnpack.SkipPixels += (ctx->Scissor.X - px); + width -= (ctx->Scissor.X - px); + px = ctx->Scissor.X; + } + /* clip right */ + if (px + width >= ctx->Scissor.X + ctx->Scissor.Width) { + width -= (px + width - (ctx->Scissor.X + ctx->Scissor.Width)); + } + /* clip bottom */ + if (py < ctx->Scissor.Y) { + scissoredUnpack.SkipRows += (ctx->Scissor.Y - py); + height -= (ctx->Scissor.Y - py); + py = ctx->Scissor.Y; + } + /* clip top */ + if (py + height >= ctx->Scissor.Y + ctx->Scissor.Height) { + height -= (py + height - (ctx->Scissor.Y + ctx->Scissor.Height)); + } + + if (width <= 0 || height <= 0) + return; + } + else { + finalUnpack = unpack; + } + + /* compute pixel value */ + { + GLint r = (GLint) (ctx->Current.RasterColor[RCOMP] * 255.0f); + GLint g = (GLint) (ctx->Current.RasterColor[GCOMP] * 255.0f); + GLint b = (GLint) (ctx->Current.RasterColor[BCOMP] * 255.0f); + GLint a = (GLint) (ctx->Current.RasterColor[ACOMP] * 255.0f); + if (fxMesa->colDepth == 15) { + color = TDFXPACKCOLOR1555(b, g, r, a); + mode = GR_LFBWRITEMODE_1555; + } else { + color = fxMesa->bgrOrder ? TDFXPACKCOLOR565(r, g, b) : TDFXPACKCOLOR565(b, g, r); + mode = GR_LFBWRITEMODE_565; + } + } + + info.size = sizeof(info); + if (!grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, + GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) { + _swrast_Bitmap(ctx, px, py, width, height, finalUnpack, bitmap); + return; + } + + { + const GLint winX = 0; + const GLint winY = 0; + /* The dest stride depends on the hardware and whether we're drawing + * to the front or back buffer. This compile-time test seems to do + * the job for now. + */ + const GLint dstStride = info.strideInBytes / 2; /* stride in GLushorts */ + + GLint row; + /* compute dest address of bottom-left pixel in bitmap */ + GLushort *dst = (GLushort *) info.lfbPtr + + (winY + py) * dstStride + (winX + px); + + for (row = 0; row < height; row++) { + const GLubyte *src = + (const GLubyte *) _mesa_image_address2d(finalUnpack, + bitmap, width, height, + GL_COLOR_INDEX, GL_BITMAP, + row, 0); + if (finalUnpack->LsbFirst) { + /* least significan bit first */ + GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7); + GLint col; + for (col = 0; col < width; col++) { + if (*src & mask) { + dst[col] = color; + } + if (mask == 128U) { + src++; + mask = 1U; + } + else { + mask = mask << 1; + } + } + if (mask != 1) + src++; + } + else { + /* most significan bit first */ + GLubyte mask = 128U >> (finalUnpack->SkipPixels & 0x7); + GLint col; + for (col = 0; col < width; col++) { + if (*src & mask) { + dst[col] = color; + } + if (mask == 1U) { + src++; + mask = 128U; + } + else { + mask = mask >> 1; + } + } + if (mask != 128) + src++; + } + dst += dstStride; + } + } + + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); +} + +static void +fxDDDrawBitmap4 (GLcontext *ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GrLfbInfo_t info; + FxU32 color; + const struct gl_pixelstore_attrib *finalUnpack; + struct gl_pixelstore_attrib scissoredUnpack; + + /* check if there's any raster operations enabled which we can't handle */ + if ((swrast->_RasterMask & (/*ALPHATEST_BIT |*/ + /*BLEND_BIT |*/ /* blending ok, through pixpipe */ + DEPTH_BIT | /* could be done with RGB:DEPTH */ + FOG_BIT | /* could be done with RGB:DEPTH */ + LOGIC_OP_BIT | + /*CLIP_BIT |*/ /* clipping ok, below */ + STENCIL_BIT | + /*MASKING_BIT |*/ /* masking ok, we're in 32bpp */ + MULTI_DRAW_BIT | + OCCLUSION_BIT | /* nope! at least not yet */ + TEXTURE_BIT | + FRAGPROG_BIT)) + ) { + _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap); + return; + } + + /* make sure the pixelpipe is configured correctly */ + fxSetupFXUnits(ctx); + + /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */ + if (ctx->Scissor.Enabled) { + /* This is a bit tricky, but by carefully adjusting the px, py, + * width, height, skipPixels and skipRows values we can do + * scissoring without special code in the rendering loop. + */ + + /* we'll construct a new pixelstore struct */ + finalUnpack = &scissoredUnpack; + scissoredUnpack = *unpack; + if (scissoredUnpack.RowLength == 0) + scissoredUnpack.RowLength = width; + + /* clip left */ + if (px < ctx->Scissor.X) { + scissoredUnpack.SkipPixels += (ctx->Scissor.X - px); + width -= (ctx->Scissor.X - px); + px = ctx->Scissor.X; + } + /* clip right */ + if (px + width >= ctx->Scissor.X + ctx->Scissor.Width) { + width -= (px + width - (ctx->Scissor.X + ctx->Scissor.Width)); + } + /* clip bottom */ + if (py < ctx->Scissor.Y) { + scissoredUnpack.SkipRows += (ctx->Scissor.Y - py); + height -= (ctx->Scissor.Y - py); + py = ctx->Scissor.Y; + } + /* clip top */ + if (py + height >= ctx->Scissor.Y + ctx->Scissor.Height) { + height -= (py + height - (ctx->Scissor.Y + ctx->Scissor.Height)); + } + + if (width <= 0 || height <= 0) + return; + } + else { + finalUnpack = unpack; + } + + /* compute pixel value */ + { + GLint r = (GLint) (ctx->Current.RasterColor[RCOMP] * 255.0f); + GLint g = (GLint) (ctx->Current.RasterColor[GCOMP] * 255.0f); + GLint b = (GLint) (ctx->Current.RasterColor[BCOMP] * 255.0f); + GLint a = (GLint) (ctx->Current.RasterColor[ACOMP] * 255.0f); + color = TDFXPACKCOLOR8888(b, g, r, a); + } + + info.size = sizeof(info); + if (!grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_8888, + GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) { + _swrast_Bitmap(ctx, px, py, width, height, finalUnpack, bitmap); + return; + } + + { + const GLint winX = 0; + const GLint winY = 0; + /* The dest stride depends on the hardware and whether we're drawing + * to the front or back buffer. This compile-time test seems to do + * the job for now. + */ + const GLint dstStride = info.strideInBytes / 4; /* stride in GLuints */ + + GLint row; + /* compute dest address of bottom-left pixel in bitmap */ + GLuint *dst = (GLuint *) info.lfbPtr + + (winY + py) * dstStride + (winX + px); + + for (row = 0; row < height; row++) { + const GLubyte *src = + (const GLubyte *) _mesa_image_address2d(finalUnpack, + bitmap, width, height, + GL_COLOR_INDEX, GL_BITMAP, + row, 0); + if (finalUnpack->LsbFirst) { + /* least significan bit first */ + GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7); + GLint col; + for (col = 0; col < width; col++) { + if (*src & mask) { + dst[col] = color; + } + if (mask == 128U) { + src++; + mask = 1U; + } + else { + mask = mask << 1; + } + } + if (mask != 1) + src++; + } + else { + /* most significan bit first */ + GLubyte mask = 128U >> (finalUnpack->SkipPixels & 0x7); + GLint col; + for (col = 0; col < width; col++) { + if (*src & mask) { + dst[col] = color; + } + if (mask == 1U) { + src++; + mask = 128U; + } + else { + mask = mask >> 1; + } + } + if (mask != 128) + src++; + } + dst += dstStride; + } + } + + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); +} + + +static void +fxDDReadPixels565 (GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + GLvoid *dstImage) +{ + if (ctx->_ImageTransferState/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) { + _swrast_ReadPixels(ctx, x, y, width, height, format, type, + packing, dstImage); + return; + } + else { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = 0; + const GLint winY = fxMesa->height - 1; + const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */ + const GLushort *src = (const GLushort *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dstImage, + width, height, format, + type, 0, 0); + GLint dstStride = + _mesa_image_row_stride(packing, width, format, type); + + if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { + /* convert 5R6G5B into 8R8G8B */ + GLint row, col; + const GLint halfWidth = width >> 1; + const GLint extraPixel = (width & 1); + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < halfWidth; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + *d++ = FX_rgb_scale_5[(pixel >> 11) & 0x1f]; + *d++ = FX_rgb_scale_6[(pixel >> 5) & 0x3f]; + *d++ = FX_rgb_scale_5[ pixel & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 27) & 0x1f]; + *d++ = FX_rgb_scale_6[(pixel >> 21) & 0x3f]; + *d++ = FX_rgb_scale_5[(pixel >> 16) & 0x1f]; + } + if (extraPixel) { + GLushort pixel = src[width - 1]; + *d++ = FX_rgb_scale_5[(pixel >> 11) & 0x1f]; + *d++ = FX_rgb_scale_6[(pixel >> 5) & 0x3f]; + *d++ = FX_rgb_scale_5[ pixel & 0x1f]; + } + dst += dstStride; + src -= srcStride; + } + } + else if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + /* convert 5R6G5B into 8R8G8B8A */ + GLint row, col; + const GLint halfWidth = width >> 1; + const GLint extraPixel = (width & 1); + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < halfWidth; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + *d++ = FX_rgb_scale_5[(pixel >> 11) & 0x1f]; + *d++ = FX_rgb_scale_6[(pixel >> 5) & 0x3f]; + *d++ = FX_rgb_scale_5[ pixel & 0x1f]; + *d++ = 255; + *d++ = FX_rgb_scale_5[(pixel >> 27) & 0x1f]; + *d++ = FX_rgb_scale_6[(pixel >> 21) & 0x3f]; + *d++ = FX_rgb_scale_5[(pixel >> 16) & 0x1f]; + *d++ = 255; + } + if (extraPixel) { + const GLushort pixel = src[width - 1]; + *d++ = FX_rgb_scale_5[(pixel >> 11) & 0x1f]; + *d++ = FX_rgb_scale_6[(pixel >> 5) & 0x3f]; + *d++ = FX_rgb_scale_5[ pixel & 0x1f]; + *d++ = 255; + } + dst += dstStride; + src -= srcStride; + } + } + else if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { + /* directly memcpy 5R6G5B pixels into client's buffer */ + const GLint widthInBytes = width * 2; + GLint row; + for (row = 0; row < height; row++) { + MEMCPY(dst, src, widthInBytes); + dst += dstStride; + src -= srcStride; + } + } + else { + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + END_BOARD_LOCK(); + _swrast_ReadPixels(ctx, x, y, width, height, format, type, + packing, dstImage); + return; + } + + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); + } +} + +static void +fxDDReadPixels555 (GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + GLvoid *dstImage) +{ + if (ctx->_ImageTransferState/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) { + _swrast_ReadPixels(ctx, x, y, width, height, format, type, + packing, dstImage); + return; + } + else { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = 0; + const GLint winY = fxMesa->height - 1; + const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */ + const GLushort *src = (const GLushort *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dstImage, + width, height, format, + type, 0, 0); + GLint dstStride = + _mesa_image_row_stride(packing, width, format, type); + + if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { + /* convert 5R5G5B into 8R8G8B */ + GLint row, col; + const GLint halfWidth = width >> 1; + const GLint extraPixel = (width & 1); + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < halfWidth; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + *d++ = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; + *d++ = FX_rgb_scale_5[ pixel & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 26) & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 21) & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 16) & 0x1f]; + } + if (extraPixel) { + GLushort pixel = src[width - 1]; + *d++ = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; + *d++ = FX_rgb_scale_5[ pixel & 0x1f]; + } + dst += dstStride; + src -= srcStride; + } + } + else if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + /* convert 5R6G5B into 8R8G8B8A */ + GLint row, col; + const GLint halfWidth = width >> 1; + const GLint extraPixel = (width & 1); + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < halfWidth; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + *d++ = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; + *d++ = FX_rgb_scale_5[ pixel & 0x1f]; + *d++ = (pixel & 0x8000) ? 255 : 0; + *d++ = FX_rgb_scale_5[(pixel >> 26) & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 21) & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 16) & 0x1f]; + *d++ = (pixel & 0x80000000) ? 255 : 0; + } + if (extraPixel) { + const GLushort pixel = src[width - 1]; + *d++ = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; + *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; + *d++ = FX_rgb_scale_5[ pixel & 0x1f]; + *d++ = (pixel & 0x8000) ? 255 : 0; + } + dst += dstStride; + src -= srcStride; + } + } + else if (format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { + /* directly memcpy 5R5G5B pixels into client's buffer */ + const GLint widthInBytes = width * 2; + GLint row; + for (row = 0; row < height; row++) { + MEMCPY(dst, src, widthInBytes); + dst += dstStride; + src -= srcStride; + } + } + else { + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + END_BOARD_LOCK(); + _swrast_ReadPixels(ctx, x, y, width, height, format, type, + packing, dstImage); + return; + } + + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); + } +} + +static void +fxDDReadPixels8888 (GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + GLvoid *dstImage) +{ + if (ctx->_ImageTransferState/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) { + _swrast_ReadPixels(ctx, x, y, width, height, format, type, + packing, dstImage); + return; + } + else { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = 0; + const GLint winY = fxMesa->height - 1; + const GLint srcStride = info.strideInBytes / 4; /* stride in GLuints */ + const GLuint *src = (const GLuint *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dstImage, + width, height, format, + type, 0, 0); + GLint dstStride = + _mesa_image_row_stride(packing, width, format, type); + + if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { + /* convert 8A8R8G8B into 8R8G8B */ + GLint row, col; + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < width; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + *d++ = pixel >> 16; + *d++ = pixel >> 8; + *d++ = pixel; + } + dst += dstStride; + src -= srcStride; + } + } + else if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + /* 8A8R8G8B pixels into client's buffer */ + GLint row, col; + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < width; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + *d++ = pixel >> 16; + *d++ = pixel >> 8; + *d++ = pixel; + *d++ = pixel >> 24; + } + dst += dstStride; + src -= srcStride; + } + } + else if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { + /* convert 8A8R8G8B into 5R6G5B */ + GLint row, col; + for (row = 0; row < height; row++) { + GLushort *d = (GLushort *)dst; + for (col = 0; col < width; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + *d++ = (((pixel >> 16) & 0xf8) << 8) | + (((pixel >> 8) & 0xfc) << 3) | + ((pixel & 0xf8) >> 3); + } + dst += dstStride; + src -= srcStride; + } + } + else { + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + END_BOARD_LOCK(); + _swrast_ReadPixels(ctx, x, y, width, height, format, type, + packing, dstImage); + return; + } + + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); + } +} + + +static void +fxDDDrawPixels555 (GLcontext * ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GrLfbInfo_t info; + const struct gl_pixelstore_attrib *finalUnpack; + struct gl_pixelstore_attrib scissoredUnpack; + + if (ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F || + (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| + IMAGE_MAP_COLOR_BIT)) || + (swrast->_RasterMask & (ALPHATEST_BIT | + /*BLEND_BIT |*/ /* blending ok, through pixpipe */ + DEPTH_BIT | /* could be done with RGB:DEPTH */ + FOG_BIT | /* could be done with RGB:DEPTH */ + LOGIC_OP_BIT | + /*CLIP_BIT |*/ /* clipping ok, below */ + STENCIL_BIT | + MASKING_BIT | + MULTI_DRAW_BIT | + OCCLUSION_BIT | /* nope! at least not yet */ + TEXTURE_BIT | + FRAGPROG_BIT)) || + fxMesa->fallback) + { + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + return; + } + + /* make sure the pixelpipe is configured correctly */ + fxSetupFXUnits(ctx); + + /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */ + if (ctx->Scissor.Enabled) { + /* This is a bit tricky, but by carefully adjusting the px, py, + * width, height, skipPixels and skipRows values we can do + * scissoring without special code in the rendering loop. + */ + + /* we'll construct a new pixelstore struct */ + finalUnpack = &scissoredUnpack; + scissoredUnpack = *unpack; + if (scissoredUnpack.RowLength == 0) + scissoredUnpack.RowLength = width; + + /* clip left */ + if (x < ctx->Scissor.X) { + scissoredUnpack.SkipPixels += (ctx->Scissor.X - x); + width -= (ctx->Scissor.X - x); + x = ctx->Scissor.X; + } + /* clip right */ + if (x + width >= ctx->Scissor.X + ctx->Scissor.Width) { + width -= (x + width - (ctx->Scissor.X + ctx->Scissor.Width)); + } + /* clip bottom */ + if (y < ctx->Scissor.Y) { + scissoredUnpack.SkipRows += (ctx->Scissor.Y - y); + height -= (ctx->Scissor.Y - y); + y = ctx->Scissor.Y; + } + /* clip top */ + if (y + height >= ctx->Scissor.Y + ctx->Scissor.Height) { + height -= (y + height - (ctx->Scissor.Y + ctx->Scissor.Height)); + } + + if (width <= 0 || height <= 0) + return; + } + else { + finalUnpack = unpack; + } + + info.size = sizeof(info); + if (!grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_1555, + GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) { + _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels); + return; + } + + { + const GLint winX = 0; + const GLint winY = 0; + + const GLint dstStride = info.strideInBytes / 2; /* stride in GLushorts */ + GLushort *dst = (GLushort *) info.lfbPtr + (winY + y) * dstStride + (winX + x); + + if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + GLint row; + for (row = 0; row < height; row++) { + GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack, + pixels, width, height, format, type, row, 0); + GLint col; + for (col = 0; col < width; col++) { + dst[col] = TDFXPACKCOLOR1555(src[2], src[1], src[0], src[3]); + src += 4; + } + dst += dstStride; + } + } + else if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { + GLint row; + for (row = 0; row < height; row++) { + GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack, + pixels, width, height, format, type, row, 0); + GLint col; + for (col = 0; col < width; col++) { + dst[col] = TDFXPACKCOLOR1555(src[2], src[1], src[0], 255); + src += 3; + } + dst += dstStride; + } + } + else { + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels); + return; + } + + } + + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); +} + + +static void +fxDDDrawPixels565 (GLcontext * ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GrLfbInfo_t info; + const struct gl_pixelstore_attrib *finalUnpack; + struct gl_pixelstore_attrib scissoredUnpack; + + if (ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F || + (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| + IMAGE_MAP_COLOR_BIT)) || + (swrast->_RasterMask & (ALPHATEST_BIT | + /*BLEND_BIT |*/ /* blending ok, through pixpipe */ + DEPTH_BIT | /* could be done with RGB:DEPTH */ + FOG_BIT | /* could be done with RGB:DEPTH */ + LOGIC_OP_BIT | + /*CLIP_BIT |*/ /* clipping ok, below */ + STENCIL_BIT | + MASKING_BIT | + MULTI_DRAW_BIT | + OCCLUSION_BIT | /* nope! at least not yet */ + TEXTURE_BIT | + FRAGPROG_BIT)) || + fxMesa->fallback) + { + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + return; + } + + /* make sure the pixelpipe is configured correctly */ + fxSetupFXUnits(ctx); + + /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */ + if (ctx->Scissor.Enabled) { + /* This is a bit tricky, but by carefully adjusting the px, py, + * width, height, skipPixels and skipRows values we can do + * scissoring without special code in the rendering loop. + */ + + /* we'll construct a new pixelstore struct */ + finalUnpack = &scissoredUnpack; + scissoredUnpack = *unpack; + if (scissoredUnpack.RowLength == 0) + scissoredUnpack.RowLength = width; + + /* clip left */ + if (x < ctx->Scissor.X) { + scissoredUnpack.SkipPixels += (ctx->Scissor.X - x); + width -= (ctx->Scissor.X - x); + x = ctx->Scissor.X; + } + /* clip right */ + if (x + width >= ctx->Scissor.X + ctx->Scissor.Width) { + width -= (x + width - (ctx->Scissor.X + ctx->Scissor.Width)); + } + /* clip bottom */ + if (y < ctx->Scissor.Y) { + scissoredUnpack.SkipRows += (ctx->Scissor.Y - y); + height -= (ctx->Scissor.Y - y); + y = ctx->Scissor.Y; + } + /* clip top */ + if (y + height >= ctx->Scissor.Y + ctx->Scissor.Height) { + height -= (y + height - (ctx->Scissor.Y + ctx->Scissor.Height)); + } + + if (width <= 0 || height <= 0) + return; + } + else { + finalUnpack = unpack; + } + + info.size = sizeof(info); + if (!grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_565, + GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) { + _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels); + return; + } + + { + const GLint winX = 0; + const GLint winY = 0; + + const GLint dstStride = info.strideInBytes / 2; /* stride in GLushorts */ + GLushort *dst = (GLushort *) info.lfbPtr + (winY + y) * dstStride + (winX + x); + + if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + GLint row; + for (row = 0; row < height; row++) { + GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack, + pixels, width, height, format, type, row, 0); + GLint col; + for (col = 0; col < width; col++) { + dst[col] = TDFXPACKCOLOR565(src[2], src[1], src[0]); + src += 4; + } + dst += dstStride; + } + } + else if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { + GLint row; + for (row = 0; row < height; row++) { + GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack, + pixels, width, height, format, type, row, 0); + GLint col; + for (col = 0; col < width; col++) { + dst[col] = TDFXPACKCOLOR565(src[2], src[1], src[0]); + src += 3; + } + dst += dstStride; + } + } + else { + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels); + return; + } + + } + + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); +} + + +static void +fxDDDrawPixels565_rev (GLcontext * ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GrLfbInfo_t info; + const struct gl_pixelstore_attrib *finalUnpack; + struct gl_pixelstore_attrib scissoredUnpack; + + if (ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F || + (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| + IMAGE_MAP_COLOR_BIT)) || + (swrast->_RasterMask & (ALPHATEST_BIT | + /*BLEND_BIT |*/ /* blending ok, through pixpipe */ + DEPTH_BIT | /* could be done with RGB:DEPTH */ + FOG_BIT | /* could be done with RGB:DEPTH */ + LOGIC_OP_BIT | + /*CLIP_BIT |*/ /* clipping ok, below */ + STENCIL_BIT | + MASKING_BIT | + MULTI_DRAW_BIT | + OCCLUSION_BIT | /* nope! at least not yet */ + TEXTURE_BIT | + FRAGPROG_BIT)) || + fxMesa->fallback) + { + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + return; + } + + /* make sure the pixelpipe is configured correctly */ + fxSetupFXUnits(ctx); + + /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */ + if (ctx->Scissor.Enabled) { + /* This is a bit tricky, but by carefully adjusting the px, py, + * width, height, skipPixels and skipRows values we can do + * scissoring without special code in the rendering loop. + */ + + /* we'll construct a new pixelstore struct */ + finalUnpack = &scissoredUnpack; + scissoredUnpack = *unpack; + if (scissoredUnpack.RowLength == 0) + scissoredUnpack.RowLength = width; + + /* clip left */ + if (x < ctx->Scissor.X) { + scissoredUnpack.SkipPixels += (ctx->Scissor.X - x); + width -= (ctx->Scissor.X - x); + x = ctx->Scissor.X; + } + /* clip right */ + if (x + width >= ctx->Scissor.X + ctx->Scissor.Width) { + width -= (x + width - (ctx->Scissor.X + ctx->Scissor.Width)); + } + /* clip bottom */ + if (y < ctx->Scissor.Y) { + scissoredUnpack.SkipRows += (ctx->Scissor.Y - y); + height -= (ctx->Scissor.Y - y); + y = ctx->Scissor.Y; + } + /* clip top */ + if (y + height >= ctx->Scissor.Y + ctx->Scissor.Height) { + height -= (y + height - (ctx->Scissor.Y + ctx->Scissor.Height)); + } + + if (width <= 0 || height <= 0) + return; + } + else { + finalUnpack = unpack; + } + + info.size = sizeof(info); + if (!grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_565, + GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) { + _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels); + return; + } + + { + const GLint winX = 0; + const GLint winY = 0; + + const GLint dstStride = info.strideInBytes / 2; /* stride in GLushorts */ + GLushort *dst = (GLushort *) info.lfbPtr + (winY + y) * dstStride + (winX + x); + + if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + GLint row; + for (row = 0; row < height; row++) { + GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack, + pixels, width, height, format, type, row, 0); + GLint col; + for (col = 0; col < width; col++) { + dst[col] = TDFXPACKCOLOR565(src[0], src[1], src[2]); + src += 4; + } + dst += dstStride; + } + } + else if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { + GLint row; + for (row = 0; row < height; row++) { + GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack, + pixels, width, height, format, type, row, 0); + GLint col; + for (col = 0; col < width; col++) { + dst[col] = TDFXPACKCOLOR565(src[0], src[1], src[2]); + src += 3; + } + dst += dstStride; + } + } + else { + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels); + return; + } + + } + + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); +} + + +static void +fxDDDrawPixels8888 (GLcontext * ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GrLfbInfo_t info; + const struct gl_pixelstore_attrib *finalUnpack; + struct gl_pixelstore_attrib scissoredUnpack; + + if (ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F || + (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| + IMAGE_MAP_COLOR_BIT)) || + (swrast->_RasterMask & (/*ALPHATEST_BIT |*/ + /*BLEND_BIT |*/ /* blending ok, through pixpipe */ + DEPTH_BIT | /* could be done with RGB:DEPTH */ + FOG_BIT | /* could be done with RGB:DEPTH */ + LOGIC_OP_BIT | + /*CLIP_BIT |*/ /* clipping ok, below */ + STENCIL_BIT | + /*MASKING_BIT |*/ /* masking ok, we're in 32bpp */ + MULTI_DRAW_BIT | + OCCLUSION_BIT | /* nope! at least not yet */ + TEXTURE_BIT | + FRAGPROG_BIT)) || + fxMesa->fallback) + { + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + return; + } + + /* make sure the pixelpipe is configured correctly */ + fxSetupFXUnits(ctx); + + /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */ + if (ctx->Scissor.Enabled) { + /* This is a bit tricky, but by carefully adjusting the px, py, + * width, height, skipPixels and skipRows values we can do + * scissoring without special code in the rendering loop. + */ + + /* we'll construct a new pixelstore struct */ + finalUnpack = &scissoredUnpack; + scissoredUnpack = *unpack; + if (scissoredUnpack.RowLength == 0) + scissoredUnpack.RowLength = width; + + /* clip left */ + if (x < ctx->Scissor.X) { + scissoredUnpack.SkipPixels += (ctx->Scissor.X - x); + width -= (ctx->Scissor.X - x); + x = ctx->Scissor.X; + } + /* clip right */ + if (x + width >= ctx->Scissor.X + ctx->Scissor.Width) { + width -= (x + width - (ctx->Scissor.X + ctx->Scissor.Width)); + } + /* clip bottom */ + if (y < ctx->Scissor.Y) { + scissoredUnpack.SkipRows += (ctx->Scissor.Y - y); + height -= (ctx->Scissor.Y - y); + y = ctx->Scissor.Y; + } + /* clip top */ + if (y + height >= ctx->Scissor.Y + ctx->Scissor.Height) { + height -= (y + height - (ctx->Scissor.Y + ctx->Scissor.Height)); + } + + if (width <= 0 || height <= 0) + return; + } + else { + finalUnpack = unpack; + } + + info.size = sizeof(info); + if (!grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_8888, + GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) { + _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels); + return; + } + + { + const GLint winX = 0; + const GLint winY = 0; + + const GLint dstStride = info.strideInBytes / 4; /* stride in GLuints */ + GLuint *dst = (GLuint *) info.lfbPtr + (winY + y) * dstStride + (winX + x); + + if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + /* directly memcpy 8A8R8G8B pixels to screen */ + const GLint widthInBytes = width * 4; + GLint row; + for (row = 0; row < height; row++) { + GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack, + pixels, width, height, format, type, row, 0); + MEMCPY(dst, src, widthInBytes); + dst += dstStride; + } + } + else if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { + GLint row; + for (row = 0; row < height; row++) { + GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack, + pixels, width, height, format, type, row, 0); + GLint col; + for (col = 0; col < width; col++) { + dst[col] = TDFXPACKCOLOR8888(src[2], src[1], src[0], 255); + src += 3; + } + dst += dstStride; + } + } + else { + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels); + return; + } + + } + + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); +} + + +static void +fxDDFinish(GLcontext * ctx) +{ + grFlush(); +} + + + + + +/* KW: Put the word Mesa in the render string because quakeworld + * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE). + * Why? + */ +static const GLubyte * +fxDDGetString(GLcontext * ctx, GLenum name) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + switch (name) { + case GL_RENDERER: + return (GLubyte *)fxMesa->rendererString; +#if __WIN32__ /* hack to advertise vanilla extension names */ + case GL_EXTENSIONS: + if (ctx->Extensions.String == NULL) { + GLubyte *ext = _mesa_make_extension_string(ctx); + if (ext != NULL) { + ctx->Extensions.String = _mesa_malloc(strlen((char *)ext) + 256); + if (ctx->Extensions.String != NULL) { + strcpy((char *)ctx->Extensions.String, (char *)ext); + /* put any additional extension names here */ +#if 0 + strcat((char *)ctx->Extensions.String, " 3DFX_set_global_palette"); +#endif +#if __WIN32__ + strcat((char *)ctx->Extensions.String, " WGL_3DFX_gamma_control"); + strcat((char *)ctx->Extensions.String, " WGL_EXT_swap_control"); + strcat((char *)ctx->Extensions.String, " WGL_EXT_extensions_string WGL_ARB_extensions_string"); +#endif + /* put any additional extension names here */ + _mesa_free(ext); + } else { + ctx->Extensions.String = ext; + } + } + } + return ctx->Extensions.String; +#endif + default: + return NULL; + } +} + +static const struct tnl_pipeline_stage *fx_pipeline[] = { + &_tnl_vertex_transform_stage, /* XXX todo - Add the fastpath here */ + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + &_tnl_point_attenuation_stage, +#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program) + &_tnl_arb_vertex_program_stage, + &_tnl_vertex_program_stage, +#endif + &_tnl_render_stage, + 0, +}; + + + + +int +fxDDInitFxMesaContext(fxMesaContext fxMesa) +{ + GLcontext *ctx = fxMesa->glCtx; + + FX_setupGrVertexLayout(); + + fxMesa->color = 0xffffffff; + fxMesa->clearC = 0; + fxMesa->clearA = 0; + + fxMesa->stats.swapBuffer = 0; + fxMesa->stats.reqTexUpload = 0; + fxMesa->stats.texUpload = 0; + fxMesa->stats.memTexUpload = 0; + + fxMesa->tmuSrc = FX_TMU_NONE; + fxMesa->lastUnitsMode = FX_UM_NONE; + fxTMInit(fxMesa); + + /* FX units setup */ + + fxMesa->unitsState.alphaTestEnabled = GL_FALSE; + fxMesa->unitsState.alphaTestFunc = GL_ALWAYS; + fxMesa->unitsState.alphaTestRefValue = 0.0; + + fxMesa->unitsState.blendEnabled = GL_FALSE; + fxMesa->unitsState.blendSrcFuncRGB = GR_BLEND_ONE; + fxMesa->unitsState.blendDstFuncRGB = GR_BLEND_ZERO; + fxMesa->unitsState.blendSrcFuncAlpha = GR_BLEND_ONE; + fxMesa->unitsState.blendDstFuncAlpha = GR_BLEND_ZERO; + fxMesa->unitsState.blendEqRGB = GR_BLEND_OP_ADD; + fxMesa->unitsState.blendEqAlpha = GR_BLEND_OP_ADD; + + fxMesa->unitsState.depthTestEnabled = GL_FALSE; + fxMesa->unitsState.depthMask = GL_TRUE; + fxMesa->unitsState.depthTestFunc = GL_LESS; + fxMesa->unitsState.depthBias = 0; + + fxMesa->unitsState.stencilWriteMask = 0xff; + + if (fxMesa->colDepth == 32) { + /* 32bpp */ + fxMesa->Glide.grColorMaskExt(FXTRUE, FXTRUE, FXTRUE, fxMesa->haveHwAlpha); + } else { + /* 15/16 bpp mode */ + grColorMask(FXTRUE, fxMesa->haveHwAlpha); + } + + fxMesa->currentFB = fxMesa->haveDoubleBuffer ? GR_BUFFER_BACKBUFFER : GR_BUFFER_FRONTBUFFER; + grRenderBuffer(fxMesa->currentFB); + + fxMesa->state = MALLOC(FX_grGetInteger(GR_GLIDE_STATE_SIZE)); + fxMesa->fogTable = (GrFog_t *) MALLOC(FX_grGetInteger(GR_FOG_TABLE_ENTRIES) * + sizeof(GrFog_t)); + + if (!fxMesa->state || !fxMesa->fogTable) { + if (fxMesa->state) + FREE(fxMesa->state); + if (fxMesa->fogTable) + FREE(fxMesa->fogTable); + return 0; + } + + if (fxMesa->haveZBuffer) { + grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER); + } + + if (!fxMesa->bgrOrder) { + grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); + } + + if (fxMesa->Glide.grSetNumPendingBuffers != NULL) { + fxMesa->Glide.grSetNumPendingBuffers(fxMesa->maxPendingSwapBuffers); + } + + fxMesa->textureAlign = FX_grGetInteger(GR_TEXTURE_ALIGN); + /* [koolsmoky] */ + { + char *env; + int textureLevels = 0; + int textureSize = FX_grGetInteger(GR_MAX_TEXTURE_SIZE); + do { + textureLevels++; + } while ((textureSize >>= 0x1) & 0x7ff); + ctx->Const.MaxTextureLevels = textureLevels; + ctx->Const.MaxTextureLodBias = /*textureLevels - 1*/8; /* Glide bug */ +#if FX_RESCALE_BIG_TEXURES_HACK + fxMesa->textureMaxLod = textureLevels - 1; + if ((env = getenv("MESA_FX_MAXLOD")) != NULL) { + int maxLevels = atoi(env) + 1; + if ((maxLevels <= MAX_TEXTURE_LEVELS) && (maxLevels > textureLevels)) { + ctx->Const.MaxTextureLevels = maxLevels; + } + } +#endif + } + ctx->Const.MaxTextureCoordUnits = + ctx->Const.MaxTextureImageUnits = fxMesa->haveTwoTMUs ? 2 : 1; + ctx->Const.MaxTextureUnits = MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits); + + fxMesa->new_state = _NEW_ALL; + if (!fxMesa->haveHwStencil) { + /* don't touch stencil if there is none */ + fxMesa->new_state &= ~FX_NEW_STENCIL; + } + + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext(ctx); + _ac_CreateContext(ctx); + _tnl_CreateContext(ctx); + _swsetup_CreateContext(ctx); + + /* Install customized pipeline */ + _tnl_destroy_pipeline(ctx); + _tnl_install_pipeline(ctx, fx_pipeline); + + fxAllocVB(ctx); + + fxSetupDDPointers(ctx); + fxDDInitTriFuncs(ctx); + + /* Tell the software rasterizer to use pixel fog always. + */ + _swrast_allow_vertex_fog(ctx, GL_FALSE); + _swrast_allow_pixel_fog(ctx, GL_TRUE); + _tnl_allow_vertex_fog( ctx, GL_FALSE ); + _tnl_allow_pixel_fog( ctx, GL_TRUE ); + + /* Tell tnl not to calculate or use vertex fog factors. (Needed to + * tell render stage not to clip fog coords). + */ +/* _tnl_calculate_vertex_fog( ctx, GL_FALSE ); */ + + fxDDInitExtensions(ctx); + +#if 0 + /* do we want dither? It just looks bad... */ + grEnable(GR_ALLOW_MIPMAP_DITHER); +#endif + grGlideGetState((GrState *) fxMesa->state); + + return 1; +} + +/* Undo the above. + */ +void +fxDDDestroyFxMesaContext(fxMesaContext fxMesa) +{ + _swsetup_DestroyContext(fxMesa->glCtx); + _tnl_DestroyContext(fxMesa->glCtx); + _ac_DestroyContext(fxMesa->glCtx); + _swrast_DestroyContext(fxMesa->glCtx); + + if (fxMesa->state) + FREE(fxMesa->state); + if (fxMesa->fogTable) + FREE(fxMesa->fogTable); + fxFreeVB(fxMesa->glCtx); +} + + + + +void +fxDDInitExtensions(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + +#if 1 /* multipass ColorSum stage */ + _mesa_enable_extension(ctx, "GL_EXT_secondary_color"); +#endif + + _mesa_enable_extension(ctx, "GL_ARB_point_sprite"); + _mesa_enable_extension(ctx, "GL_EXT_point_parameters"); + _mesa_enable_extension(ctx, "GL_EXT_paletted_texture"); + _mesa_enable_extension(ctx, "GL_EXT_texture_lod_bias"); + _mesa_enable_extension(ctx, "GL_EXT_shared_texture_palette"); + _mesa_enable_extension(ctx, "GL_EXT_blend_func_separate"); + _mesa_enable_extension(ctx, "GL_EXT_texture_env_add"); + _mesa_enable_extension(ctx, "GL_EXT_stencil_wrap"); + _mesa_enable_extension(ctx, "GL_EXT_stencil_two_side"); + + if (fxMesa->haveTwoTMUs) { + _mesa_enable_extension(ctx, "GL_ARB_multitexture"); + } + + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + _mesa_enable_extension(ctx, "GL_ARB_texture_compression"); + _mesa_enable_extension(ctx, "GL_3DFX_texture_compression_FXT1"); + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + _mesa_enable_extension(ctx, "GL_S3_s3tc"); + _mesa_enable_extension(ctx, "GL_NV_blend_square"); + } else { + /* [dBorca] + * We should enable generic texture compression functions, + * but some poorly written apps automatically assume S3TC. + * Binding NCC to GL_COMPRESSED_RGB[A] is an unnecessary hassle, + * since it's slow and ugly (better with palette textures, then). + * Moreover, NCC is not an OpenGL standard, so we can't use + * precompressed textures. Last, but not least, NCC runs amok + * when multitexturing on a Voodoo3 and up (see POINTCAST vs UMA). + * Note: this is also a problem with palette textures, but + * faking multitex by multipass is evil... + * Implementing NCC requires three stages: + * fxDDChooseTextureFormat: + * bind GL_COMPRESSED_RGB[A] to _mesa_texformat_argb8888, + * so we can quantize properly, at a later time + * fxDDTexImage: + * if GL_COMPRESSED_RGB + * use _mesa_texformat_l8 to get 1bpt and set GR_TEXFMT_YIQ_422 + * if GL_COMPRESSED_RGBA + * use _mesa_texformat_al88 to get 2bpt and set GR_TEXFMT_AYIQ_8422 + * txMipQuantize(...); + * if (level == 0) { + * txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal); + * } + * fxSetupSingleTMU_NoLock/fxSetupDoubleTMU_NoLock: + * grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette)); + */ + /*_mesa_enable_extension(ctx, "GL_ARB_texture_compression");*/ + _mesa_enable_extension(ctx, "GL_SGIS_generate_mipmap"); + } + + if (fxMesa->HaveCmbExt) { + _mesa_enable_extension(ctx, "GL_ARB_texture_env_combine"); + _mesa_enable_extension(ctx, "GL_EXT_texture_env_combine"); + } + + if (fxMesa->HavePixExt) { + _mesa_enable_extension(ctx, "GL_EXT_blend_subtract"); + _mesa_enable_extension(ctx, "GL_EXT_blend_equation_separate"); + } + + if (fxMesa->HaveMirExt) { + _mesa_enable_extension(ctx, "GL_ARB_texture_mirrored_repeat"); + } + + if (fxMesa->type >= GR_SSTTYPE_Voodoo2) { + _mesa_enable_extension(ctx, "GL_EXT_fog_coord"); + } + + /* core-level extensions */ + _mesa_enable_extension(ctx, "GL_EXT_multi_draw_arrays"); + _mesa_enable_extension(ctx, "GL_IBM_multimode_draw_arrays"); + _mesa_enable_extension(ctx, "GL_ARB_vertex_buffer_object"); + /* dangerous */ + if (getenv("MESA_FX_ALLOW_VP")) { + _mesa_enable_extension(ctx, "GL_ARB_vertex_program"); + _mesa_enable_extension(ctx, "GL_NV_vertex_program"); + _mesa_enable_extension(ctx, "GL_NV_vertex_program1_1"); + _mesa_enable_extension(ctx, "GL_MESA_program_debug"); + } +#if 0 + /* this requires _tnl_vertex_cull_stage in the pipeline */ + _mesa_enable_extension(ctx, "EXT_cull_vertex"); +#endif +} + + +/************************************************************************/ +/************************************************************************/ +/************************************************************************/ + +/* Check if the hardware supports the current context + * + * Performs similar work to fxDDChooseRenderState() - should be merged. + */ +GLuint +fx_check_IsInHardware(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (ctx->RenderMode != GL_RENDER) { + return FX_FALLBACK_RENDER_MODE; + } + + if (ctx->Stencil.Enabled && !fxMesa->haveHwStencil) { + return FX_FALLBACK_STENCIL; + } + + if (ctx->DrawBuffer->_ColorDrawBufferMask[0] != BUFFER_BIT_FRONT_LEFT && + ctx->DrawBuffer->_ColorDrawBufferMask[0] != BUFFER_BIT_BACK_LEFT) { + return FX_FALLBACK_DRAW_BUFFER; + } + + if (ctx->Color.BlendEnabled) { + if (ctx->Color.BlendEquationRGB != GL_FUNC_ADD) { + if (!fxMesa->HavePixExt || + ((ctx->Color.BlendEquationRGB != GL_FUNC_SUBTRACT) && + (ctx->Color.BlendEquationRGB != GL_FUNC_REVERSE_SUBTRACT))) { + return FX_FALLBACK_BLEND; + } + } + + if (ctx->Color.BlendEquationA != GL_FUNC_ADD) { + if (!fxMesa->HavePixExt || + ((ctx->Color.BlendEquationA != GL_FUNC_SUBTRACT) && + (ctx->Color.BlendEquationA != GL_FUNC_REVERSE_SUBTRACT))) { + return FX_FALLBACK_BLEND; + } + } + +#if 0 + /* [dBorca] + * We fail the spec here, unless certain blending modes: + * RGB: (GL_ONE + GL_*) or (GL_ZERO + GL_*) or ... + */ + if (NEED_SECONDARY_COLOR(ctx)) { + if ((ctx->Color.BlendEquationRGB != GL_FUNC_ADD) && + (ctx->Color.BlendSrcRGB != GL_ONE)) { + /* Can't use multipass to blend ColorSum stage */ + return FX_FALLBACK_SPECULAR; + } + } +#endif + } + + /* [dBorca] + * We could avoid this for certain `sfactor/dfactor' + * I do not think that is even worthwhile to check + * because if someone is using blending they use more + * interesting settings and also it would add more + * state tracking to a lot of the code. + */ + if (ctx->Color.ColorLogicOpEnabled && (ctx->Color.LogicOp != GL_COPY)) { + return FX_FALLBACK_LOGICOP; + } + + if ((fxMesa->colDepth != 32) && + ((ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP]) || + (ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]))) { + return FX_FALLBACK_COLORMASK; + } + + /* Unsupported texture/multitexture cases */ + + /* we can only do 1D/2D textures */ + if (ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT)) + return FX_FALLBACK_TEXTURE_MAP; + + if (fxMesa->haveTwoTMUs) { + if (ctx->Texture.Unit[1]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT)) + return FX_FALLBACK_TEXTURE_MAP; + + if (ctx->Texture.Unit[0]._ReallyEnabled) { + if (fxMesa->type < GR_SSTTYPE_Voodoo2) + if (ctx->Texture.Unit[0].EnvMode == GL_BLEND && + (ctx->Texture.Unit[1]._ReallyEnabled || + ctx->Texture.Unit[0].EnvColor[0] != 0 || + ctx->Texture.Unit[0].EnvColor[1] != 0 || + ctx->Texture.Unit[0].EnvColor[2] != 0 || + ctx->Texture.Unit[0].EnvColor[3] != 1)) { + return FX_FALLBACK_TEXTURE_ENV; + } + if (ctx->Texture.Unit[0]._Current->Image[0][0]->Border > 0) + return FX_FALLBACK_TEXTURE_BORDER; + } + + if (ctx->Texture.Unit[1]._ReallyEnabled) { + if (fxMesa->type < GR_SSTTYPE_Voodoo2) + if (ctx->Texture.Unit[1].EnvMode == GL_BLEND) + return FX_FALLBACK_TEXTURE_ENV; + if (ctx->Texture.Unit[1]._Current->Image[0][0]->Border > 0) + return FX_FALLBACK_TEXTURE_BORDER; + } + + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fprintf(stderr, "fx_check_IsInHardware: envmode is %s/%s\n", + _mesa_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode), + _mesa_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode)); + + /* KW: This was wrong (I think) and I changed it... which doesn't mean + * it is now correct... + * BP: The old condition just seemed to test if both texture units + * were enabled. That's easy! + */ + if (ctx->Texture._EnabledUnits == 0x3) { +#if 0 + /* Can't use multipass to blend a multitextured triangle - fall + * back to software. + */ + if (!fxMesa->haveTwoTMUs && ctx->Color.BlendEnabled) { + return FX_FALLBACK_TEXTURE_MULTI; + } +#endif + + if (!fxMesa->HaveCmbExt && + (ctx->Texture.Unit[0].EnvMode != ctx->Texture.Unit[1].EnvMode) && + (ctx->Texture.Unit[0].EnvMode != GL_MODULATE) && + (ctx->Texture.Unit[0].EnvMode != GL_REPLACE)) { /* q2, seems ok... */ + if (TDFX_DEBUG & VERBOSE_DRIVER) + fprintf(stderr, "fx_check_IsInHardware: unsupported multitex env mode\n"); + return FX_FALLBACK_TEXTURE_MULTI; + } + } + } + else { + /* we have just one texture unit */ + if (ctx->Texture._EnabledUnits > 0x1) { + return FX_FALLBACK_TEXTURE_MULTI; + } + + if (fxMesa->type < GR_SSTTYPE_Voodoo2) + if (ctx->Texture.Unit[0]._ReallyEnabled && + (ctx->Texture.Unit[0].EnvMode == GL_BLEND)) { + return FX_FALLBACK_TEXTURE_ENV; + } + } + + return 0; +} + + + +static void +fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state) +{ + /* TNLcontext *tnl = TNL_CONTEXT(ctx); */ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDUpdateDDPointers(%08x)\n", new_state); + } + + _swrast_InvalidateState(ctx, new_state); + _ac_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + _swsetup_InvalidateState(ctx, new_state); + + fxMesa->new_gl_state |= new_state; +} + + + + +void +fxSetupDDPointers(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + /* TNLcontext *tnl = TNL_CONTEXT(ctx); */ + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupDDPointers()\n"); + } + + ctx->Driver.UpdateState = fxDDUpdateDDPointers; + ctx->Driver.GetString = fxDDGetString; + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = fxDDClearColor; + ctx->Driver.Clear = fxDDClear; + ctx->Driver.DrawBuffer = fxDDSetDrawBuffer; + ctx->Driver.GetBufferSize = fxDDGetBufferSize; + ctx->Driver.Viewport = fxDDViewport; + switch (fxMesa->colDepth) { + case 15: + ctx->Driver.DrawPixels = fxDDDrawPixels555; + ctx->Driver.ReadPixels = fxDDReadPixels555; + ctx->Driver.Bitmap = fxDDDrawBitmap2; + break; + case 16: + ctx->Driver.DrawPixels = !fxMesa->bgrOrder ? fxDDDrawPixels565 : fxDDDrawPixels565_rev; + ctx->Driver.ReadPixels = fxDDReadPixels565; + ctx->Driver.Bitmap = fxDDDrawBitmap2; + break; + case 32: + ctx->Driver.DrawPixels = fxDDDrawPixels8888; + ctx->Driver.ReadPixels = fxDDReadPixels8888; + ctx->Driver.Bitmap = fxDDDrawBitmap4; + break; + } + ctx->Driver.Finish = fxDDFinish; + ctx->Driver.Flush = NULL; + ctx->Driver.ChooseTextureFormat = fxDDChooseTextureFormat; + ctx->Driver.TexImage1D = fxDDTexImage1D; + ctx->Driver.TexImage2D = fxDDTexImage2D; + ctx->Driver.TexSubImage1D = fxDDTexSubImage1D; + ctx->Driver.TexSubImage2D = fxDDTexSubImage2D; + ctx->Driver.CompressedTexImage2D = fxDDCompressedTexImage2D; + ctx->Driver.CompressedTexSubImage2D = fxDDCompressedTexSubImage2D; + ctx->Driver.TestProxyTexImage = fxDDTestProxyTexImage; + ctx->Driver.TexEnv = fxDDTexEnv; + ctx->Driver.TexParameter = fxDDTexParam; + ctx->Driver.BindTexture = fxDDTexBind; + ctx->Driver.DeleteTexture = fxDDTexDel; + ctx->Driver.IsTextureResident = fxDDIsTextureResident; + ctx->Driver.UpdateTexturePalette = fxDDTexPalette; + ctx->Driver.AlphaFunc = fxDDAlphaFunc; + ctx->Driver.BlendFuncSeparate = fxDDBlendFuncSeparate; + ctx->Driver.BlendEquationSeparate = fxDDBlendEquationSeparate; + ctx->Driver.DepthFunc = fxDDDepthFunc; + ctx->Driver.DepthMask = fxDDDepthMask; + ctx->Driver.ColorMask = fxDDColorMask; + ctx->Driver.Fogfv = fxDDFogfv; + ctx->Driver.Scissor = fxDDScissor; + ctx->Driver.FrontFace = fxDDFrontFace; + ctx->Driver.CullFace = fxDDCullFace; + ctx->Driver.ShadeModel = fxDDShadeModel; + ctx->Driver.Enable = fxDDEnable; + if (fxMesa->haveHwStencil) { + ctx->Driver.StencilFunc = fxDDStencilFunc; + ctx->Driver.StencilMask = fxDDStencilMask; + ctx->Driver.StencilOp = fxDDStencilOp; + } + + fxSetupDDSpanPointers(ctx); + fxDDUpdateDDPointers(ctx, ~0); +} + + +#else + + +/* + * Need this to provide at least one external definition. + */ + +extern int gl_fx_dummy_function_dd(void); +int +gl_fx_dummy_function_dd(void) +{ + return 0; +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddspan.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddspan.c new file mode 100644 index 000000000..79abbefc2 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddspan.c @@ -0,0 +1,663 @@ +/* + * 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 + */ + + +/* fxdd.c - 3Dfx VooDoo Mesa span and pixel functions */ + + +#ifdef HAVE_CONFIG_H +#include "conf.h" +#endif + +#if defined(FX) + +#include "fxdrv.h" +#include "fxglidew.h" +#include "swrast/swrast.h" + + +/************************************************************************/ +/***** Span functions *****/ +/************************************************************************/ + +#define DBG 0 + + +#define LOCAL_VARS \ + GLuint pitch = info.strideInBytes; \ + GLuint height = fxMesa->height; \ + char *buf = (char *)((char *)info.lfbPtr + 0 /* x, y offset */); \ + GLuint p; \ + (void) buf; (void) p; + +#define CLIPPIXEL( _x, _y ) ( _x >= minx && _x < maxx && \ + _y >= miny && _y < maxy ) + +#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \ + if ( _y < miny || _y >= maxy ) { \ + _n1 = 0, _x1 = x; \ + } else { \ + _n1 = _n; \ + _x1 = _x; \ + if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx;\ + if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \ + } + +#define Y_FLIP(_y) (height - _y - 1) + +#define HW_WRITE_LOCK() \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GrLfbInfo_t info; \ + info.size = sizeof(GrLfbInfo_t); \ + if ( grLfbLock( GR_LFB_WRITE_ONLY, \ + fxMesa->currentFB, LFB_MODE, \ + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) { + +#define HW_WRITE_UNLOCK() \ + grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->currentFB ); \ + } + +#define HW_READ_LOCK() \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GrLfbInfo_t info; \ + info.size = sizeof(GrLfbInfo_t); \ + if ( grLfbLock( GR_LFB_READ_ONLY, fxMesa->currentFB, \ + LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) { + +#define HW_READ_UNLOCK() \ + grLfbUnlock( GR_LFB_READ_ONLY, fxMesa->currentFB ); \ + } + +#define HW_WRITE_CLIPLOOP() \ + do { \ + /* remember, we need to flip the scissor, too */ \ + /* is it better to do it inside fxDDScissor? */ \ + const int minx = fxMesa->clipMinX; \ + const int maxy = Y_FLIP(fxMesa->clipMinY); \ + const int maxx = fxMesa->clipMaxX; \ + const int miny = Y_FLIP(fxMesa->clipMaxY); + +#define HW_READ_CLIPLOOP() \ + do { \ + /* remember, we need to flip the scissor, too */ \ + /* is it better to do it inside fxDDScissor? */ \ + const int minx = fxMesa->clipMinX; \ + const int maxy = Y_FLIP(fxMesa->clipMinY); \ + const int maxx = fxMesa->clipMaxX; \ + const int miny = Y_FLIP(fxMesa->clipMaxY); + +#define HW_ENDCLIPLOOP() \ + } while (0) + + +/* 16 bit, ARGB1555 color spanline and pixel functions */ + +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_1555 + +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 2 + +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = TDFXPACKCOLOR1555( color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = \ + TDFXPACKCOLOR1555( r, g, b, a ) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLushort p = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch); \ + rgba[0] = FX_rgb_scale_5[(p >> 10) & 0x1F]; \ + rgba[1] = FX_rgb_scale_5[(p >> 5) & 0x1F]; \ + rgba[2] = FX_rgb_scale_5[ p & 0x1F]; \ + rgba[3] = (p & 0x8000) ? 255 : 0; \ + } while (0) + +#define TAG(x) tdfx##x##_ARGB1555 +#include "../dri/common/spantmp.h" + + +/* 16 bit, RGB565 color spanline and pixel functions */ +/* [dBorca] Hack alert: + * This is wrong. The alpha value is lost, even when we provide + * HW alpha (565 w/o depth buffering). To really update alpha buffer, + * we would need to do the 565 writings via 8888 colorformat and rely + * on the Voodoo to perform color scaling. In which case our 565 span + * would look nicer! But this violates FSAA rules... + */ + +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_565 + +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 2 + +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = TDFXPACKCOLOR565( color[RCOMP], color[GCOMP], color[BCOMP] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = \ + TDFXPACKCOLOR565( r, g, b ) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLushort p = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch); \ + rgba[0] = FX_rgb_scale_5[(p >> 11) & 0x1F]; \ + rgba[1] = FX_rgb_scale_6[(p >> 5) & 0x3F]; \ + rgba[2] = FX_rgb_scale_5[ p & 0x1F]; \ + rgba[3] = 0xff; \ + } while (0) + +#define TAG(x) tdfx##x##_RGB565 +#include "../dri/common/spantmp.h" + + +/* 32 bit, ARGB8888 color spanline and pixel functions */ + +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_8888 + +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 4 + +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = TDFXPACKCOLOR8888( color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = \ + TDFXPACKCOLOR8888( r, g, b, a ) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLuint p = *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = (p >> 24) & 0xff; \ + } while (0) + +#define TAG(x) tdfx##x##_ARGB8888 +#include "../dri/common/spantmp.h" + + +/************************************************************************/ +/***** Depth functions *****/ +/************************************************************************/ + +#define DBG 0 + +#undef HW_WRITE_LOCK +#undef HW_WRITE_UNLOCK +#undef HW_READ_LOCK +#undef HW_READ_UNLOCK + +#define HW_CLIPLOOP HW_WRITE_CLIPLOOP + +#define LOCAL_DEPTH_VARS \ + GLuint pitch = info.strideInBytes; \ + GLuint height = fxMesa->height; \ + char *buf = (char *)((char *)info.lfbPtr + 0 /* x, y offset */); \ + (void) buf; + +#define HW_WRITE_LOCK() \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GrLfbInfo_t info; \ + info.size = sizeof(GrLfbInfo_t); \ + if ( grLfbLock( GR_LFB_WRITE_ONLY, \ + GR_BUFFER_AUXBUFFER, LFB_MODE, \ + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) { + +#define HW_WRITE_UNLOCK() \ + grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_AUXBUFFER); \ + } + +#define HW_READ_LOCK() \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GrLfbInfo_t info; \ + info.size = sizeof(GrLfbInfo_t); \ + if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER, \ + LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) { + +#define HW_READ_UNLOCK() \ + grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER); \ + } + + +/* 16 bit, depth spanline and pixel functions */ + +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_ZA16 + +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 2 + +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) + +#define TAG(x) tdfx##x##_Z16 +#include "../dri/common/depthtmp.h" + + +/* 24 bit, depth spanline and pixel functions (for use w/ stencil) */ +/* [dBorca] Hack alert: + * This is evil. The incoming Mesa's 24bit depth value + * is shifted left 8 bits, to obtain a full 32bit value, + * which will be thrown into the framebuffer. We rely on + * the fact that Voodoo hardware transforms a 32bit value + * into 24bit value automatically and, MOST IMPORTANT, won't + * alter the upper 8bits of the value already existing in the + * framebuffer (where stencil resides). + */ + +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_Z32 + +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 4 + +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d << 8 + +#define READ_DEPTH( d, _x, _y ) \ + d = (*(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch)) & 0xffffff + +#define TAG(x) tdfx##x##_Z24 +#include "../dri/common/depthtmp.h" + + +/* 32 bit, depth spanline and pixel functions (for use w/o stencil) */ +/* [dBorca] Hack alert: + * This is more evil. We make Mesa run in 32bit depth, but + * tha Voodoo HW can only handle 24bit depth. Well, exploiting + * the pixel pipeline, we can achieve 24:8 format for greater + * precision... + * If anyone tells me how to really store 32bit values into the + * depth buffer, I'll write the *_Z32 routines. Howver, bear in + * mind that means running without stencil! + */ + +/************************************************************************/ +/***** Span functions (optimized) *****/ +/************************************************************************/ + +/* + * Read a span of 15-bit RGB pixels. Note, we don't worry about cliprects + * since OpenGL says obscured pixels have undefined values. + */ +static void fxReadRGBASpan_ARGB1555 (const GLcontext * ctx, + struct gl_renderbuffer *rb, + GLuint n, + GLint x, GLint y, + GLubyte rgba[][4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + info.size = sizeof(GrLfbInfo_t); + if (grLfbLock(GR_LFB_READ_ONLY, fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = 0; + const GLint winY = fxMesa->height - 1; + const GLushort *data16 = (const GLushort *)((const GLubyte *)info.lfbPtr + + (winY - y) * info.strideInBytes + + (winX + x) * 2); + const GLuint *data32 = (const GLuint *) data16; + GLuint i, j; + GLuint extraPixel = (n & 1); + n -= extraPixel; + + for (i = j = 0; i < n; i += 2, j++) { + GLuint pixel = data32[j]; + rgba[i][0] = FX_rgb_scale_5[(pixel >> 10) & 0x1F]; + rgba[i][1] = FX_rgb_scale_5[(pixel >> 5) & 0x1F]; + rgba[i][2] = FX_rgb_scale_5[ pixel & 0x1F]; + rgba[i][3] = (pixel & 0x8000) ? 255 : 0; + rgba[i+1][0] = FX_rgb_scale_5[(pixel >> 26) & 0x1F]; + rgba[i+1][1] = FX_rgb_scale_5[(pixel >> 21) & 0x1F]; + rgba[i+1][2] = FX_rgb_scale_5[(pixel >> 16) & 0x1F]; + rgba[i+1][3] = (pixel & 0x80000000) ? 255 : 0; + } + if (extraPixel) { + GLushort pixel = data16[n]; + rgba[n][0] = FX_rgb_scale_5[(pixel >> 10) & 0x1F]; + rgba[n][1] = FX_rgb_scale_5[(pixel >> 5) & 0x1F]; + rgba[n][2] = FX_rgb_scale_5[ pixel & 0x1F]; + rgba[n][3] = (pixel & 0x8000) ? 255 : 0; + } + + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } +} + +/* + * Read a span of 16-bit RGB pixels. Note, we don't worry about cliprects + * since OpenGL says obscured pixels have undefined values. + */ +static void fxReadRGBASpan_RGB565 (const GLcontext * ctx, + struct gl_renderbuffer *rb, + GLuint n, + GLint x, GLint y, + GLubyte rgba[][4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + info.size = sizeof(GrLfbInfo_t); + if (grLfbLock(GR_LFB_READ_ONLY, fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { + const GLint winX = 0; + const GLint winY = fxMesa->height - 1; + const GLushort *data16 = (const GLushort *)((const GLubyte *)info.lfbPtr + + (winY - y) * info.strideInBytes + + (winX + x) * 2); + const GLuint *data32 = (const GLuint *) data16; + GLuint i, j; + GLuint extraPixel = (n & 1); + n -= extraPixel; + + for (i = j = 0; i < n; i += 2, j++) { + GLuint pixel = data32[j]; + rgba[i][0] = FX_rgb_scale_5[(pixel >> 11) & 0x1F]; + rgba[i][1] = FX_rgb_scale_6[(pixel >> 5) & 0x3F]; + rgba[i][2] = FX_rgb_scale_5[ pixel & 0x1F]; + rgba[i][3] = 255; + rgba[i+1][0] = FX_rgb_scale_5[(pixel >> 27) & 0x1F]; + rgba[i+1][1] = FX_rgb_scale_6[(pixel >> 21) & 0x3F]; + rgba[i+1][2] = FX_rgb_scale_5[(pixel >> 16) & 0x1F]; + rgba[i+1][3] = 255; + } + if (extraPixel) { + GLushort pixel = data16[n]; + rgba[n][0] = FX_rgb_scale_5[(pixel >> 11) & 0x1F]; + rgba[n][1] = FX_rgb_scale_6[(pixel >> 5) & 0x3F]; + rgba[n][2] = FX_rgb_scale_5[ pixel & 0x1F]; + rgba[n][3] = 255; + } + + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } +} + +/* + * Read a span of 32-bit RGB pixels. Note, we don't worry about cliprects + * since OpenGL says obscured pixels have undefined values. + */ +static void fxReadRGBASpan_ARGB8888 (const GLcontext * ctx, + struct gl_renderbuffer *rb, + GLuint n, + GLint x, GLint y, + GLubyte rgba[][4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint i; + grLfbReadRegion(fxMesa->currentFB, x, fxMesa->height - 1 - y, n, 1, n * 4, rgba); + for (i = 0; i < n; i++) { + GLubyte c = rgba[i][0]; + rgba[i][0] = rgba[i][2]; + rgba[i][2] = c; + } +} + + +/************************************************************************/ +/***** Depth functions (optimized) *****/ +/************************************************************************/ + +static void +fxReadDepthSpan_Z16(GLcontext * ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLdepth depth[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLint bottom = fxMesa->height - 1; + GLushort depth16[MAX_WIDTH]; + GLuint i; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxReadDepthSpan_Z16(...)\n"); + } + + grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth16); + for (i = 0; i < n; i++) { + depth[i] = depth16[i]; + } +} + + +static void +fxReadDepthSpan_Z24(GLcontext * ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLdepth depth[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLint bottom = fxMesa->height - 1; + GLuint i; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxReadDepthSpan_Z24(...)\n"); + } + + grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth); + for (i = 0; i < n; i++) { + depth[i] &= 0xffffff; + } +} + + +/************************************************************************/ +/***** Stencil functions (optimized) *****/ +/************************************************************************/ + +static void +fxWriteStencilSpan (GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLstencil stencil[], const GLubyte mask[]) +{ + /* + * XXX todo + */ +} + +static void +fxReadStencilSpan(GLcontext * ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLstencil stencil[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLint bottom = fxMesa->height - 1; + GLuint zs32[MAX_WIDTH]; + GLuint i; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxReadStencilSpan(...)\n"); + } + + grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, zs32); + for (i = 0; i < n; i++) { + stencil[i] = zs32[i] >> 24; + } +} + +static void +fxWriteStencilPixels (GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, + const GLint x[], const GLint y[], + const GLstencil stencil[], + const GLubyte mask[]) +{ + /* + * XXX todo + */ +} + +static void +fxReadStencilPixels (GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, + const GLint x[], const GLint y[], + GLstencil stencil[]) +{ + /* + * XXX todo + */ +} + + + +/* + * This function is called to specify which buffer to read and write + * for software rasterization (swrast) fallbacks. This doesn't necessarily + * correspond to glDrawBuffer() or glReadBuffer() calls. + */ +static void +fxDDSetBuffer(GLcontext * ctx, GLframebuffer * buffer, GLuint bufferBit) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) buffer; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDSetBuffer(%x)\n", (int)bufferBit); + } + + if (bufferBit == BUFFER_BIT_FRONT_LEFT) { + fxMesa->currentFB = GR_BUFFER_FRONTBUFFER; + grRenderBuffer(fxMesa->currentFB); + } + else if (bufferBit == BUFFER_BIT_BACK_LEFT) { + fxMesa->currentFB = GR_BUFFER_BACKBUFFER; + grRenderBuffer(fxMesa->currentFB); + } +} + + +/************************************************************************/ + + + +void +fxSetupDDSpanPointers(GLcontext * ctx) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + swdd->SetBuffer = fxDDSetBuffer; + + switch (fxMesa->colDepth) { + case 15: + swdd->WriteRGBASpan = tdfxWriteRGBASpan_ARGB1555; + swdd->WriteRGBSpan = tdfxWriteRGBSpan_ARGB1555; + swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB1555; + swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB1555; + swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB1555; + swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_ARGB1555; + swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB1555; + + swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z16; + swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z16; + swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z16; + swdd->ReadDepthPixels = tdfxReadDepthPixels_Z16; + break; + case 16: + swdd->WriteRGBASpan = tdfxWriteRGBASpan_RGB565; + swdd->WriteRGBSpan = tdfxWriteRGBSpan_RGB565; + swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_RGB565; + swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_RGB565; + swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_RGB565; + swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_RGB565; + swdd->ReadRGBAPixels = tdfxReadRGBAPixels_RGB565; + + swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z16; + swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z16; + swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z16; + swdd->ReadDepthPixels = tdfxReadDepthPixels_Z16; + break; + case 32: + swdd->WriteRGBASpan = tdfxWriteRGBASpan_ARGB8888; + swdd->WriteRGBSpan = tdfxWriteRGBSpan_ARGB8888; + swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB8888; + swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB8888; + swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB8888; + swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_ARGB8888; + swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB8888; + + swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z24; + swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z24; + swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z24; + swdd->ReadDepthPixels = tdfxReadDepthPixels_Z24; + break; + } + + if (fxMesa->haveHwStencil) { + swdd->WriteStencilSpan = fxWriteStencilSpan; + swdd->ReadStencilSpan = fxReadStencilSpan; + swdd->WriteStencilPixels = fxWriteStencilPixels; + swdd->ReadStencilPixels = fxReadStencilPixels; + } +#if 0 + swdd->WriteCI8Span = NULL; + swdd->WriteCI32Span = NULL; + swdd->WriteMonoCISpan = NULL; + swdd->WriteCI32Pixels = NULL; + swdd->WriteMonoCIPixels = NULL; + swdd->ReadCI32Span = NULL; + swdd->ReadCI32Pixels = NULL; + + swdd->SpanRenderStart = tdfxSpanRenderStart; /* BEGIN_BOARD_LOCK */ + swdd->SpanRenderFinish = tdfxSpanRenderFinish; /* END_BOARD_LOCK */ +#endif +} + + +#else + + +/* + * Need this to provide at least one external definition. + */ + +extern int gl_fx_dummy_function_span(void); +int +gl_fx_dummy_function_span(void) +{ + return 0; +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddtex.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddtex.c new file mode 100644 index 000000000..f3f12c4cc --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddtex.c @@ -0,0 +1,1849 @@ +/* + * 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 + */ + + +#ifdef HAVE_CONFIG_H +#include "conf.h" +#endif + +#if defined(FX) + +#include "fxdrv.h" +#include "enums.h" +#include "image.h" +#include "teximage.h" +#include "texformat.h" +#include "texcompress.h" +#include "texobj.h" +#include "texstore.h" + + +/* no borders! can't halve 1x1! (stride > width * comp) not allowed */ +static void +_mesa_halve2x2_teximage2d ( GLcontext *ctx, + struct gl_texture_image *texImage, + GLuint bytesPerPixel, + GLint srcWidth, GLint srcHeight, + const GLvoid *srcImage, GLvoid *dstImage ) +{ + GLint i, j, k; + GLint dstWidth = srcWidth / 2; + GLint dstHeight = srcHeight / 2; + GLint srcRowStride = srcWidth * bytesPerPixel; + GLubyte *src = (GLubyte *)srcImage; + GLubyte *dst = dstImage; + + GLuint bpt = 0; + GLubyte *_s = NULL; + GLubyte *_d = NULL; + GLenum _t = 0; + + if (texImage->TexFormat->MesaFormat == MESA_FORMAT_RGB565) { + _t = GL_UNSIGNED_SHORT_5_6_5_REV; + bpt = bytesPerPixel; + } else if (texImage->TexFormat->MesaFormat == MESA_FORMAT_ARGB4444) { + _t = GL_UNSIGNED_SHORT_4_4_4_4_REV; + bpt = bytesPerPixel; + } else if (texImage->TexFormat->MesaFormat == MESA_FORMAT_ARGB1555) { + _t = GL_UNSIGNED_SHORT_1_5_5_5_REV; + bpt = bytesPerPixel; + } + if (bpt) { + bytesPerPixel = 4; + srcRowStride = srcWidth * bytesPerPixel; + if (dstWidth == 0) { + dstWidth = 1; + } + if (dstHeight == 0) { + dstHeight = 1; + } + _s = src = MALLOC(srcRowStride * srcHeight); + _d = dst = MALLOC(dstWidth * bytesPerPixel * dstHeight); + _mesa_texstore_rgba8888(ctx, 2, GL_RGBA, + &_mesa_texformat_rgba8888_rev, src, + 0, 0, 0, /* dstX/Y/Zoffset */ + srcRowStride, /* dstRowStride */ + 0, /* dstImageStride */ + srcWidth, srcHeight, 1, + texImage->Format, _t, srcImage, &ctx->DefaultPacking); + } + + if (srcHeight == 1) { + for (i = 0; i < dstWidth; i++) { + for (k = 0; k < bytesPerPixel; k++) { + dst[0] = (src[0] + src[bytesPerPixel] + 1) / 2; + src++; + dst++; + } + src += bytesPerPixel; + } + } else if (srcWidth == 1) { + for (j = 0; j < dstHeight; j++) { + for (k = 0; k < bytesPerPixel; k++) { + dst[0] = (src[0] + src[srcRowStride] + 1) / 2; + src++; + dst++; + } + src += srcRowStride; + } + } else { + for (j = 0; j < dstHeight; j++) { + for (i = 0; i < dstWidth; i++) { + for (k = 0; k < bytesPerPixel; k++) { + dst[0] = (src[0] + + src[bytesPerPixel] + + src[srcRowStride] + + src[srcRowStride + bytesPerPixel] + 2) / 4; + src++; + dst++; + } + src += bytesPerPixel; + } + src += srcRowStride; + } + } + + if (bpt) { + src = _s; + dst = _d; + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + texImage->TexFormat, dstImage, + 0, 0, 0, /* dstX/Y/Zoffset */ + dstWidth * bpt, + 0, /* dstImageStride */ + dstWidth, dstHeight, 1, + GL_BGRA, CHAN_TYPE, dst, &ctx->DefaultPacking); + FREE(dst); + FREE(src); + } +} + + +void +fxPrintTextureData(tfxTexInfo * ti) +{ + fprintf(stderr, "Texture Data:\n"); + if (ti->tObj) { + fprintf(stderr, "\tName: %d\n", ti->tObj->Name); + fprintf(stderr, "\tBaseLevel: %d\n", ti->tObj->BaseLevel); + fprintf(stderr, "\tSize: %d x %d\n", + ti->tObj->Image[0][ti->tObj->BaseLevel]->Width, + ti->tObj->Image[0][ti->tObj->BaseLevel]->Height); + } + else + fprintf(stderr, "\tName: UNNAMED\n"); + fprintf(stderr, "\tLast used: %d\n", ti->lastTimeUsed); + fprintf(stderr, "\tTMU: %ld\n", ti->whichTMU); + fprintf(stderr, "\t%s\n", (ti->isInTM) ? "In TMU" : "Not in TMU"); + if (ti->tm[0]) + fprintf(stderr, "\tMem0: %x-%x\n", (unsigned) ti->tm[0]->startAddr, + (unsigned) ti->tm[0]->endAddr); + if (ti->tm[1]) + fprintf(stderr, "\tMem1: %x-%x\n", (unsigned) ti->tm[1]->startAddr, + (unsigned) ti->tm[1]->endAddr); + fprintf(stderr, "\tMipmaps: %d-%d\n", ti->minLevel, ti->maxLevel); + fprintf(stderr, "\tFilters: min %d max %d\n", + (int) ti->minFilt, (int) ti->maxFilt); + fprintf(stderr, "\tClamps: s %d t %d\n", (int) ti->sClamp, + (int) ti->tClamp); + fprintf(stderr, "\tScales: s %f t %f\n", ti->sScale, ti->tScale); + fprintf(stderr, "\t%s\n", + (ti->fixedPalette) ? "Fixed palette" : "Non fixed palette"); + fprintf(stderr, "\t%s\n", (ti->validated) ? "Validated" : "Not validated"); +} + + +/************************************************************************/ +/*************************** Texture Mapping ****************************/ +/************************************************************************/ + +static void +fxTexInvalidate(GLcontext * ctx, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti; + + ti = fxTMGetTexInfo(tObj); + if (ti->isInTM) + fxTMMoveOutTM(fxMesa, tObj); /* TO DO: SLOW but easy to write */ + + ti->validated = GL_FALSE; + fxMesa->new_state |= FX_NEW_TEXTURING; +} + +static tfxTexInfo * +fxAllocTexObjData(fxMesaContext fxMesa) +{ + tfxTexInfo *ti; + + if (!(ti = CALLOC(sizeof(tfxTexInfo)))) { + fprintf(stderr, "fxAllocTexObjData: ERROR: out of memory !\n"); + fxCloseHardware(); + exit(-1); + } + + ti->validated = GL_FALSE; + ti->isInTM = GL_FALSE; + + ti->whichTMU = FX_TMU_NONE; + + ti->tm[FX_TMU0] = NULL; + ti->tm[FX_TMU1] = NULL; + + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + ti->maxFilt = GR_TEXTUREFILTER_BILINEAR; + + ti->sClamp = GR_TEXTURECLAMP_WRAP; + ti->tClamp = GR_TEXTURECLAMP_WRAP; + + ti->mmMode = GR_MIPMAP_NEAREST; + ti->LODblend = FXFALSE; + + return ti; +} + +void +fxDDTexBind(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDTexBind(%d, %x)\n", tObj->Name, (GLuint)tObj->DriverData); + } + + if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D)) + return; + + if (!tObj->DriverData) { + tObj->DriverData = fxAllocTexObjData(fxMesa); + } + ti = fxTMGetTexInfo(tObj); + + fxMesa->texBindNumber++; + ti->lastTimeUsed = fxMesa->texBindNumber; + + fxMesa->new_state |= FX_NEW_TEXTURING; +} + +void +fxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname, + const GLfloat * param) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + if (param) + fprintf(stderr, "fxDDTexEnv(%x, %x)\n", pname, (GLint) (*param)); + else + fprintf(stderr, "fxDDTexEnv(%x)\n", pname); + } + + /* apply any lod biasing right now */ + if (pname == GL_TEXTURE_LOD_BIAS_EXT) { + GLfloat bias = *param; + CLAMP_SELF(bias, -ctx->Const.MaxTextureLodBias, + ctx->Const.MaxTextureLodBias - 0.25); + + grTexLodBiasValue(GR_TMU0, bias); + + if (fxMesa->haveTwoTMUs) { + grTexLodBiasValue(GR_TMU1, bias); + } + + } + + fxMesa->new_state |= FX_NEW_TEXTURING; +} + +void +fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj, + GLenum pname, const GLfloat * params) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLenum param = (GLenum) (GLint) params[0]; + tfxTexInfo *ti; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDTexParam(%d, %x, %s, %s)\n", + tObj->Name, (GLuint) tObj->DriverData, + _mesa_lookup_enum_by_nr(pname), + _mesa_lookup_enum_by_nr(param)); + } + + if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D)) + return; + + if (!tObj->DriverData) + tObj->DriverData = fxAllocTexObjData(fxMesa); + ti = fxTMGetTexInfo(tObj); + + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + switch (param) { + case GL_NEAREST: + ti->mmMode = GR_MIPMAP_DISABLE; + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + ti->LODblend = FXFALSE; + break; + case GL_LINEAR: + ti->mmMode = GR_MIPMAP_DISABLE; + ti->minFilt = GR_TEXTUREFILTER_BILINEAR; + ti->LODblend = FXFALSE; + break; + case GL_NEAREST_MIPMAP_LINEAR: + /* [dBorca] + * currently Napalm can't do single-pass trilinear, + * because the way its combiners are set. So we fall back + * to GL_NEAREST_MIPMAP_NEAREST. We'll let true trilinear + * enabled for V2, V3. + */ + if (!fxMesa->HaveCmbExt) { + if (fxMesa->haveTwoTMUs) { + ti->mmMode = GR_MIPMAP_NEAREST; + ti->LODblend = FXTRUE; + } else { + ti->mmMode = GR_MIPMAP_NEAREST_DITHER; + ti->LODblend = FXFALSE; + } + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + break; + } + case GL_NEAREST_MIPMAP_NEAREST: + ti->mmMode = GR_MIPMAP_NEAREST; + ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + ti->LODblend = FXFALSE; + break; + case GL_LINEAR_MIPMAP_LINEAR: + /* [dBorca] + * currently Napalm can't do single-pass trilinear, + * because the way its combiners are set. So we fall back + * to GL_LINEAR_MIPMAP_NEAREST. We'll let true trilinear + * enabled for V2, V3. + */ + if (!fxMesa->HaveCmbExt) { + if (fxMesa->haveTwoTMUs) { + ti->mmMode = GR_MIPMAP_NEAREST; + ti->LODblend = FXTRUE; + } else { + ti->mmMode = GR_MIPMAP_NEAREST_DITHER; + ti->LODblend = FXFALSE; + } + ti->minFilt = GR_TEXTUREFILTER_BILINEAR; + break; + } + case GL_LINEAR_MIPMAP_NEAREST: + ti->mmMode = GR_MIPMAP_NEAREST; + ti->minFilt = GR_TEXTUREFILTER_BILINEAR; + ti->LODblend = FXFALSE; + break; + default: + break; + } + fxTexInvalidate(ctx, tObj); + break; + + case GL_TEXTURE_MAG_FILTER: + switch (param) { + case GL_NEAREST: + ti->maxFilt = GR_TEXTUREFILTER_POINT_SAMPLED; + break; + case GL_LINEAR: + ti->maxFilt = GR_TEXTUREFILTER_BILINEAR; + break; + default: + break; + } + fxMesa->new_state |= FX_NEW_TEXTURING; + break; + + case GL_TEXTURE_WRAP_S: + switch (param) { + case GL_MIRRORED_REPEAT: + ti->sClamp = GR_TEXTURECLAMP_MIRROR_EXT; + break; + case GL_CLAMP_TO_BORDER: /* no-no, but don't REPEAT, either */ + case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */ + case GL_CLAMP: + ti->sClamp = GR_TEXTURECLAMP_CLAMP; + break; + case GL_REPEAT: + ti->sClamp = GR_TEXTURECLAMP_WRAP; + break; + default: + break; + } + fxMesa->new_state |= FX_NEW_TEXTURING; + break; + + case GL_TEXTURE_WRAP_T: + switch (param) { + case GL_MIRRORED_REPEAT: + ti->tClamp = GR_TEXTURECLAMP_MIRROR_EXT; + break; + case GL_CLAMP_TO_BORDER: /* no-no, but don't REPEAT, either */ + case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */ + case GL_CLAMP: + ti->tClamp = GR_TEXTURECLAMP_CLAMP; + break; + case GL_REPEAT: + ti->tClamp = GR_TEXTURECLAMP_WRAP; + break; + default: + break; + } + fxMesa->new_state |= FX_NEW_TEXTURING; + break; + + case GL_TEXTURE_BORDER_COLOR: + /* TO DO */ + break; + + case GL_TEXTURE_MIN_LOD: + /* TO DO */ + break; + case GL_TEXTURE_MAX_LOD: + /* TO DO */ + break; + case GL_TEXTURE_BASE_LEVEL: + fxTexInvalidate(ctx, tObj); + break; + case GL_TEXTURE_MAX_LEVEL: + fxTexInvalidate(ctx, tObj); + break; + + default: + break; + } +} + +void +fxDDTexDel(GLcontext * ctx, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDTexDel(%d, %p)\n", tObj->Name, (void *) ti); + } + + if (!ti) + return; + + fxTMFreeTexture(fxMesa, tObj); + + FREE(ti); + tObj->DriverData = NULL; + + /* Free mipmap images and the texture object itself */ + _mesa_delete_texture_object(ctx, tObj); +} + + +/** + * Allocate a new texture object. + * Called via ctx->Driver.NewTextureObject. + * Note: this function will be called during context creation to + * allocate the default texture objects. + */ +struct gl_texture_object * +fxDDNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) +{ + struct gl_texture_object *obj; + obj = _mesa_new_texture_object(ctx, name, target); + return obj; +} + + +/* + * Return true if texture is resident, false otherwise. + */ +GLboolean +fxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + return (ti && ti->isInTM); +} + + + +/* + * Convert a gl_color_table texture palette to Glide's format. + */ +static GrTexTable_t +convertPalette(const fxMesaContext fxMesa, FxU32 data[256], const struct gl_color_table *table) +{ + const GLubyte *tableUB = (const GLubyte *) table->Table; + GLint width = table->Size; + FxU32 r, g, b, a; + GLint i; + + ASSERT(table->Type == GL_UNSIGNED_BYTE); + + switch (table->Format) { + case GL_INTENSITY: + for (i = 0; i < width; i++) { + r = tableUB[i]; + g = tableUB[i]; + b = tableUB[i]; + a = tableUB[i]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; + case GL_LUMINANCE: + for (i = 0; i < width; i++) { + r = tableUB[i]; + g = tableUB[i]; + b = tableUB[i]; + a = 255; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + return GR_TEXTABLE_PALETTE; + case GL_ALPHA: + for (i = 0; i < width; i++) { + r = g = b = 255; + a = tableUB[i]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; + case GL_LUMINANCE_ALPHA: + for (i = 0; i < width; i++) { + r = g = b = tableUB[i * 2 + 0]; + a = tableUB[i * 2 + 1]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; + default: + case GL_RGB: + for (i = 0; i < width; i++) { + r = tableUB[i * 3 + 0]; + g = tableUB[i * 3 + 1]; + b = tableUB[i * 3 + 2]; + a = 255; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + return GR_TEXTABLE_PALETTE; + case GL_RGBA: + for (i = 0; i < width; i++) { + r = tableUB[i * 4 + 0]; + g = tableUB[i * 4 + 1]; + b = tableUB[i * 4 + 2]; + a = tableUB[i * 4 + 3]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; + } +} + + +void +fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (tObj) { + /* per-texture palette */ + tfxTexInfo *ti; + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDTexPalette(%d, %x)\n", + tObj->Name, (GLuint) tObj->DriverData); + } + /* This might be a proxy texture. */ + if (!tObj->Palette.Table) + return; + if (!tObj->DriverData) + tObj->DriverData = fxAllocTexObjData(fxMesa); + ti = fxTMGetTexInfo(tObj); + ti->paltype = convertPalette(fxMesa, ti->palette.data, &tObj->Palette); + fxTexInvalidate(ctx, tObj); + } + else { + /* global texture palette */ + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDTexPalette(global)\n"); + } + fxMesa->glbPalType = convertPalette(fxMesa, fxMesa->glbPalette.data, &ctx->Texture.Palette); + fxMesa->new_state |= FX_NEW_TEXTURING; + + grTexDownloadTable(fxMesa->glbPalType, &(fxMesa->glbPalette)); + } +} + + +void +fxDDTexUseGlbPalette(GLcontext * ctx, GLboolean state) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxDDTexUseGlbPalette(%d)\n", state); + } + + fxMesa->haveGlobalPaletteTexture = state; + fxMesa->new_state |= FX_NEW_TEXTURING; +} + + +static int +logbase2(int n) +{ + GLint i = 1; + GLint log2 = 0; + + if (n < 0) { + return -1; + } + + while (n > i) { + i *= 2; + log2++; + } + if (i != n) { + return -1; + } + else { + return log2; + } +} + + +/* fxTexGetInfo + * w, h - source texture width and height + * lodlevel - Glide lod level token for the larger texture dimension + * ar - Glide aspect ratio token + * sscale - S scale factor used during triangle setup + * tscale - T scale factor used during triangle setup + * wscale - OpenGL -> Glide image width scale factor + * hscale - OpenGL -> Glide image height scale factor + */ +int +fxTexGetInfo(int w, int h, GrLOD_t * lodlevel, GrAspectRatio_t * ar, + float *sscale, float *tscale, + int *wscale, int *hscale) +{ + int logw, logh, ws, hs; + GrLOD_t l; + GrAspectRatio_t aspectratio; + float s, t; + + logw = logbase2(w); + logh = logbase2(h); + + l = MAX2(logw, logh); + aspectratio = logw - logh; + ws = hs = 1; + s = t = 256.0f; + + /* hardware only allows a maximum aspect ratio of 8x1, so handle + * |aspectratio| > 3 by scaling the image and using an 8x1 aspect + * ratio + */ + switch (aspectratio) { + case 0: + break; + case 1: + t = 128.0f; + break; + case 2: + t = 64.0f; + break; + case 3: + t = 32.0f; + break; + case -1: + s = 128.0f; + break; + case -2: + s = 64.0f; + break; + case -3: + s = 32.0f; + break; + default: + if (aspectratio > 3) { + t = 32.0f; + hs = 1 << (aspectratio - 3); + aspectratio = GR_ASPECT_LOG2_8x1; + } else /*if (aspectratio < -3)*/ { + s = 32.0f; + ws = 1 << (-aspectratio - 3); + aspectratio = GR_ASPECT_LOG2_1x8; + } + } + + if (lodlevel) + (*lodlevel) = l; + + if (ar) + (*ar) = aspectratio; + + if (sscale) + (*sscale) = s; + + if (tscale) + (*tscale) = t; + + if (wscale) + (*wscale) = ws; + + if (hscale) + (*hscale) = hs; + + + return 1; +} + +static GLboolean +fxIsTexSupported(GLenum target, GLint internalFormat, + const struct gl_texture_image *image) +{ + if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D)) + return GL_FALSE; + +#if 0 + if (!fxTexGetInfo(image->Width, image->Height, NULL, NULL, NULL, NULL, NULL, NULL)) + return GL_FALSE; +#endif + + if (image->Border > 0) + return GL_FALSE; + + return GL_TRUE; +} + + +/**********************************************************************/ +/**** NEW TEXTURE IMAGE FUNCTIONS ****/ +/**********************************************************************/ +extern void +fxt1_decode_1 (const void *texture, int width, + int i, int j, unsigned char *rgba); + +/* Texel-fetch functions for software texturing and glGetTexImage(). + * We should have been able to use some "standard" fetch functions (which + * may get defined in texutil.c) but we have to account for scaled texture + * images on tdfx hardware (the 8:1 aspect ratio limit). + * Hence, we need special functions here. + */ + +static void +fetch_intensity8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = *texel; + rgba[GCOMP] = *texel; + rgba[BCOMP] = *texel; + rgba[ACOMP] = *texel; +} + + +static void +fetch_luminance8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = *texel; + rgba[GCOMP] = *texel; + rgba[BCOMP] = *texel; + rgba[ACOMP] = 255; +} + + +static void +fetch_alpha8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = 255; + rgba[GCOMP] = 255; + rgba[BCOMP] = 255; + rgba[ACOMP] = *texel; +} + + +static void +fetch_index8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *indexOut) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + *indexOut = *texel; +} + + +static void +fetch_luminance8_alpha8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2; + rgba[RCOMP] = texel[0]; + rgba[GCOMP] = texel[0]; + rgba[BCOMP] = texel[0]; + rgba[ACOMP] = texel[1]; +} + + +static void +fetch_r5g6b5(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLushort *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLushort *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = FX_rgb_scale_5[(*texel >> 11) & 0x1F]; + rgba[GCOMP] = FX_rgb_scale_6[(*texel >> 5) & 0x3F]; + rgba[BCOMP] = FX_rgb_scale_5[ *texel & 0x1F]; + rgba[ACOMP] = 255; +} + + +static void +fetch_r4g4b4a4(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLushort *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLushort *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = FX_rgb_scale_4[(*texel >> 8) & 0xF]; + rgba[GCOMP] = FX_rgb_scale_4[(*texel >> 4) & 0xF]; + rgba[BCOMP] = FX_rgb_scale_4[ *texel & 0xF]; + rgba[ACOMP] = FX_rgb_scale_4[(*texel >> 12) & 0xF]; +} + + +static void +fetch_r5g5b5a1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLushort *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLushort *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = FX_rgb_scale_5[(*texel >> 10) & 0x1F]; + rgba[GCOMP] = FX_rgb_scale_5[(*texel >> 5) & 0x1F]; + rgba[BCOMP] = FX_rgb_scale_5[ *texel & 0x1F]; + rgba[ACOMP] = (*texel >> 15) * 255; +} + + +static void +fetch_a8r8g8b8(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + const GLuint *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLuint *) texImage->Data) + j * mml->width + i; + rgba[RCOMP] = (((*texel) >> 16) & 0xff); + rgba[GCOMP] = (((*texel) >> 8) & 0xff); + rgba[BCOMP] = (((*texel) ) & 0xff); + rgba[ACOMP] = (((*texel) >> 24) & 0xff); +} + + +static void +fetch_rgb_fxt1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + fxt1_decode_1(texImage->Data, mml->width, i, j, rgba); + rgba[ACOMP] = 255; +} + + +static void +fetch_rgba_fxt1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + fxt1_decode_1(texImage->Data, mml->width, i, j, rgba); +} + + +static void +fetch_rgb_dxt1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + _mesa_texformat_rgb_dxt1.FetchTexel2D(texImage, i, j, k, rgba); +} + + +static void +fetch_rgba_dxt1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + _mesa_texformat_rgba_dxt1.FetchTexel2D(texImage, i, j, k, rgba); +} + + +static void +fetch_rgba_dxt3(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + _mesa_texformat_rgba_dxt3.FetchTexel2D(texImage, i, j, k, rgba); +} + + +static void +fetch_rgba_dxt5(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + _mesa_texformat_rgba_dxt5.FetchTexel2D(texImage, i, j, k, rgba); +} + + +#if 0 /* break glass in case of emergency */ +static void +PrintTexture(int w, int h, int c, const GLubyte * data) +{ + int i, j; + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + if (c == 2) + fprintf(stderr, "%02x %02x ", data[0], data[1]); + else if (c == 3) + fprintf(stderr, "%02x %02x %02x ", data[0], data[1], data[2]); + data += c; + } + fprintf(stderr, "\n"); + } +} +#endif + + +const struct gl_texture_format * +fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum srcFormat, GLenum srcType ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLboolean allow32bpt = fxMesa->HaveTexFmt; + + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxDDChooseTextureFormat(...)\n"); + } + + switch (internalFormat) { + case GL_COMPRESSED_RGB: + /* intentional fall through */ + case 3: + case GL_RGB: + if ( srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5 ) { + return &_mesa_texformat_rgb565; + } + /* intentional fall through */ + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return (allow32bpt) ? &_mesa_texformat_argb8888 + : &_mesa_texformat_rgb565; + case GL_RGBA2: + case GL_RGBA4: + return &_mesa_texformat_argb4444; + case GL_COMPRESSED_RGBA: + /* intentional fall through */ + case 4: + case GL_RGBA: + if ( srcFormat == GL_BGRA ) { + if ( srcType == GL_UNSIGNED_INT_8_8_8_8_REV ) { + return &_mesa_texformat_argb8888; + } + else if ( srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { + return &_mesa_texformat_argb4444; + } + else if ( srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + return &_mesa_texformat_argb1555; + } + } + /* intentional fall through */ + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return (allow32bpt) ? &_mesa_texformat_argb8888 + : &_mesa_texformat_argb4444; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return &_mesa_texformat_i8; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + return &_mesa_texformat_l8; + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: + return &_mesa_texformat_a8; + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return &_mesa_texformat_ci8; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + return &_mesa_texformat_al88; + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + return &_mesa_texformat_rgb565; + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + /* GL_EXT_texture_compression_s3tc */ + /* GL_S3_s3tc */ + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + return &_mesa_texformat_rgb_dxt1; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + return &_mesa_texformat_rgba_dxt3; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + /* GL_3DFX_texture_compression_FXT1 */ + case GL_COMPRESSED_RGB_FXT1_3DFX: + return &_mesa_texformat_rgb_fxt1; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return &_mesa_texformat_rgba_fxt1; + default: + _mesa_problem(NULL, "unexpected format in fxDDChooseTextureFormat"); + return NULL; + } +} + + +static GrTextureFormat_t +fxGlideFormat(GLint mesaFormat) +{ + switch (mesaFormat) { + case MESA_FORMAT_I8: + return GR_TEXFMT_ALPHA_8; + case MESA_FORMAT_A8: + return GR_TEXFMT_ALPHA_8; + case MESA_FORMAT_L8: + return GR_TEXFMT_INTENSITY_8; + case MESA_FORMAT_CI8: + return GR_TEXFMT_P_8; + case MESA_FORMAT_AL88: + return GR_TEXFMT_ALPHA_INTENSITY_88; + case MESA_FORMAT_RGB565: + return GR_TEXFMT_RGB_565; + case MESA_FORMAT_ARGB4444: + return GR_TEXFMT_ARGB_4444; + case MESA_FORMAT_ARGB1555: + return GR_TEXFMT_ARGB_1555; + case MESA_FORMAT_ARGB8888: + return GR_TEXFMT_ARGB_8888; + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return GR_TEXFMT_ARGB_CMP_FXT1; + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + return GR_TEXFMT_ARGB_CMP_DXT1; + case MESA_FORMAT_RGBA_DXT3: + return GR_TEXFMT_ARGB_CMP_DXT3; + case MESA_FORMAT_RGBA_DXT5: + return GR_TEXFMT_ARGB_CMP_DXT5; + default: + _mesa_problem(NULL, "Unexpected format in fxGlideFormat"); + return 0; + } +} + + +static FetchTexelFuncC +fxFetchFunction(GLint mesaFormat) +{ + switch (mesaFormat) { + case MESA_FORMAT_I8: + return &fetch_intensity8; + case MESA_FORMAT_A8: + return &fetch_alpha8; + case MESA_FORMAT_L8: + return &fetch_luminance8; + case MESA_FORMAT_CI8: + return &fetch_index8; + case MESA_FORMAT_AL88: + return &fetch_luminance8_alpha8; + case MESA_FORMAT_RGB565: + return &fetch_r5g6b5; + case MESA_FORMAT_ARGB4444: + return &fetch_r4g4b4a4; + case MESA_FORMAT_ARGB1555: + return &fetch_r5g5b5a1; + case MESA_FORMAT_ARGB8888: + return &fetch_a8r8g8b8; + case MESA_FORMAT_RGB_FXT1: + return &fetch_rgb_fxt1; + case MESA_FORMAT_RGBA_FXT1: + return &fetch_rgba_fxt1; + case MESA_FORMAT_RGB_DXT1: + return &fetch_rgb_dxt1; + case MESA_FORMAT_RGBA_DXT1: + return &fetch_rgba_dxt1; + case MESA_FORMAT_RGBA_DXT3: + return &fetch_rgba_dxt3; + case MESA_FORMAT_RGBA_DXT5: + return &fetch_rgba_dxt5; + default: + _mesa_problem(NULL, "Unexpected format in fxFetchFunction"); + return NULL; + } +} + + +static GLboolean +adjust2DRatio (GLcontext *ctx, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + tfxMipMapLevel *mml, + struct gl_texture_image *texImage, + GLint texelBytes, + GLint dstRowStride) +{ + const GLint newWidth = width * mml->wScale; + const GLint newHeight = height * mml->hScale; + GLvoid *tempImage; + + if (!texImage->IsCompressed) { + GLubyte *destAddr; + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + return GL_FALSE; + } + + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + texImage->TexFormat, tempImage, + 0, 0, 0, /* dstX/Y/Zoffset */ + width * texelBytes, /* dstRowStride */ + 0, /* dstImageStride */ + width, height, 1, + format, type, pixels, packing); + + /* now rescale */ + /* compute address of dest subimage within the overal tex image */ + destAddr = (GLubyte *) texImage->Data + + (yoffset * mml->hScale * mml->width + + xoffset * mml->wScale) * texelBytes; + + _mesa_rescale_teximage2d(texelBytes, + width, + dstRowStride, /* dst stride */ + width, height, + newWidth, newHeight, + tempImage, destAddr); + } else { + const GLint rawBytes = 4; + GLvoid *rawImage = MALLOC(width * height * rawBytes); + if (!rawImage) { + return GL_FALSE; + } + tempImage = MALLOC(newWidth * newHeight * rawBytes); + if (!tempImage) { + return GL_FALSE; + } + /* unpack image, apply transfer ops and store in rawImage */ + _mesa_texstore_rgba8888(ctx, 2, GL_RGBA, + &_mesa_texformat_rgba8888_rev, rawImage, + 0, 0, 0, /* dstX/Y/Zoffset */ + width * rawBytes, /* dstRowStride */ + 0, /* dstImageStride */ + width, height, 1, + format, type, pixels, packing); + _mesa_rescale_teximage2d(rawBytes, + width, + newWidth * rawBytes, /* dst stride */ + width, height, /* src */ + newWidth, newHeight, /* dst */ + rawImage /*src*/, tempImage /*dst*/ ); + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + texImage->TexFormat, texImage->Data, + xoffset * mml->wScale, yoffset * mml->hScale, 0, /* dstX/Y/Zoffset */ + dstRowStride, + 0, /* dstImageStride */ + newWidth, newHeight, 1, + GL_RGBA, CHAN_TYPE, tempImage, &ctx->DefaultPacking); + FREE(rawImage); + } + + FREE(tempImage); + + return GL_TRUE; +} + + +void +fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti; + tfxMipMapLevel *mml; + GLint texelBytes, dstRowStride; + + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n", + texObj->Name, texImage->IntFormat, format, type, + texImage->Width, texImage->Height); + } + + if (!fxIsTexSupported(target, internalFormat, texImage)) { + _mesa_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n"); + return; + } + + if (!texObj->DriverData) { + texObj->DriverData = fxAllocTexObjData(fxMesa); + if (!texObj->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + ti = fxTMGetTexInfo(texObj); + + if (!texImage->DriverData) { + texImage->DriverData = CALLOC(sizeof(tfxMipMapLevel)); + if (!texImage->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + mml = FX_MIPMAP_DATA(texImage); + + fxTexGetInfo(width, height, NULL, NULL, NULL, NULL, + &mml->wScale, &mml->hScale); + + mml->width = width * mml->wScale; + mml->height = height * mml->hScale; + +#if FX_COMPRESS_S3TC_AS_FXT1_HACK + /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */ + if (!ctx->Mesa_DXTn && texImage->IsCompressed) { + switch (internalFormat) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + internalFormat = GL_COMPRESSED_RGB_FXT1_3DFX; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + internalFormat = GL_COMPRESSED_RGBA_FXT1_3DFX; + } + texImage->IntFormat = internalFormat; + } +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + GLenum texNapalm = 0; + if (internalFormat == GL_COMPRESSED_RGB) { + texNapalm = GL_COMPRESSED_RGB_FXT1_3DFX; + } else if (internalFormat == GL_COMPRESSED_RGBA) { + texNapalm = GL_COMPRESSED_RGBA_FXT1_3DFX; + } + if (texNapalm) { + texImage->IntFormat = internalFormat = texNapalm; + texImage->IsCompressed = GL_TRUE; + } + } +#endif + + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); + texelBytes = texImage->TexFormat->TexelBytes; + /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/ + + mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + + /* allocate mipmap buffer */ + assert(!texImage->Data); + if (texImage->IsCompressed) { + texImage->CompressedSize = _mesa_compressed_texture_size(ctx, + mml->width, + mml->height, + 1, + internalFormat); + dstRowStride = _mesa_compressed_row_stride(internalFormat, mml->width); + texImage->Data = _mesa_malloc(texImage->CompressedSize); + } else { + dstRowStride = mml->width * texelBytes; + texImage->Data = _mesa_malloc(mml->width * mml->height * texelBytes); + } + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + + if (pixels != NULL) { + if (mml->wScale != 1 || mml->hScale != 1) { + /* rescale image to overcome 1:8 aspect limitation */ + if (!adjust2DRatio(ctx, + 0, 0, + width, height, + format, type, pixels, + packing, + mml, + texImage, + texelBytes, + dstRowStride) + ) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + else { + /* no rescaling needed */ + /* unpack image, apply transfer ops and store in texImage->Data */ + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + texImage->TexFormat, texImage->Data, + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + 0, /* dstImageStride */ + width, height, 1, + format, type, pixels, packing); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + GLint mipWidth, mipHeight; + tfxMipMapLevel *mip; + struct gl_texture_image *mipImage; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); + + assert(!texImage->IsCompressed); + + while (level < texObj->MaxLevel && level < maxLevels - 1) { + mipWidth = width / 2; + if (!mipWidth) { + mipWidth = 1; + } + mipHeight = height / 2; + if (!mipHeight) { + mipHeight = 1; + } + if ((mipWidth == width) && (mipHeight == height)) { + break; + } + _mesa_TexImage2D(target, ++level, internalFormat, + mipWidth, mipHeight, border, + format, type, + NULL); + mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mip = FX_MIPMAP_DATA(mipImage); + _mesa_halve2x2_teximage2d(ctx, + texImage, + texelBytes, + mml->width, mml->height, + texImage->Data, mipImage->Data); + texImage = mipImage; + mml = mip; + width = mipWidth; + height = mipHeight; + } + } + } + + ti->info.format = mml->glideFormat; + texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat); + + fxTexInvalidate(ctx, texObj); +} + + +void +fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti; + tfxMipMapLevel *mml; + GLint texelBytes, dstRowStride; + + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxDDTexSubImage2D: id=%d\n", texObj->Name); + } + + if (!texObj->DriverData) { + _mesa_problem(ctx, "problem in fxDDTexSubImage2D"); + return; + } + + ti = fxTMGetTexInfo(texObj); + assert(ti); + mml = FX_MIPMAP_DATA(texImage); + assert(mml); + + assert(texImage->Data); /* must have an existing texture image! */ + assert(texImage->Format); + + texelBytes = texImage->TexFormat->TexelBytes; + if (texImage->IsCompressed) { + dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, mml->width); + } else { + dstRowStride = mml->width * texelBytes; + } + + if (mml->wScale != 1 || mml->hScale != 1) { + /* need to rescale subimage to match mipmap level's rescale factors */ + if (!adjust2DRatio(ctx, + xoffset, yoffset, + width, height, + format, type, pixels, + packing, + mml, + texImage, + texelBytes, + dstRowStride) + ) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); + return; + } + } + else { + /* no rescaling needed */ + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + texImage->TexFormat, (GLubyte *) texImage->Data, + xoffset, yoffset, 0, /* dstX/Y/Zoffset */ + dstRowStride, + 0, /* dstImageStride */ + width, height, 1, + format, type, pixels, packing); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + GLint mipWidth, mipHeight; + tfxMipMapLevel *mip; + struct gl_texture_image *mipImage; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); + + assert(!texImage->IsCompressed); + + width = texImage->Width; + height = texImage->Height; + while (level < texObj->MaxLevel && level < maxLevels - 1) { + mipWidth = width / 2; + if (!mipWidth) { + mipWidth = 1; + } + mipHeight = height / 2; + if (!mipHeight) { + mipHeight = 1; + } + if ((mipWidth == width) && (mipHeight == height)) { + break; + } + ++level; + mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mip = FX_MIPMAP_DATA(mipImage); + _mesa_halve2x2_teximage2d(ctx, + texImage, + texelBytes, + mml->width, mml->height, + texImage->Data, mipImage->Data); + texImage = mipImage; + mml = mip; + width = mipWidth; + height = mipHeight; + } + } + + if (ti->validated && ti->isInTM && !texObj->GenerateMipmap) + fxTMReloadMipMapLevel(fxMesa, texObj, level); + else + fxTexInvalidate(ctx, texObj); +} + + +void +fxDDCompressedTexImage2D (GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti; + tfxMipMapLevel *mml; + + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxDDCompressedTexImage2D: id=%d int 0x%x %dx%d\n", + texObj->Name, internalFormat, + width, height); + } + + assert(texImage->IsCompressed); + + if (!fxIsTexSupported(target, internalFormat, texImage)) { + _mesa_problem(NULL, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n"); + return; + } + + if (!texObj->DriverData) { + texObj->DriverData = fxAllocTexObjData(fxMesa); + if (!texObj->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } + } + ti = fxTMGetTexInfo(texObj); + + if (!texImage->DriverData) { + texImage->DriverData = CALLOC(sizeof(tfxMipMapLevel)); + if (!texImage->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } + } + mml = FX_MIPMAP_DATA(texImage); + + fxTexGetInfo(width, height, NULL, NULL, NULL, NULL, + &mml->wScale, &mml->hScale); + + mml->width = width * mml->wScale; + mml->height = height * mml->hScale; + + + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, -1/*format*/, -1/*type*/); + assert(texImage->TexFormat); + + /* Determine the appropriate Glide texel format, + * given the user's internal texture format hint. + */ + mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + + /* allocate new storage for texture image, if needed */ + if (!texImage->Data) { + texImage->CompressedSize = _mesa_compressed_texture_size(ctx, + mml->width, + mml->height, + 1, + internalFormat); + texImage->Data = _mesa_malloc(texImage->CompressedSize); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } + } + + /* save the texture data */ + if (mml->wScale != 1 || mml->hScale != 1) { + /* [dBorca] Hack alert: + * now we're screwed. We can't decompress, + * unless we do it in HW (via textureBuffer). + * We still have some chances: + * 1) we got FXT1 textures - we CAN decompress, rescale for + * aspectratio, then compress back. + * 2) there is a chance that MIN("s", "t") won't be overflowed. + * Thus, we don't care about textureclamp and we could lower + * MIN("uscale", "vscale") below 32. We still have to have + * our data aligned inside a 8:1 rectangle. + * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT, + * we replicate the data over the padded area. + * For now, we take 2) + 3) but texelfetchers will be wrong! + */ + GLuint srcRowStride = _mesa_compressed_row_stride(internalFormat, width); + + GLuint destRowStride = _mesa_compressed_row_stride(internalFormat, + mml->width); + + _mesa_upscale_teximage2d(srcRowStride, (height+3) / 4, + destRowStride, (mml->height+3) / 4, + 1, data, srcRowStride, + texImage->Data); + ti->padded = GL_TRUE; + } else { + MEMCPY(texImage->Data, data, texImage->CompressedSize); + } + + ti->info.format = mml->glideFormat; + texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + assert(!texImage->IsCompressed); + } + + fxTexInvalidate(ctx, texObj); +} + + +void +fxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLint height, GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti; + tfxMipMapLevel *mml; + GLint destRowStride, srcRowStride; + GLint i, rows; + GLubyte *dest; + + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxDDCompressedTexSubImage2D: id=%d\n", texObj->Name); + } + + ti = fxTMGetTexInfo(texObj); + assert(ti); + mml = FX_MIPMAP_DATA(texImage); + assert(mml); + + srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width); + + destRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + mml->width); + dest = _mesa_compressed_image_address(xoffset, yoffset, 0, + texImage->IntFormat, + mml->width, + (GLubyte*) texImage->Data); + + rows = height / 4; /* hardcoded 4, but works for FXT1/DXTC */ + + for (i = 0; i < rows; i++) { + MEMCPY(dest, data, srcRowStride); + dest += destRowStride; + data = (GLvoid *)((GLuint)data + (GLuint)srcRowStride); + } + + /* [dBorca] Hack alert: + * see fxDDCompressedTexImage2D for caveats + */ + if (mml->wScale != 1 || mml->hScale != 1) { + srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, texImage->Width); + + destRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + mml->width); + _mesa_upscale_teximage2d(srcRowStride, texImage->Height / 4, + destRowStride, mml->height / 4, + 1, texImage->Data, destRowStride, + texImage->Data); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + assert(!texImage->IsCompressed); + } + + if (ti->validated && ti->isInTM) + fxTMReloadMipMapLevel(fxMesa, texObj, level); + else + fxTexInvalidate(ctx, texObj); +} + + +void +fxDDTexImage1D (GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + fxDDTexImage2D(ctx, target, level, + internalFormat, width, 1, border, + format, type, pixels, + packing, + texObj, + texImage); +} + + +void +fxDDTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + fxDDTexSubImage2D(ctx, target, level, + xoffset, 0, width, 1, + format, type, pixels, + packing, + texObj, + texImage); +} + + +GLboolean +fxDDTestProxyTexImage (GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLenum format, GLenum type, + GLint width, GLint height, + GLint depth, GLint border) +{ + /* XXX todo - maybe through fxTexValidate() */ + return _mesa_test_proxy_teximage(ctx, target, + level, internalFormat, + format, type, + width, height, + depth, border); +} + + +#else /* FX */ + +/* + * Need this to provide at least one external definition. + */ + +extern int gl_fx_dummy_function_ddtex(void); +int +gl_fx_dummy_function_ddtex(void) +{ + return 0; +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdrv.h b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdrv.h new file mode 100644 index 000000000..ca3bdc99b --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdrv.h @@ -0,0 +1,771 @@ +/* + * 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 + */ + +/* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */ + + +#ifndef FXDRV_H +#define FXDRV_H + +/* If you comment out this define, a variable takes its place, letting + * you turn debugging on/off from the debugger. + */ + +#include "glheader.h" + + +#if defined(__linux__) +#include <signal.h> +#endif + +#include "context.h" +#include "imports.h" +#include "macros.h" +#include "matrix.h" +#include "mtypes.h" + +#include "GL/fxmesa.h" +#include "fxglidew.h" + +#include "math/m_vector.h" + + +/* Define some shorter names for these things. + */ +#define XCOORD GR_VERTEX_X_OFFSET +#define YCOORD GR_VERTEX_Y_OFFSET +#define ZCOORD GR_VERTEX_OOZ_OFFSET +#define OOWCOORD GR_VERTEX_OOW_OFFSET + +#define S0COORD GR_VERTEX_SOW_TMU0_OFFSET +#define T0COORD GR_VERTEX_TOW_TMU0_OFFSET +#define S1COORD GR_VERTEX_SOW_TMU1_OFFSET +#define T1COORD GR_VERTEX_TOW_TMU1_OFFSET + + + +#ifdef __i386__ +#define FXCOLOR4( c ) (* (int *)c) +#else +#define FXCOLOR4( c ) ( \ + ( ((unsigned int)(c[3]))<<24 ) | \ + ( ((unsigned int)(c[2]))<<16 ) | \ + ( ((unsigned int)(c[1]))<<8 ) | \ + ( (unsigned int)(c[0])) ) +#endif + +#define TDFXPACKCOLOR1555( r, g, b, a ) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) +#define TDFXPACKCOLOR565( r, g, b ) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) +#define TDFXPACKCOLOR8888( r, g, b, a ) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + + + +/* fastpath flags first + */ +#define SETUP_TMU0 0x1 +#define SETUP_TMU1 0x2 +#define SETUP_RGBA 0x4 +#define SETUP_SNAP 0x8 +#define SETUP_XYZW 0x10 +#define SETUP_PTEX 0x20 +#define SETUP_PSIZ 0x40 +#define SETUP_SPEC 0x80 +#define SETUP_FOGC 0x100 +#define MAX_SETUP 0x200 + + +#define FX_NUM_TMU 2 + +#define FX_TMU0 GR_TMU0 +#define FX_TMU1 GR_TMU1 +#define FX_TMU_SPLIT 98 +#define FX_TMU_BOTH 99 +#define FX_TMU_NONE 100 + +/* Used for fxMesa->lastUnitsMode */ + +#define FX_UM_NONE 0x00000000 + +#define FX_UM_E0_REPLACE 0x00000001 +#define FX_UM_E0_MODULATE 0x00000002 +#define FX_UM_E0_DECAL 0x00000004 +#define FX_UM_E0_BLEND 0x00000008 +#define FX_UM_E0_ADD 0x00000010 + +#define FX_UM_E1_REPLACE 0x00000020 +#define FX_UM_E1_MODULATE 0x00000040 +#define FX_UM_E1_DECAL 0x00000080 +#define FX_UM_E1_BLEND 0x00000100 +#define FX_UM_E1_ADD 0x00000200 + +#define FX_UM_E_ENVMODE 0x000003ff + +#define FX_UM_E0_ALPHA 0x00001000 +#define FX_UM_E0_LUMINANCE 0x00002000 +#define FX_UM_E0_LUMINANCE_ALPHA 0x00004000 +#define FX_UM_E0_INTENSITY 0x00008000 +#define FX_UM_E0_RGB 0x00010000 +#define FX_UM_E0_RGBA 0x00020000 + +#define FX_UM_E1_ALPHA 0x00040000 +#define FX_UM_E1_LUMINANCE 0x00080000 +#define FX_UM_E1_LUMINANCE_ALPHA 0x00100000 +#define FX_UM_E1_INTENSITY 0x00200000 +#define FX_UM_E1_RGB 0x00400000 +#define FX_UM_E1_RGBA 0x00800000 + +#define FX_UM_E_IFMT 0x00fff000 + +#define FX_UM_COLOR_ITERATED 0x01000000 +#define FX_UM_COLOR_CONSTANT 0x02000000 +#define FX_UM_ALPHA_ITERATED 0x04000000 +#define FX_UM_ALPHA_CONSTANT 0x08000000 + + +/* for Voodoo3/Banshee's grColorCombine() and grAlphaCombine() */ +struct tdfx_combine { + GrCombineFunction_t Function; /* Combine function */ + GrCombineFactor_t Factor; /* Combine scale factor */ + GrCombineLocal_t Local; /* Local combine source */ + GrCombineOther_t Other; /* Other combine source */ + FxBool Invert; /* Combine result inversion flag */ +}; + +/* for Voodoo3's grTexCombine() */ +struct tdfx_texcombine { + GrCombineFunction_t FunctionRGB; + GrCombineFactor_t FactorRGB; + GrCombineFunction_t FunctionAlpha; + GrCombineFactor_t FactorAlpha; + FxBool InvertRGB; + FxBool InvertAlpha; +}; + + +/* for Voodoo5's grColorCombineExt() */ +struct tdfx_combine_color_ext { + GrCCUColor_t SourceA; + GrCombineMode_t ModeA; + GrCCUColor_t SourceB; + GrCombineMode_t ModeB; + GrCCUColor_t SourceC; + FxBool InvertC; + GrCCUColor_t SourceD; + FxBool InvertD; + FxU32 Shift; + FxBool Invert; +}; + +/* for Voodoo5's grAlphaCombineExt() */ +struct tdfx_combine_alpha_ext { + GrACUColor_t SourceA; + GrCombineMode_t ModeA; + GrACUColor_t SourceB; + GrCombineMode_t ModeB; + GrACUColor_t SourceC; + FxBool InvertC; + GrACUColor_t SourceD; + FxBool InvertD; + FxU32 Shift; + FxBool Invert; +}; + +/* for Voodoo5's grTexColorCombineExt() */ +struct tdfx_color_texenv { + GrTCCUColor_t SourceA; + GrCombineMode_t ModeA; + GrTCCUColor_t SourceB; + GrCombineMode_t ModeB; + GrTCCUColor_t SourceC; + FxBool InvertC; + GrTCCUColor_t SourceD; + FxBool InvertD; + FxU32 Shift; + FxBool Invert; +}; + +/* for Voodoo5's grTexAlphaCombineExt() */ +struct tdfx_alpha_texenv { + GrTACUColor_t SourceA; + GrCombineMode_t ModeA; + GrTACUColor_t SourceB; + GrCombineMode_t ModeB; + GrTACUColor_t SourceC; + FxBool InvertC; + GrTCCUColor_t SourceD; + FxBool InvertD; + FxU32 Shift; + FxBool Invert; +}; + +/* Voodoo5's texture combine environment */ +struct tdfx_texcombine_ext { + struct tdfx_alpha_texenv Alpha; + struct tdfx_color_texenv Color; + GrColor_t EnvColor; +}; + + +/* + Memory range from startAddr to endAddr-1 +*/ +typedef struct MemRange_t +{ + struct MemRange_t *next; + FxU32 startAddr, endAddr; +} +MemRange; + +typedef struct +{ + GLsizei width, height; /* image size */ + GLint wScale, hScale; /* image scale factor */ + GrTextureFormat_t glideFormat; /* Glide image format */ +} +tfxMipMapLevel; + +/* + * TDFX-specific texture object data. This hangs off of the + * struct gl_texture_object DriverData pointer. + */ +typedef struct tfxTexInfo_t +{ + struct tfxTexInfo_t *next; + struct gl_texture_object *tObj; + + GLuint lastTimeUsed; + FxU32 whichTMU; + GLboolean isInTM; + + MemRange *tm[FX_NUM_TMU]; + + GLint minLevel, maxLevel; + GLint baseLevelInternalFormat; + + GrTexInfo info; + + GrTextureFilterMode_t minFilt; + GrTextureFilterMode_t maxFilt; + FxBool LODblend; + + GrTextureClampMode_t sClamp; + GrTextureClampMode_t tClamp; + + GrMipMapMode_t mmMode; + + GLfloat sScale, tScale; + + GrTexTable_t paltype; + GuTexPalette palette; + + GLboolean fixedPalette; + GLboolean validated; + + GLboolean padded; +} +tfxTexInfo; + +typedef struct +{ + GLuint swapBuffer; + GLuint reqTexUpload; + GLuint texUpload; + GLuint memTexUpload; +} +tfxStats; + + + +typedef struct +{ + /* Alpha test */ + + GLboolean alphaTestEnabled; + GrCmpFnc_t alphaTestFunc; + GLfloat alphaTestRefValue; + + /* Blend function */ + + GLboolean blendEnabled; + GrAlphaBlendFnc_t blendSrcFuncRGB; + GrAlphaBlendFnc_t blendDstFuncRGB; + GrAlphaBlendFnc_t blendSrcFuncAlpha; + GrAlphaBlendFnc_t blendDstFuncAlpha; + GrAlphaBlendOp_t blendEqRGB; + GrAlphaBlendOp_t blendEqAlpha; + + /* Depth test */ + + GLboolean depthTestEnabled; + GLboolean depthMask; + GrCmpFnc_t depthTestFunc; + FxI32 depthBias; + + /* Stencil */ + + GLboolean stencilEnabled; + GrCmpFnc_t stencilFunction; /* Stencil function */ + GrStencil_t stencilRefValue; /* Stencil reference value */ + GrStencil_t stencilValueMask; /* Value mask */ + GrStencil_t stencilWriteMask; /* Write mask */ + GrCmpFnc_t stencilFailFunc; /* Stencil fail function */ + GrCmpFnc_t stencilZFailFunc; /* Stencil pass, depth fail function */ + GrCmpFnc_t stencilZPassFunc; /* Stencil pass, depth pass function */ + GrStencil_t stencilClear; /* Buffer clear value */ +} +tfxUnitsState; + + + + +/* Flags for fxMesa->new_state + */ +#define FX_NEW_TEXTURING 0x1 +#define FX_NEW_BLEND 0x2 +#define FX_NEW_ALPHA 0x4 +#define FX_NEW_DEPTH 0x8 +#define FX_NEW_FOG 0x10 +#define FX_NEW_SCISSOR 0x20 +#define FX_NEW_COLOR_MASK 0x40 +#define FX_NEW_CULL 0x80 +#define FX_NEW_STENCIL 0x100 + + +#define FX_CONTEXT(ctx) ((fxMesaContext)((ctx)->DriverCtx)) + +#define FX_TEXTURE_DATA(texUnit) fxTMGetTexInfo((texUnit)->_Current) + +#define fxTMGetTexInfo(o) ((tfxTexInfo*)((o)->DriverData)) + +#define FX_MIPMAP_DATA(img) ((tfxMipMapLevel *) (img)->DriverData) + +#define BEGIN_BOARD_LOCK() +#define END_BOARD_LOCK() +#define BEGIN_CLIP_LOOP() +#define END_CLIP_LOOP() + + + + +/* Covers the state referenced by IsInHardware: + */ +#define _FX_NEW_IS_IN_HARDWARE (_NEW_TEXTURE| \ + _NEW_HINT| \ + _NEW_STENCIL| \ + _NEW_BUFFERS| \ + _NEW_COLOR| \ + _NEW_LIGHT) + +/* Covers the state referenced by fxDDChooseRenderState + */ +#define _FX_NEW_RENDERSTATE (_FX_NEW_IS_IN_HARDWARE | \ + _DD_NEW_FLATSHADE | \ + _DD_NEW_TRI_LIGHT_TWOSIDE| \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_SMOOTH | \ + _DD_NEW_TRI_STIPPLE | \ + _DD_NEW_LINE_SMOOTH | \ + _DD_NEW_LINE_STIPPLE | \ + _DD_NEW_LINE_WIDTH | \ + _DD_NEW_POINT_SMOOTH | \ + _DD_NEW_POINT_SIZE | \ + _NEW_LINE) + + +/* Covers the state referenced by fxDDChooseSetupFunction. + */ +#define _FX_NEW_SETUP_FUNCTION (_NEW_LIGHT| \ + _NEW_FOG| \ + _NEW_TEXTURE| \ + _NEW_COLOR) \ + + +/* lookup table for scaling y bit colors up to 8 bits */ +extern GLuint FX_rgb_scale_4[16]; +extern GLuint FX_rgb_scale_5[32]; +extern GLuint FX_rgb_scale_6[64]; + +typedef void (*fx_tri_func) (fxMesaContext, GrVertex *, GrVertex *, GrVertex *); +typedef void (*fx_line_func) (fxMesaContext, GrVertex *, GrVertex *); +typedef void (*fx_point_func) (fxMesaContext, GrVertex *); + +struct tfxMesaContext +{ + GrTexTable_t glbPalType; + GuTexPalette glbPalette; + + GLcontext *glCtx; /* the core Mesa context */ + GLvisual *glVis; /* describes the color buffer */ + GLframebuffer *glBuffer; /* the ancillary buffers */ + + GLint board; /* the board used for this context */ + GLint width, height; /* size of color buffer */ + + GrBuffer_t currentFB; + + GLboolean bgrOrder; + GrColor_t color; + GrColor_t clearC; + GrAlpha_t clearA; + GLuint constColor; + GrCullMode_t cullMode; + + tfxUnitsState unitsState; + tfxUnitsState restoreUnitsState; /* saved during multipass */ + GLboolean multipass; /* true when drawing intermediate pass */ + + GLuint new_state; + GLuint new_gl_state; + + /* Texture Memory Manager Data + */ + GLuint texBindNumber; + GLint tmuSrc; + GLuint lastUnitsMode; + GLuint freeTexMem[FX_NUM_TMU]; + MemRange *tmPool; + MemRange *tmFree[FX_NUM_TMU]; + + GLenum fogTableMode; + GLfloat fogDensity; + GLfloat fogStart, fogEnd; + GrFog_t *fogTable; + GLint textureAlign; + GLint textureMaxLod; + + /* Vertex building and storage: + */ + GLuint tmu_source[FX_NUM_TMU]; + GLuint SetupIndex; + GLuint stw_hint_state; /* for grHints */ + GrVertex *verts; + GLboolean snapVertices; /* needed for older Voodoo hardware */ + + /* Rasterization: + */ + GLuint render_index; + GLuint fallback; + GLenum render_primitive; + GLenum raster_primitive; + + /* Current rasterization functions + */ + fx_point_func draw_point; + fx_line_func draw_line; + fx_tri_func draw_tri; + + + /* Keep texture scales somewhere handy: + */ + GLfloat s0scale; + GLfloat s1scale; + GLfloat t0scale; + GLfloat t1scale; + + GLfloat inv_s0scale; + GLfloat inv_s1scale; + GLfloat inv_t0scale; + GLfloat inv_t1scale; + + /* Glide stuff + */ + tfxStats stats; + void *state; + + /* Options */ + + GLboolean verbose; + GLboolean haveTwoTMUs; /* True if we really have 2 tmu's */ + GLboolean haveHwAlpha; + GLboolean haveHwStencil; + GLboolean haveZBuffer; + GLboolean haveDoubleBuffer; + GLboolean haveGlobalPaletteTexture; + GLint swapInterval; + GLint maxPendingSwapBuffers; + + GrContext_t glideContext; + + int screen_width; + int screen_height; + int clipMinX; + int clipMaxX; + int clipMinY; + int clipMaxY; + + int colDepth; + GLboolean fsaa; + + /* Glide (per card) capabilities. These get mirrored + * from `glbHWConfig' when creating a new context... + */ + GrSstType type; + FxBool HavePalExt; /* PALETTE6666 */ + FxBool HavePixExt; /* PIXEXT */ + FxBool HaveTexFmt; /* TEXFMT */ + FxBool HaveCmbExt; /* COMBINE */ + FxBool HaveMirExt; /* TEXMIRROR */ + FxBool HaveTexUma; /* TEXUMA */ + FxBool HaveTexus2; /* Texus 2 - FXT1 */ + struct tdfx_glide Glide; + char rendererString[64]; +}; + + +extern void fxSetupFXUnits(GLcontext *); +extern void fxSetupDDPointers(GLcontext *); + +/* fxvb.c: + */ +extern void fxAllocVB(GLcontext * ctx); +extern void fxFreeVB(GLcontext * ctx); +extern void fxPrintSetupFlags(char *msg, GLuint flags ); +extern void fxCheckTexSizes( GLcontext *ctx ); +extern void fxBuildVertices( GLcontext *ctx, GLuint start, GLuint end, + GLuint newinputs ); +extern void fxChooseVertexState( GLcontext *ctx ); + + + + + + +/* fxtrifuncs: + */ +extern void fxDDInitTriFuncs(GLcontext *); +extern void fxDDChooseRenderState(GLcontext * ctx); + + +extern void fxUpdateDDSpanPointers(GLcontext *); +extern void fxSetupDDSpanPointers(GLcontext *); + +extern void fxPrintTextureData(tfxTexInfo * ti); + +extern const struct gl_texture_format * +fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum srcFormat, GLenum srcType ); +extern void fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, GLint width, GLint height, + GLint border, GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +extern void fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +extern void fxDDCompressedTexImage2D(GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +extern void fxDDCompressedTexSubImage2D(GLcontext *ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLint height, GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +extern void fxDDTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, GLint width, + GLint border, GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +extern void fxDDTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +extern GLboolean fxDDTestProxyTexImage (GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLenum format, GLenum type, + GLint width, GLint height, + GLint depth, GLint border); +extern void fxDDTexEnv(GLcontext *, GLenum, GLenum, const GLfloat *); +extern void fxDDTexParam(GLcontext *, GLenum, struct gl_texture_object *, + GLenum, const GLfloat *); +extern void fxDDTexBind(GLcontext *, GLenum, struct gl_texture_object *); +extern struct gl_texture_object *fxDDNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ); +extern void fxDDTexDel(GLcontext *, struct gl_texture_object *); +extern GLboolean fxDDIsTextureResident(GLcontext *, struct gl_texture_object *); +extern void fxDDTexPalette(GLcontext *, struct gl_texture_object *); +extern void fxDDTexUseGlbPalette(GLcontext *, GLboolean); + +extern void fxDDEnable(GLcontext *, GLenum, GLboolean); +extern void fxDDAlphaFunc(GLcontext *, GLenum, GLfloat); +extern void fxDDBlendFuncSeparate(GLcontext *, GLenum, GLenum, GLenum, GLenum); +extern void fxDDBlendEquationSeparate(GLcontext *, GLenum, GLenum); +extern void fxDDDepthMask(GLcontext *, GLboolean); +extern void fxDDDepthFunc(GLcontext *, GLenum); +extern void fxDDStencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask); +extern void fxDDStencilMask (GLcontext *ctx, GLuint mask); +extern void fxDDStencilOp (GLcontext *ctx, GLenum sfail, GLenum zfail, GLenum zpass); + +extern void fxDDInitExtensions(GLcontext * ctx); + +extern void fxTMInit(fxMesaContext ctx); +extern void fxTMClose(fxMesaContext ctx); +extern void fxTMRestoreTextures_NoLock(fxMesaContext ctx); +extern void fxTMMoveInTM(fxMesaContext, struct gl_texture_object *, GLint); +extern void fxTMMoveOutTM(fxMesaContext, struct gl_texture_object *); +#define fxTMMoveOutTM_NoLock fxTMMoveOutTM +extern void fxTMFreeTexture(fxMesaContext, struct gl_texture_object *); +extern void fxTMReloadMipMapLevel(fxMesaContext, struct gl_texture_object *, + GLint); +extern void fxTMReloadSubMipMapLevel(fxMesaContext, + struct gl_texture_object *, GLint, GLint, + GLint); +extern int fxTMCheckStartAddr (fxMesaContext fxMesa, GLint tmu, tfxTexInfo *ti); + +extern void fxTexGetFormat(GLcontext *, GLenum, GrTextureFormat_t *, GLint *); /* [koolsmoky] */ + +extern int fxTexGetInfo(int, int, GrLOD_t *, GrAspectRatio_t *, + float *, float *, int *, int *); + +extern void fxDDScissor(GLcontext * ctx, + GLint x, GLint y, GLsizei w, GLsizei h); +extern void fxDDFogfv(GLcontext * ctx, GLenum pname, const GLfloat * params); +extern void fxDDColorMask(GLcontext * ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a); + +extern void fxDDWriteDepthSpan(GLcontext * ctx, GLuint n, GLint x, GLint y, + const GLdepth depth[], const GLubyte mask[]); + +extern void fxDDReadDepthSpan(GLcontext * ctx, GLuint n, GLint x, GLint y, + GLdepth depth[]); + +extern void fxDDWriteDepthPixels(GLcontext * ctx, GLuint n, + const GLint x[], const GLint y[], + const GLdepth depth[], const GLubyte mask[]); + +extern void fxDDReadDepthPixels(GLcontext * ctx, GLuint n, + const GLint x[], const GLint y[], + GLdepth depth[]); + +extern void fxDDShadeModel(GLcontext * ctx, GLenum mode); + +extern void fxDDCullFace(GLcontext * ctx, GLenum mode); +extern void fxDDFrontFace(GLcontext * ctx, GLenum mode); + +extern void fxPrintRenderState(const char *msg, GLuint state); +extern void fxPrintHintState(const char *msg, GLuint state); + +extern int fxDDInitFxMesaContext(fxMesaContext fxMesa); +extern void fxDDDestroyFxMesaContext(fxMesaContext fxMesa); + + +extern void fxSetScissorValues(GLcontext * ctx); +extern void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, + struct gl_texture_object *tObj, GLint where); + +extern void fxCheckIsInHardware(GLcontext *ctx); + +/* fxsetup: + * semi-private functions + */ +void fxSetupCull (GLcontext * ctx); +void fxSetupScissor (GLcontext * ctx); +void fxSetupColorMask (GLcontext * ctx); +void fxSetupBlend (GLcontext *ctx); +void fxSetupDepthTest (GLcontext *ctx); +void fxSetupTexture (GLcontext *ctx); +void fxSetupStencil (GLcontext *ctx); +void fxSetupStencilFace (GLcontext *ctx, GLint face); + +/* Flags for software fallback cases */ +#define FX_FALLBACK_TEXTURE_MAP 0x0001 +#define FX_FALLBACK_DRAW_BUFFER 0x0002 +#define FX_FALLBACK_SPECULAR 0x0004 +#define FX_FALLBACK_STENCIL 0x0008 +#define FX_FALLBACK_RENDER_MODE 0x0010 +#define FX_FALLBACK_LOGICOP 0x0020 +#define FX_FALLBACK_TEXTURE_ENV 0x0040 +#define FX_FALLBACK_TEXTURE_BORDER 0x0080 +#define FX_FALLBACK_COLORMASK 0x0100 +#define FX_FALLBACK_BLEND 0x0200 +#define FX_FALLBACK_TEXTURE_MULTI 0x0400 + +extern GLuint fx_check_IsInHardware(GLcontext *ctx); + +/*** + *** CNORM: clamp float to [0,1] and map to float in [0,255] + ***/ +#if defined(USE_IEEE) && !defined(DEBUG) +#define IEEE_0996 0x3f7f0000 /* 0.996 or so */ +#define CNORM(N, F) \ + do { \ + fi_type __tmp; \ + __tmp.f = (F); \ + if (__tmp.i < 0) \ + N = 0; \ + else if (__tmp.i >= IEEE_0996) \ + N = 255.0f; \ + else { \ + N = (F) * 255.0f; \ + } \ + } while (0) +#else +#define CNORM(n, f) \ + n = (CLAMP((f), 0.0F, 1.0F) * 255.0F) +#endif + +/* run-time debugging */ +#ifndef FX_DEBUG +#define FX_DEBUG 0 +#endif +#if FX_DEBUG +extern int TDFX_DEBUG; +#else +#define TDFX_DEBUG 0 +#endif + +/* dirty hacks */ +#define FX_RESCALE_BIG_TEXURES_HACK 1 +#define FX_COMPRESS_S3TC_AS_FXT1_HACK 1 + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.c new file mode 100644 index 000000000..afb9441ad --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.c @@ -0,0 +1,2309 @@ +/* + * Mesa 3-D graphics library + * Version: 5.0.1 + * + * Copyright (C) 1999-2003 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. + */ + +/* + * Mesa/FX device driver. Interface to Glide3. + * + * Copyright (c) 2003 - Daniel Borca + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + */ + + +#ifdef FX + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <assert.h> + +#define FX_TRAP_GLIDE_internal +#include "fxg.h" + + + +/****************************************************************************\ +* logging * +\****************************************************************************/ +#if FX_TRAP_GLIDE +#define TRAP_LOG trp_printf +#ifdef __GNUC__ +__attribute__ ((format(printf, 1, 2))) +#endif /* __GNUC__ */ +int trp_printf (const char *format, ...) +{ + va_list arg; + int n; + FILE *trap_file; + va_start(arg, format); + trap_file = fopen("trap.log", "a"); + if (trap_file == NULL) { + trap_file = stderr; + } + n = vfprintf(trap_file, format, arg); + fclose(trap_file); + va_end(arg); + return n; +} +#else /* FX_TRAP_GLIDE */ +#ifdef __GNUC__ +#define TRAP_LOG(format, ...) do {} while (0) +#else /* __GNUC__ */ +#define TRAP_LOG 0 && (unsigned long) +#endif /* __GNUC__ */ +#endif /* FX_TRAP_GLIDE */ + + + +#if FX_TRAP_GLIDE +/****************************************************************************\ +* helpers * +\****************************************************************************/ + +#define GOT "\t" + +const char *TRP_BOOL (FxBool b) +{ + return b ? "FXTRUE" : "FXFALSE"; +} + +#define TRAP_CASE_STRING(name) case name: return #name +#define TRAP_NODEFAULT default: assert(0) + +const char *TRP_PARAM (FxU32 mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_PARAM_DISABLE); + TRAP_CASE_STRING(GR_PARAM_ENABLE); + TRAP_NODEFAULT; + } +} + +const char *TRP_VTX (FxU32 param) +{ + switch (param) { + TRAP_CASE_STRING(GR_PARAM_XY); + TRAP_CASE_STRING(GR_PARAM_Z); + TRAP_CASE_STRING(GR_PARAM_W); + TRAP_CASE_STRING(GR_PARAM_Q); + TRAP_CASE_STRING(GR_PARAM_FOG_EXT); + TRAP_CASE_STRING(GR_PARAM_A); + TRAP_CASE_STRING(GR_PARAM_RGB); + TRAP_CASE_STRING(GR_PARAM_PARGB); + TRAP_CASE_STRING(GR_PARAM_ST0); + TRAP_CASE_STRING(GR_PARAM_ST1); + TRAP_CASE_STRING(GR_PARAM_ST2); + TRAP_CASE_STRING(GR_PARAM_Q0); + TRAP_CASE_STRING(GR_PARAM_Q1); + TRAP_CASE_STRING(GR_PARAM_Q2); + TRAP_NODEFAULT; + } +} + +const char *TRP_ARRAY (FxU32 mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_POINTS); + TRAP_CASE_STRING(GR_LINE_STRIP); + TRAP_CASE_STRING(GR_LINES); + TRAP_CASE_STRING(GR_POLYGON); + TRAP_CASE_STRING(GR_TRIANGLE_STRIP); + TRAP_CASE_STRING(GR_TRIANGLE_FAN); + TRAP_CASE_STRING(GR_TRIANGLES); + TRAP_CASE_STRING(GR_TRIANGLE_STRIP_CONTINUE); + TRAP_CASE_STRING(GR_TRIANGLE_FAN_CONTINUE); + TRAP_NODEFAULT; + } +} + +const char *TRP_BUFFER (GrBuffer_t buffer) +{ + switch (buffer) { + TRAP_CASE_STRING(GR_BUFFER_FRONTBUFFER); + TRAP_CASE_STRING(GR_BUFFER_BACKBUFFER); + TRAP_CASE_STRING(GR_BUFFER_AUXBUFFER); + TRAP_CASE_STRING(GR_BUFFER_DEPTHBUFFER); + TRAP_CASE_STRING(GR_BUFFER_ALPHABUFFER); + TRAP_CASE_STRING(GR_BUFFER_TRIPLEBUFFER); + TRAP_CASE_STRING(GR_BUFFER_TEXTUREBUFFER_EXT); + TRAP_CASE_STRING(GR_BUFFER_TEXTUREAUXBUFFER_EXT); + TRAP_NODEFAULT; + } +} + +const char *TRP_ORIGIN (GrOriginLocation_t origin_location) +{ + switch (origin_location) { + TRAP_CASE_STRING(GR_ORIGIN_UPPER_LEFT); + TRAP_CASE_STRING(GR_ORIGIN_LOWER_LEFT); + TRAP_CASE_STRING(GR_ORIGIN_ANY); + TRAP_NODEFAULT; + } +} + +const char *TRP_REFRESH (GrScreenRefresh_t refresh_rate) +{ + switch (refresh_rate) { + TRAP_CASE_STRING(GR_REFRESH_60Hz); + TRAP_CASE_STRING(GR_REFRESH_70Hz); + TRAP_CASE_STRING(GR_REFRESH_72Hz); + TRAP_CASE_STRING(GR_REFRESH_75Hz); + TRAP_CASE_STRING(GR_REFRESH_80Hz); + TRAP_CASE_STRING(GR_REFRESH_90Hz); + TRAP_CASE_STRING(GR_REFRESH_100Hz); + TRAP_CASE_STRING(GR_REFRESH_85Hz); + TRAP_CASE_STRING(GR_REFRESH_120Hz); + TRAP_CASE_STRING(GR_REFRESH_NONE); + TRAP_NODEFAULT; + } +} + +const char *TRP_COLFMT (GrColorFormat_t color_format) +{ + switch (color_format) { + TRAP_CASE_STRING(GR_COLORFORMAT_ARGB); + TRAP_CASE_STRING(GR_COLORFORMAT_ABGR); + TRAP_CASE_STRING(GR_COLORFORMAT_RGBA); + TRAP_CASE_STRING(GR_COLORFORMAT_BGRA); + TRAP_NODEFAULT; + } +} + +const char *TRP_RESOLUTION (GrScreenResolution_t screen_resolution) +{ + switch (screen_resolution) { + TRAP_CASE_STRING(GR_RESOLUTION_320x200); + TRAP_CASE_STRING(GR_RESOLUTION_320x240); + TRAP_CASE_STRING(GR_RESOLUTION_400x256); + TRAP_CASE_STRING(GR_RESOLUTION_512x384); + TRAP_CASE_STRING(GR_RESOLUTION_640x200); + TRAP_CASE_STRING(GR_RESOLUTION_640x350); + TRAP_CASE_STRING(GR_RESOLUTION_640x400); + TRAP_CASE_STRING(GR_RESOLUTION_640x480); + TRAP_CASE_STRING(GR_RESOLUTION_800x600); + TRAP_CASE_STRING(GR_RESOLUTION_960x720); + TRAP_CASE_STRING(GR_RESOLUTION_856x480); + TRAP_CASE_STRING(GR_RESOLUTION_512x256); + TRAP_CASE_STRING(GR_RESOLUTION_1024x768); + TRAP_CASE_STRING(GR_RESOLUTION_1280x1024); + TRAP_CASE_STRING(GR_RESOLUTION_1600x1200); + TRAP_CASE_STRING(GR_RESOLUTION_400x300); + TRAP_CASE_STRING(GR_RESOLUTION_1152x864); + TRAP_CASE_STRING(GR_RESOLUTION_1280x960); + TRAP_CASE_STRING(GR_RESOLUTION_1600x1024); + TRAP_CASE_STRING(GR_RESOLUTION_1792x1344); + TRAP_CASE_STRING(GR_RESOLUTION_1856x1392); + TRAP_CASE_STRING(GR_RESOLUTION_1920x1440); + TRAP_CASE_STRING(GR_RESOLUTION_2048x1536); + TRAP_CASE_STRING(GR_RESOLUTION_2048x2048); + TRAP_CASE_STRING(GR_RESOLUTION_NONE); + TRAP_NODEFAULT; + } +} + +const char *TRP_BLEND (GrAlphaBlendFnc_t func) +{ + switch (func) { + TRAP_CASE_STRING(GR_BLEND_ZERO); + TRAP_CASE_STRING(GR_BLEND_SRC_ALPHA); + TRAP_CASE_STRING(GR_BLEND_SRC_COLOR); + /*TRAP_CASE_STRING(GR_BLEND_DST_COLOR); ==GR_BLEND_SRC_COLOR*/ + TRAP_CASE_STRING(GR_BLEND_DST_ALPHA); + TRAP_CASE_STRING(GR_BLEND_ONE); + TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SRC_ALPHA); + TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SRC_COLOR); + /*TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_DST_COLOR); ==GR_BLEND_ONE_MINUS_SRC_COLOR*/ + TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_DST_ALPHA); + TRAP_CASE_STRING(GR_BLEND_SAME_COLOR_EXT); + /*TRAP_CASE_STRING(GR_BLEND_RESERVED_8); ==GR_BLEND_SAME_COLOR_EXT*/ + TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SAME_COLOR_EXT); + /*TRAP_CASE_STRING(GR_BLEND_RESERVED_9); ==GR_BLEND_ONE_MINUS_SAME_COLOR_EXT*/ + TRAP_CASE_STRING(GR_BLEND_RESERVED_A); + TRAP_CASE_STRING(GR_BLEND_RESERVED_B); + TRAP_CASE_STRING(GR_BLEND_RESERVED_C); + TRAP_CASE_STRING(GR_BLEND_RESERVED_D); + TRAP_CASE_STRING(GR_BLEND_RESERVED_E); + TRAP_CASE_STRING(GR_BLEND_ALPHA_SATURATE); + /*TRAP_CASE_STRING(GR_BLEND_PREFOG_COLOR); ==GR_BLEND_ALPHA_SATURATE*/ + TRAP_NODEFAULT; + } +} + +const char *TRP_CMBFUNC (GrCombineFunction_t cfunc) +{ + switch (cfunc) { + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_ZERO); + /*TRAP_CASE_STRING(GR_COMBINE_FUNCTION_NONE); ==GR_COMBINE_FUNCTION_ZERO*/ + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_LOCAL); + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_LOCAL_ALPHA); + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_SCALE_OTHER); + /*TRAP_CASE_STRING(GR_COMBINE_FUNCTION_BLEND_OTHER); ==GR_COMBINE_FUNCTION_SCALE_OTHER*/ + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL); + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA); + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL); + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL); + /*TRAP_CASE_STRING(GR_COMBINE_FUNCTION_BLEND); ==GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL*/ + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA); + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL); + /*TRAP_CASE_STRING(GR_COMBINE_FUNCTION_BLEND_LOCAL); ==GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL*/ + TRAP_CASE_STRING(GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA); + TRAP_NODEFAULT; + } +} + +const char *TRP_CMBFACT (GrCombineFactor_t cfactor) +{ + switch (cfactor) { + TRAP_CASE_STRING(GR_COMBINE_FACTOR_ZERO); + /*TRAP_CASE_STRING(GR_COMBINE_FACTOR_NONE); ==GR_COMBINE_FACTOR_ZERO*/ + TRAP_CASE_STRING(GR_COMBINE_FACTOR_LOCAL); + TRAP_CASE_STRING(GR_COMBINE_FACTOR_OTHER_ALPHA); + TRAP_CASE_STRING(GR_COMBINE_FACTOR_LOCAL_ALPHA); + TRAP_CASE_STRING(GR_COMBINE_FACTOR_TEXTURE_ALPHA); + TRAP_CASE_STRING(GR_COMBINE_FACTOR_TEXTURE_RGB); + /*TRAP_CASE_STRING(GR_COMBINE_FACTOR_DETAIL_FACTOR); ==GR_COMBINE_FACTOR_TEXTURE_ALPHA*/ + /*TRAP_CASE_STRING(GR_COMBINE_FACTOR_LOD_FRACTION); ==GR_COMBINE_FACTOR_TEXTURE_RGB ???*/ + TRAP_CASE_STRING(GR_COMBINE_FACTOR_ONE); + TRAP_CASE_STRING(GR_COMBINE_FACTOR_ONE_MINUS_LOCAL); + TRAP_CASE_STRING(GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA); + TRAP_CASE_STRING(GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA); + TRAP_CASE_STRING(GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA); + /*TRAP_CASE_STRING(GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR); ==GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA*/ + TRAP_CASE_STRING(GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION); + TRAP_NODEFAULT; + } +} + +const char *TRP_CMBLOCAL (GrCombineLocal_t clocal) +{ + switch (clocal) { + TRAP_CASE_STRING(GR_COMBINE_LOCAL_ITERATED); + TRAP_CASE_STRING(GR_COMBINE_LOCAL_CONSTANT); + /*TRAP_CASE_STRING(GR_COMBINE_LOCAL_NONE); ==GR_COMBINE_LOCAL_CONSTANT*/ + TRAP_CASE_STRING(GR_COMBINE_LOCAL_DEPTH); + TRAP_NODEFAULT; + } +} + +const char *TRP_CMBOTHER (GrCombineOther_t cother) +{ + switch (cother) { + TRAP_CASE_STRING(GR_COMBINE_OTHER_ITERATED); + TRAP_CASE_STRING(GR_COMBINE_OTHER_TEXTURE); + TRAP_CASE_STRING(GR_COMBINE_OTHER_CONSTANT); + /*TRAP_CASE_STRING(GR_COMBINE_OTHER_NONE); ==GR_COMBINE_OTHER_CONSTANT*/ + TRAP_NODEFAULT; + } +} + +const char *TRP_CMPFUNC (GrCmpFnc_t function) +{ + switch (function) { + TRAP_CASE_STRING(GR_CMP_NEVER); + TRAP_CASE_STRING(GR_CMP_LESS); + TRAP_CASE_STRING(GR_CMP_EQUAL); + TRAP_CASE_STRING(GR_CMP_LEQUAL); + TRAP_CASE_STRING(GR_CMP_GREATER); + TRAP_CASE_STRING(GR_CMP_NOTEQUAL); + TRAP_CASE_STRING(GR_CMP_GEQUAL); + TRAP_CASE_STRING(GR_CMP_ALWAYS); + TRAP_NODEFAULT; + } +} + +const char *TRP_CKMODE (GrChromakeyMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_CHROMAKEY_DISABLE); + TRAP_CASE_STRING(GR_CHROMAKEY_ENABLE); + TRAP_NODEFAULT; + } +} + +const char *TRP_CULLMODE (GrCullMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_CULL_DISABLE); + TRAP_CASE_STRING(GR_CULL_NEGATIVE); + TRAP_CASE_STRING(GR_CULL_POSITIVE); + TRAP_NODEFAULT; + } +} + +const char *TRP_DEPTHMODE (GrDepthBufferMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_DEPTHBUFFER_DISABLE); + TRAP_CASE_STRING(GR_DEPTHBUFFER_ZBUFFER); + TRAP_CASE_STRING(GR_DEPTHBUFFER_WBUFFER); + TRAP_CASE_STRING(GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS); + TRAP_CASE_STRING(GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS); + TRAP_NODEFAULT; + } +} + +const char *TRP_DITHERMODE (GrDitherMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_DITHER_DISABLE); + TRAP_CASE_STRING(GR_DITHER_2x2); + TRAP_CASE_STRING(GR_DITHER_4x4); + TRAP_NODEFAULT; + } +} + +const char *TRP_FOGMODE (GrFogMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_FOG_DISABLE); + TRAP_CASE_STRING(GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + TRAP_CASE_STRING(GR_FOG_WITH_TABLE_ON_Q); + /*TRAP_CASE_STRING(GR_FOG_WITH_TABLE_ON_W); ==GR_FOG_WITH_TABLE_ON_Q*/ + TRAP_CASE_STRING(GR_FOG_WITH_ITERATED_Z); + TRAP_CASE_STRING(GR_FOG_WITH_ITERATED_ALPHA_EXT); + TRAP_CASE_STRING(GR_FOG_MULT2); + TRAP_CASE_STRING(GR_FOG_ADD2); + TRAP_NODEFAULT; + } +} + +const char *TRP_GETNAME (FxU32 pname) +{ + switch (pname) { + TRAP_CASE_STRING(GR_BITS_DEPTH); + TRAP_CASE_STRING(GR_BITS_RGBA); + TRAP_CASE_STRING(GR_FIFO_FULLNESS); + TRAP_CASE_STRING(GR_FOG_TABLE_ENTRIES); + TRAP_CASE_STRING(GR_GAMMA_TABLE_ENTRIES); + TRAP_CASE_STRING(GR_GLIDE_STATE_SIZE); + TRAP_CASE_STRING(GR_GLIDE_VERTEXLAYOUT_SIZE); + TRAP_CASE_STRING(GR_IS_BUSY); + TRAP_CASE_STRING(GR_LFB_PIXEL_PIPE); + TRAP_CASE_STRING(GR_MAX_TEXTURE_SIZE); + TRAP_CASE_STRING(GR_MAX_TEXTURE_ASPECT_RATIO); + TRAP_CASE_STRING(GR_MEMORY_FB); + TRAP_CASE_STRING(GR_MEMORY_TMU); + TRAP_CASE_STRING(GR_MEMORY_UMA); + TRAP_CASE_STRING(GR_NUM_BOARDS); + TRAP_CASE_STRING(GR_NON_POWER_OF_TWO_TEXTURES); + TRAP_CASE_STRING(GR_NUM_FB); + TRAP_CASE_STRING(GR_NUM_SWAP_HISTORY_BUFFER); + TRAP_CASE_STRING(GR_NUM_TMU); + TRAP_CASE_STRING(GR_PENDING_BUFFERSWAPS); + TRAP_CASE_STRING(GR_REVISION_FB); + TRAP_CASE_STRING(GR_REVISION_TMU); + TRAP_CASE_STRING(GR_STATS_LINES); + TRAP_CASE_STRING(GR_STATS_PIXELS_AFUNC_FAIL); + TRAP_CASE_STRING(GR_STATS_PIXELS_CHROMA_FAIL); + TRAP_CASE_STRING(GR_STATS_PIXELS_DEPTHFUNC_FAIL); + TRAP_CASE_STRING(GR_STATS_PIXELS_IN); + TRAP_CASE_STRING(GR_STATS_PIXELS_OUT); + TRAP_CASE_STRING(GR_STATS_PIXELS); + TRAP_CASE_STRING(GR_STATS_POINTS); + TRAP_CASE_STRING(GR_STATS_TRIANGLES_IN); + TRAP_CASE_STRING(GR_STATS_TRIANGLES_OUT); + TRAP_CASE_STRING(GR_STATS_TRIANGLES); + TRAP_CASE_STRING(GR_SWAP_HISTORY); + TRAP_CASE_STRING(GR_SUPPORTS_PASSTHRU); + TRAP_CASE_STRING(GR_TEXTURE_ALIGN); + TRAP_CASE_STRING(GR_VIDEO_POSITION); + TRAP_CASE_STRING(GR_VIEWPORT); + TRAP_CASE_STRING(GR_WDEPTH_MIN_MAX); + TRAP_CASE_STRING(GR_ZDEPTH_MIN_MAX); + TRAP_CASE_STRING(GR_VERTEX_PARAMETER); + TRAP_CASE_STRING(GR_BITS_GAMMA); + TRAP_CASE_STRING(GR_GET_RESERVED_1); + TRAP_NODEFAULT; + } +} + +const char *TRP_GETSTRING (FxU32 pname) +{ + switch (pname) { + TRAP_CASE_STRING(GR_EXTENSION); + TRAP_CASE_STRING(GR_HARDWARE); + TRAP_CASE_STRING(GR_RENDERER); + TRAP_CASE_STRING(GR_VENDOR); + TRAP_CASE_STRING(GR_VERSION); + TRAP_NODEFAULT; + } +} + +const char *TRP_ENABLE (GrEnableMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_AA_ORDERED); + TRAP_CASE_STRING(GR_ALLOW_MIPMAP_DITHER); + TRAP_CASE_STRING(GR_PASSTHRU); + TRAP_CASE_STRING(GR_SHAMELESS_PLUG); + TRAP_CASE_STRING(GR_VIDEO_SMOOTHING); + TRAP_CASE_STRING(GR_TEXTURE_UMA_EXT); + TRAP_CASE_STRING(GR_STENCIL_MODE_EXT); + TRAP_CASE_STRING(GR_OPENGL_MODE_EXT); + TRAP_NODEFAULT; + } +} + +const char *TRP_COORD (GrCoordinateSpaceMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_WINDOW_COORDS); + TRAP_CASE_STRING(GR_CLIP_COORDS); + TRAP_NODEFAULT; + } +} + +const char *TRP_STIPPLEMODE (GrStippleMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_STIPPLE_DISABLE); + TRAP_CASE_STRING(GR_STIPPLE_PATTERN); + TRAP_CASE_STRING(GR_STIPPLE_ROTATE); + TRAP_NODEFAULT; + } +} + +const char *TRP_LODLEVEL (GrLOD_t lod) +{ + switch (lod) { + TRAP_CASE_STRING(GR_LOD_LOG2_2048); + TRAP_CASE_STRING(GR_LOD_LOG2_1024); + TRAP_CASE_STRING(GR_LOD_LOG2_512); + TRAP_CASE_STRING(GR_LOD_LOG2_256); + TRAP_CASE_STRING(GR_LOD_LOG2_128); + TRAP_CASE_STRING(GR_LOD_LOG2_64); + TRAP_CASE_STRING(GR_LOD_LOG2_32); + TRAP_CASE_STRING(GR_LOD_LOG2_16); + TRAP_CASE_STRING(GR_LOD_LOG2_8); + TRAP_CASE_STRING(GR_LOD_LOG2_4); + TRAP_CASE_STRING(GR_LOD_LOG2_2); + TRAP_CASE_STRING(GR_LOD_LOG2_1); + TRAP_NODEFAULT; + } +} + +const char *TRP_ASPECTRATIO (GrAspectRatio_t aspect) +{ + switch (aspect) { + TRAP_CASE_STRING(GR_ASPECT_LOG2_8x1); + TRAP_CASE_STRING(GR_ASPECT_LOG2_4x1); + TRAP_CASE_STRING(GR_ASPECT_LOG2_2x1); + TRAP_CASE_STRING(GR_ASPECT_LOG2_1x1); + TRAP_CASE_STRING(GR_ASPECT_LOG2_1x2); + TRAP_CASE_STRING(GR_ASPECT_LOG2_1x4); + TRAP_CASE_STRING(GR_ASPECT_LOG2_1x8); + TRAP_NODEFAULT; + } +} + +const char *TRP_TEXFMT (GrTextureFormat_t fmt) +{ + switch (fmt) { + TRAP_CASE_STRING(GR_TEXFMT_8BIT); + /*TRAP_CASE_STRING(GR_TEXFMT_RGB_332); ==GR_TEXFMT_8BIT*/ + TRAP_CASE_STRING(GR_TEXFMT_YIQ_422); + TRAP_CASE_STRING(GR_TEXFMT_ALPHA_8); + TRAP_CASE_STRING(GR_TEXFMT_INTENSITY_8); + TRAP_CASE_STRING(GR_TEXFMT_ALPHA_INTENSITY_44); + TRAP_CASE_STRING(GR_TEXFMT_P_8); + TRAP_CASE_STRING(GR_TEXFMT_RSVD0); + /*TRAP_CASE_STRING(GR_TEXFMT_P_8_6666); ==GR_TEXFMT_RSVD0*/ + /*TRAP_CASE_STRING(GR_TEXFMT_P_8_6666_EXT); ==GR_TEXFMT_RSVD0*/ + TRAP_CASE_STRING(GR_TEXFMT_RSVD1); + TRAP_CASE_STRING(GR_TEXFMT_16BIT); + /*TRAP_CASE_STRING(GR_TEXFMT_ARGB_8332); ==GR_TEXFMT_16BIT*/ + TRAP_CASE_STRING(GR_TEXFMT_AYIQ_8422); + TRAP_CASE_STRING(GR_TEXFMT_RGB_565); + TRAP_CASE_STRING(GR_TEXFMT_ARGB_1555); + TRAP_CASE_STRING(GR_TEXFMT_ARGB_4444); + TRAP_CASE_STRING(GR_TEXFMT_ALPHA_INTENSITY_88); + TRAP_CASE_STRING(GR_TEXFMT_AP_88); + TRAP_CASE_STRING(GR_TEXFMT_RSVD2); + /*TRAP_CASE_STRING(GR_TEXFMT_RSVD4); ==GR_TEXFMT_RSVD2*/ + TRAP_CASE_STRING(GR_TEXFMT_ARGB_CMP_FXT1); + TRAP_CASE_STRING(GR_TEXFMT_ARGB_8888); + TRAP_CASE_STRING(GR_TEXFMT_YUYV_422); + TRAP_CASE_STRING(GR_TEXFMT_UYVY_422); + TRAP_CASE_STRING(GR_TEXFMT_AYUV_444); + TRAP_CASE_STRING(GR_TEXFMT_ARGB_CMP_DXT1); + TRAP_CASE_STRING(GR_TEXFMT_ARGB_CMP_DXT2); + TRAP_CASE_STRING(GR_TEXFMT_ARGB_CMP_DXT3); + TRAP_CASE_STRING(GR_TEXFMT_ARGB_CMP_DXT4); + TRAP_CASE_STRING(GR_TEXFMT_ARGB_CMP_DXT5); + TRAP_CASE_STRING(GR_TEXTFMT_RGB_888); + TRAP_NODEFAULT; + } +} + +const char *TRP_EVENODD (FxU32 evenOdd) +{ + switch (evenOdd) { + TRAP_CASE_STRING(GR_MIPMAPLEVELMASK_EVEN); + TRAP_CASE_STRING(GR_MIPMAPLEVELMASK_ODD); + TRAP_CASE_STRING(GR_MIPMAPLEVELMASK_BOTH); + TRAP_NODEFAULT; + } +} + +const char *TRP_NCC (GrNCCTable_t table) +{ + switch (table) { + TRAP_CASE_STRING(GR_NCCTABLE_NCC0); + TRAP_CASE_STRING(GR_NCCTABLE_NCC1); + TRAP_NODEFAULT; + } +} + +const char *TRP_CLAMPMODE (GrTextureClampMode_t clampmode) +{ + switch (clampmode) { + TRAP_CASE_STRING(GR_TEXTURECLAMP_WRAP); + TRAP_CASE_STRING(GR_TEXTURECLAMP_CLAMP); + TRAP_CASE_STRING(GR_TEXTURECLAMP_MIRROR_EXT); + TRAP_NODEFAULT; + } +} + +const char *TRP_TEXFILTER (GrTextureFilterMode_t filter_mode) +{ + switch (filter_mode) { + TRAP_CASE_STRING(GR_TEXTUREFILTER_POINT_SAMPLED); + TRAP_CASE_STRING(GR_TEXTUREFILTER_BILINEAR); + TRAP_NODEFAULT; + } +} + +const char *TRP_TABLE (GrTexTable_t type) +{ + switch (type) { + TRAP_CASE_STRING(GR_TEXTABLE_NCC0); + TRAP_CASE_STRING(GR_TEXTABLE_NCC1); + TRAP_CASE_STRING(GR_TEXTABLE_PALETTE); + TRAP_CASE_STRING(GR_TEXTABLE_PALETTE_6666_EXT); + TRAP_NODEFAULT; + } +} + +const char *TRP_MIPMODE (GrMipMapMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_MIPMAP_DISABLE); + TRAP_CASE_STRING(GR_MIPMAP_NEAREST); + TRAP_CASE_STRING(GR_MIPMAP_NEAREST_DITHER); + TRAP_NODEFAULT; + } +} + +const char *TRP_TEXBASERANGE (GrTexBaseRange_t range) +{ + switch (range) { + TRAP_CASE_STRING(GR_TEXBASE_2048); + TRAP_CASE_STRING(GR_TEXBASE_1024); + TRAP_CASE_STRING(GR_TEXBASE_512); + TRAP_CASE_STRING(GR_TEXBASE_256_TO_1); + TRAP_CASE_STRING(GR_TEXBASE_256); + TRAP_CASE_STRING(GR_TEXBASE_128); + TRAP_CASE_STRING(GR_TEXBASE_64); + TRAP_CASE_STRING(GR_TEXBASE_32_TO_1); + TRAP_NODEFAULT; + } +} + +const char *TRP_LOCKTYPE (GrLock_t type) +{ + switch (type) { + TRAP_CASE_STRING(GR_LFB_READ_ONLY); + TRAP_CASE_STRING(GR_LFB_WRITE_ONLY); + /*TRAP_CASE_STRING(GR_LFB_IDLE); ==GR_LFB_READ_ONLY*/ + TRAP_CASE_STRING(GR_LFB_NOIDLE); + TRAP_CASE_STRING(GR_LFB_WRITE_ONLY_EXPLICIT_EXT); + TRAP_NODEFAULT; + } +} + +const char *TRP_WRITEMODE (GrLfbWriteMode_t writeMode) +{ + switch (writeMode) { + TRAP_CASE_STRING(GR_LFBWRITEMODE_565); + TRAP_CASE_STRING(GR_LFBWRITEMODE_555); + TRAP_CASE_STRING(GR_LFBWRITEMODE_1555); + TRAP_CASE_STRING(GR_LFBWRITEMODE_RESERVED1); + TRAP_CASE_STRING(GR_LFBWRITEMODE_888); + TRAP_CASE_STRING(GR_LFBWRITEMODE_8888); + TRAP_CASE_STRING(GR_LFBWRITEMODE_RESERVED2); + TRAP_CASE_STRING(GR_LFBWRITEMODE_RESERVED3); + TRAP_CASE_STRING(GR_LFBWRITEMODE_Z32); + TRAP_CASE_STRING(GR_LFBWRITEMODE_RESERVED5); + TRAP_CASE_STRING(GR_LFBWRITEMODE_RESERVED6); + TRAP_CASE_STRING(GR_LFBWRITEMODE_RESERVED7); + TRAP_CASE_STRING(GR_LFBWRITEMODE_565_DEPTH); + TRAP_CASE_STRING(GR_LFBWRITEMODE_555_DEPTH); + TRAP_CASE_STRING(GR_LFBWRITEMODE_1555_DEPTH); + TRAP_CASE_STRING(GR_LFBWRITEMODE_ZA16); + TRAP_CASE_STRING(GR_LFBWRITEMODE_ANY); + TRAP_NODEFAULT; + } +} + +const char *TRP_SRCFMT (GrLfbSrcFmt_t src_format) +{ + switch (src_format) { + TRAP_CASE_STRING(GR_LFB_SRC_FMT_565); + TRAP_CASE_STRING(GR_LFB_SRC_FMT_555); + TRAP_CASE_STRING(GR_LFB_SRC_FMT_1555); + TRAP_CASE_STRING(GR_LFB_SRC_FMT_888); + TRAP_CASE_STRING(GR_LFB_SRC_FMT_8888); + TRAP_CASE_STRING(GR_LFB_SRC_FMT_565_DEPTH); + TRAP_CASE_STRING(GR_LFB_SRC_FMT_555_DEPTH); + TRAP_CASE_STRING(GR_LFB_SRC_FMT_1555_DEPTH); + TRAP_CASE_STRING(GR_LFB_SRC_FMT_ZA16); + TRAP_CASE_STRING(GR_LFB_SRC_FMT_RLE16); + TRAP_CASE_STRING(GR_LFBWRITEMODE_Z32); /*???*/ + TRAP_NODEFAULT; + } +} + +const char *TRP_CRMODE (GrChromaRangeMode_t mode) +{ + switch (mode) { + TRAP_CASE_STRING(GR_CHROMARANGE_DISABLE_EXT); + /*TRAP_CASE_STRING(GR_CHROMARANGE_RGB_ALL_EXT); ==GR_CHROMARANGE_DISABLE_EXT*/ + TRAP_CASE_STRING(GR_CHROMARANGE_ENABLE_EXT); + TRAP_NODEFAULT; + } +} + +const char *TRP_PIXFMT (GrPixelFormat_t pixelformat) +{ + switch (pixelformat) { + TRAP_CASE_STRING(GR_PIXFMT_I_8); + TRAP_CASE_STRING(GR_PIXFMT_AI_88); + TRAP_CASE_STRING(GR_PIXFMT_RGB_565); + TRAP_CASE_STRING(GR_PIXFMT_ARGB_1555); + TRAP_CASE_STRING(GR_PIXFMT_ARGB_8888); + TRAP_CASE_STRING(GR_PIXFMT_AA_2_RGB_565); + TRAP_CASE_STRING(GR_PIXFMT_AA_2_ARGB_1555); + TRAP_CASE_STRING(GR_PIXFMT_AA_2_ARGB_8888); + TRAP_CASE_STRING(GR_PIXFMT_AA_4_RGB_565); + TRAP_CASE_STRING(GR_PIXFMT_AA_4_ARGB_1555); + TRAP_CASE_STRING(GR_PIXFMT_AA_4_ARGB_8888); + TRAP_CASE_STRING(GR_PIXFMT_AA_8_RGB_565); + TRAP_CASE_STRING(GR_PIXFMT_AA_8_ARGB_1555); + TRAP_CASE_STRING(GR_PIXFMT_AA_8_ARGB_8888); + TRAP_NODEFAULT; + } +} + +const char *TRP_STENCILOP (GrStencilOp_t op) +{ + switch (op) { + TRAP_CASE_STRING(GR_STENCILOP_KEEP); + TRAP_CASE_STRING(GR_STENCILOP_ZERO); + TRAP_CASE_STRING(GR_STENCILOP_REPLACE); + TRAP_CASE_STRING(GR_STENCILOP_INCR_CLAMP); + TRAP_CASE_STRING(GR_STENCILOP_DECR_CLAMP); + TRAP_CASE_STRING(GR_STENCILOP_INVERT); + TRAP_CASE_STRING(GR_STENCILOP_INCR_WRAP); + TRAP_CASE_STRING(GR_STENCILOP_DECR_WRAP); + TRAP_NODEFAULT; + } +} + +const char *TRP_BLENDOP (GrAlphaBlendOp_t op) +{ + switch (op) { + TRAP_CASE_STRING(GR_BLEND_OP_ADD); + TRAP_CASE_STRING(GR_BLEND_OP_SUB); + TRAP_CASE_STRING(GR_BLEND_OP_REVSUB); + TRAP_NODEFAULT; + } +} + +const char *TRP_CU (GrCCUColor_t a) +{ + switch (a) { + TRAP_CASE_STRING(GR_CMBX_ZERO); + TRAP_CASE_STRING(GR_CMBX_TEXTURE_ALPHA); + TRAP_CASE_STRING(GR_CMBX_ALOCAL); + TRAP_CASE_STRING(GR_CMBX_AOTHER); + TRAP_CASE_STRING(GR_CMBX_B); + TRAP_CASE_STRING(GR_CMBX_CONSTANT_ALPHA); + TRAP_CASE_STRING(GR_CMBX_CONSTANT_COLOR); + TRAP_CASE_STRING(GR_CMBX_DETAIL_FACTOR); + TRAP_CASE_STRING(GR_CMBX_ITALPHA); + TRAP_CASE_STRING(GR_CMBX_ITRGB); + TRAP_CASE_STRING(GR_CMBX_LOCAL_TEXTURE_ALPHA); + TRAP_CASE_STRING(GR_CMBX_LOCAL_TEXTURE_RGB); + TRAP_CASE_STRING(GR_CMBX_LOD_FRAC); + TRAP_CASE_STRING(GR_CMBX_OTHER_TEXTURE_ALPHA); + TRAP_CASE_STRING(GR_CMBX_OTHER_TEXTURE_RGB); + TRAP_CASE_STRING(GR_CMBX_TEXTURE_RGB); + TRAP_CASE_STRING(GR_CMBX_TMU_CALPHA); + TRAP_CASE_STRING(GR_CMBX_TMU_CCOLOR); + TRAP_NODEFAULT; + } +} + +const char *TRP_CMBMODE (GrCombineMode_t a_mode) +{ + switch (a_mode) { + TRAP_CASE_STRING(GR_FUNC_MODE_ZERO); + TRAP_CASE_STRING(GR_FUNC_MODE_X); + TRAP_CASE_STRING(GR_FUNC_MODE_ONE_MINUS_X); + TRAP_CASE_STRING(GR_FUNC_MODE_NEGATIVE_X); + TRAP_CASE_STRING(GR_FUNC_MODE_X_MINUS_HALF); + TRAP_NODEFAULT; + } +} + +const char *TRP_TMU (GrChipID_t tmu) +{ + switch (tmu) { + TRAP_CASE_STRING(GR_TMU0); + TRAP_CASE_STRING(GR_TMU1); + TRAP_NODEFAULT; + } +} + +const char *TRP_TXDITHER (FxU32 dither) +{ + switch (dither) { + TRAP_CASE_STRING(TX_DITHER_NONE); + TRAP_CASE_STRING(TX_DITHER_4x4); + TRAP_CASE_STRING(TX_DITHER_ERR); + TRAP_NODEFAULT; + } +} + +const char *TRP_TXCOMPRESS (FxU32 compress) +{ + switch (compress) { + TRAP_CASE_STRING(TX_COMPRESSION_STATISTICAL); + TRAP_CASE_STRING(TX_COMPRESSION_HEURISTIC); + TRAP_NODEFAULT; + } +} + + + +/****************************************************************************\ +* REAL POINTERS * +\****************************************************************************/ + +/* +** glide extensions +*/ +void (FX_CALL *real_grSetNumPendingBuffers) (FxI32 NumPendingBuffers); +char * (FX_CALL *real_grGetRegistryOrEnvironmentStringExt) (char *theEntry); +void (FX_CALL *real_grGetGammaTableExt) (FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue); +void (FX_CALL *real_grChromaRangeModeExt) (GrChromakeyMode_t mode); +void (FX_CALL *real_grChromaRangeExt) (GrColor_t color, GrColor_t range, GrChromaRangeMode_t match_mode); +void (FX_CALL *real_grTexChromaModeExt) (GrChipID_t tmu, GrChromakeyMode_t mode); +void (FX_CALL *real_grTexChromaRangeExt) (GrChipID_t tmu, GrColor_t min, GrColor_t max, GrTexChromakeyMode_t mode); + +/* pointcast */ +void (FX_CALL *real_grTexDownloadTableExt) (GrChipID_t tmu, GrTexTable_t type, void *data); +void (FX_CALL *real_grTexDownloadTablePartialExt) (GrChipID_t tmu, GrTexTable_t type, void *data, int start, int end); +void (FX_CALL *real_grTexNCCTableExt) (GrChipID_t tmu, GrNCCTable_t table); + +/* tbext */ +void (FX_CALL *real_grTextureBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask); +void (FX_CALL *real_grTextureAuxBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask); +void (FX_CALL *real_grAuxBufferExt) (GrBuffer_t buffer); + +/* napalm */ +GrContext_t (FX_CALL *real_grSstWinOpenExt) (FxU32 hWnd, GrScreenResolution_t resolution, GrScreenRefresh_t refresh, GrColorFormat_t format, GrOriginLocation_t origin, GrPixelFormat_t pixelformat, int nColBuffers, int nAuxBuffers); +void (FX_CALL *real_grStencilFuncExt) (GrCmpFnc_t fnc, GrStencil_t ref, GrStencil_t mask); +void (FX_CALL *real_grStencilMaskExt) (GrStencil_t value); +void (FX_CALL *real_grStencilOpExt) (GrStencilOp_t stencil_fail, GrStencilOp_t depth_fail, GrStencilOp_t depth_pass); +void (FX_CALL *real_grLfbConstantStencilExt) (GrStencil_t value); +void (FX_CALL *real_grBufferClearExt) (GrColor_t color, GrAlpha_t alpha, FxU32 depth, GrStencil_t stencil); +void (FX_CALL *real_grColorCombineExt) (GrCCUColor_t a, GrCombineMode_t a_mode, GrCCUColor_t b, GrCombineMode_t b_mode, GrCCUColor_t c, FxBool c_invert, GrCCUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); +void (FX_CALL *real_grAlphaCombineExt) (GrACUColor_t a, GrCombineMode_t a_mode, GrACUColor_t b, GrCombineMode_t b_mode, GrACUColor_t c, FxBool c_invert, GrACUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); +void (FX_CALL *real_grTexColorCombineExt) (GrChipID_t tmu, GrTCCUColor_t a, GrCombineMode_t a_mode, GrTCCUColor_t b, GrCombineMode_t b_mode, GrTCCUColor_t c, FxBool c_invert, GrTCCUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); +void (FX_CALL *real_grTexAlphaCombineExt) (GrChipID_t tmu, GrTACUColor_t a, GrCombineMode_t a_mode, GrTACUColor_t b, GrCombineMode_t b_mode, GrTACUColor_t c, FxBool c_invert, GrTACUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); +void (FX_CALL *real_grConstantColorValueExt) (GrChipID_t tmu, GrColor_t value); +void (FX_CALL *real_grColorMaskExt) (FxBool r, FxBool g, FxBool b, FxBool a); +void (FX_CALL *real_grAlphaBlendFunctionExt) (GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendOp_t rgb_op, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df, GrAlphaBlendOp_t alpha_op); +void (FX_CALL *real_grTBufferWriteMaskExt) (FxU32 tmask); + +/* +** texus +*/ +void (FX_CALL *real_txImgQuantize) (char *dst, char *src, int w, int h, FxU32 format, FxU32 dither); +void (FX_CALL *real_txMipQuantize) (TxMip *pxMip, TxMip *txMip, int fmt, FxU32 d, FxU32 comp); +void (FX_CALL *real_txPalToNcc) (GuNccTable *ncc_table, const FxU32 *pal); + + + +/****************************************************************************\ +* DEBUG HOOKS * +\****************************************************************************/ + +/* +** rendering functions +*/ +void FX_CALL trap_grDrawPoint (const void *pt) +{ +#define FN_NAME "grDrawPoint" + TRAP_LOG("%s(%p)\n", FN_NAME, pt); + grDrawPoint(pt); +#undef FN_NAME +} + +void FX_CALL trap_grDrawLine (const void *v1, + const void *v2) +{ +#define FN_NAME "grDrawLine" + TRAP_LOG("%s(%p, %p)\n", FN_NAME, v1, v2); + grDrawLine(v1, v2); +#undef FN_NAME +} + +void FX_CALL trap_grDrawTriangle (const void *a, + const void *b, + const void *c) +{ +#define FN_NAME "grDrawTriangle" + TRAP_LOG("%s(%p, %p, %p)\n", FN_NAME, a, b, c); + grDrawTriangle(a, b, c); +#undef FN_NAME +} + +void FX_CALL trap_grVertexLayout (FxU32 param, + FxI32 offset, + FxU32 mode) +{ +#define FN_NAME "grVertexLayout" + TRAP_LOG("%s(%s, %ld, %s)\n", FN_NAME, TRP_VTX(param), offset, TRP_PARAM(mode)); + grVertexLayout(param, offset, mode); +#undef FN_NAME +} + +void FX_CALL trap_grDrawVertexArray (FxU32 mode, + FxU32 Count, + void *pointers) +{ +#define FN_NAME "grDrawVertexArray" + TRAP_LOG("%s(%s, %lu, %p)\n", FN_NAME, TRP_ARRAY(mode), Count, pointers); + grDrawVertexArray(mode, Count, pointers); +#undef FN_NAME +} + +void FX_CALL trap_grDrawVertexArrayContiguous (FxU32 mode, + FxU32 Count, + void *pointers, + FxU32 stride) +{ +#define FN_NAME "grDrawVertexArrayContiguous" + TRAP_LOG("%s(%s, %lu, %p, %lu)\n", FN_NAME, TRP_ARRAY(mode), Count, pointers, stride); + grDrawVertexArrayContiguous(mode, Count, pointers, stride); +#undef FN_NAME +} + +/* +** Antialiasing Functions +*/ +void FX_CALL trap_grAADrawTriangle (const void *a, + const void *b, + const void *c, + FxBool ab_antialias, + FxBool bc_antialias, + FxBool ca_antialias) +{ +#define FN_NAME "grAADrawTriangle" + TRAP_LOG("%s(%p, %p, %p, %s, %s, %s)\n", FN_NAME, a, b, c, TRP_BOOL(ab_antialias), TRP_BOOL(bc_antialias), TRP_BOOL(ca_antialias)); + grAADrawTriangle(a, b, c, ab_antialias, bc_antialias, ca_antialias); +#undef FN_NAME +} + +/* +** buffer management +*/ +void FX_CALL trap_grBufferClear (GrColor_t color, + GrAlpha_t alpha, + FxU32 depth) +{ +#define FN_NAME "grBufferClear" + TRAP_LOG("%s(%08lx, %02x, %08lx)\n", FN_NAME, color, alpha, depth); + grBufferClear(color, alpha, depth); +#undef FN_NAME +} + +void FX_CALL trap_grBufferSwap (FxU32 swap_interval) +{ +#define FN_NAME "grBufferSwap" + TRAP_LOG("%s(%lu)\n", FN_NAME, swap_interval); + grBufferSwap(swap_interval); +#undef FN_NAME +} + +void FX_CALL trap_grRenderBuffer (GrBuffer_t buffer) +{ +#define FN_NAME "grRenderBuffer" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_BUFFER(buffer)); + grRenderBuffer(buffer); +#undef FN_NAME +} + +/* +** error management +*/ +void FX_CALL trap_grErrorSetCallback (GrErrorCallbackFnc_t fnc) +{ +#define FN_NAME "grErrorSetCallback" + TRAP_LOG("%s(%p)\n", FN_NAME, (void *)fnc); + grErrorSetCallback(fnc); +#undef FN_NAME +} + +/* +** SST routines +*/ +void FX_CALL trap_grFinish (void) +{ +#define FN_NAME "grFinish" + TRAP_LOG("%s()\n", FN_NAME); + grFinish(); +#undef FN_NAME +} + +void FX_CALL trap_grFlush (void) +{ +#define FN_NAME "grFlush" + TRAP_LOG("%s()\n", FN_NAME); + grFlush(); +#undef FN_NAME +} + +GrContext_t FX_CALL trap_grSstWinOpen (FxU32 hWnd, + GrScreenResolution_t screen_resolution, + GrScreenRefresh_t refresh_rate, + GrColorFormat_t color_format, + GrOriginLocation_t origin_location, + int nColBuffers, + int nAuxBuffers) +{ +#define FN_NAME "grSstWinOpen" + GrContext_t rv; + TRAP_LOG("%s(%08lx, %s, %s, %s, %s, %d, %d)\n", FN_NAME, hWnd, TRP_RESOLUTION(screen_resolution), TRP_REFRESH(refresh_rate), TRP_COLFMT(color_format), TRP_ORIGIN(origin_location), nColBuffers, nAuxBuffers); + rv = grSstWinOpen(hWnd, screen_resolution, refresh_rate, color_format, origin_location, nColBuffers, nAuxBuffers); + TRAP_LOG(GOT "%p\n", (void *)rv); + return rv; +#undef FN_NAME +} + +FxBool FX_CALL trap_grSstWinClose (GrContext_t context) +{ +#define FN_NAME "grSstWinClose" + FxBool rv; + TRAP_LOG("%s(%p)\n", FN_NAME, (void *)context); + rv = grSstWinClose(context); + TRAP_LOG(GOT "%s\n", TRP_BOOL(rv)); + return rv; +#undef FN_NAME +} + +FxBool FX_CALL trap_grSelectContext (GrContext_t context) +{ +#define FN_NAME "grSelectContext" + FxBool rv; + TRAP_LOG("%s(%p)\n", FN_NAME, (void *)context); + rv = grSelectContext(context); + TRAP_LOG(GOT "%s\n", TRP_BOOL(rv)); + return rv; +#undef FN_NAME +} + +void FX_CALL trap_grSstOrigin (GrOriginLocation_t origin) +{ +#define FN_NAME "grSstOrigin" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_ORIGIN(origin)); + grSstOrigin(origin); +#undef FN_NAME +} + +void FX_CALL trap_grSstSelect (int which_sst) +{ +#define FN_NAME "grSstSelect" + TRAP_LOG("%s(%d)\n", FN_NAME, which_sst); + grSstSelect(which_sst); +#undef FN_NAME +} + +/* +** Glide configuration and special effect maintenance functions +*/ +void FX_CALL trap_grAlphaBlendFunction (GrAlphaBlendFnc_t rgb_sf, + GrAlphaBlendFnc_t rgb_df, + GrAlphaBlendFnc_t alpha_sf, + GrAlphaBlendFnc_t alpha_df) +{ +#define FN_NAME "grAlphaBlendFunction" + TRAP_LOG("%s(%s, %s, %s, %s)\n", FN_NAME, TRP_BLEND(rgb_sf), TRP_BLEND(rgb_df), TRP_BLEND(alpha_sf), TRP_BLEND(alpha_df)); + grAlphaBlendFunction(rgb_sf, rgb_df, alpha_sf, alpha_df); +#undef FN_NAME +} + +void FX_CALL trap_grAlphaCombine (GrCombineFunction_t function, + GrCombineFactor_t factor, + GrCombineLocal_t local, + GrCombineOther_t other, + FxBool invert) +{ +#define FN_NAME "grAlphaCombine" + TRAP_LOG("%s(%s, %s, %s, %s, %s)\n", FN_NAME, TRP_CMBFUNC(function), TRP_CMBFACT(factor), TRP_CMBLOCAL(local), TRP_CMBOTHER(other), TRP_BOOL(invert)); + grAlphaCombine(function, factor, local, other, invert); +#undef FN_NAME +} + +void FX_CALL trap_grAlphaControlsITRGBLighting (FxBool enable) +{ +#define FN_NAME "grAlphaControlsITRGBLighting" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_BOOL(enable)); + grAlphaControlsITRGBLighting(enable); +#undef FN_NAME +} + +void FX_CALL trap_grAlphaTestFunction (GrCmpFnc_t function) +{ +#define FN_NAME "grAlphaTestFunction" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_CMPFUNC(function)); + grAlphaTestFunction(function); +#undef FN_NAME +} + +void FX_CALL trap_grAlphaTestReferenceValue (GrAlpha_t value) +{ +#define FN_NAME "grAlphaTestReferenceValue" + TRAP_LOG("%s(%02x)\n", FN_NAME, value); + grAlphaTestReferenceValue(value); +#undef FN_NAME +} + +void FX_CALL trap_grChromakeyMode (GrChromakeyMode_t mode) +{ +#define FN_NAME "grChromakeyMode" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_CKMODE(mode)); + grChromakeyMode(mode); +#undef FN_NAME +} + +void FX_CALL trap_grChromakeyValue (GrColor_t value) +{ +#define FN_NAME "grChromakeyValue" + TRAP_LOG("%s(%08lx)\n", FN_NAME, value); + grChromakeyValue(value); +#undef FN_NAME +} + +void FX_CALL trap_grClipWindow (FxU32 minx, + FxU32 miny, + FxU32 maxx, + FxU32 maxy) +{ +#define FN_NAME "grClipWindow" + TRAP_LOG("%s(%lu, %lu, %lu, %lu)\n", FN_NAME, minx, miny, maxx, maxy); + grClipWindow(minx, miny, maxx, maxy); +#undef FN_NAME +} + +void FX_CALL trap_grColorCombine (GrCombineFunction_t function, + GrCombineFactor_t factor, + GrCombineLocal_t local, + GrCombineOther_t other, + FxBool invert) +{ +#define FN_NAME "grColorCombine" + TRAP_LOG("%s(%s, %s, %s, %s, %s)\n", FN_NAME, TRP_CMBFUNC(function), TRP_CMBFACT(factor), TRP_CMBLOCAL(local), TRP_CMBOTHER(other), TRP_BOOL(invert)); + grColorCombine(function, factor, local, other, invert); +#undef FN_NAME +} + +void FX_CALL trap_grColorMask (FxBool rgb, + FxBool a) +{ +#define FN_NAME "grColorMask" + TRAP_LOG("%s(%s, %s)\n", FN_NAME, TRP_BOOL(rgb), TRP_BOOL(a)); + grColorMask(rgb, a); +#undef FN_NAME +} + +void FX_CALL trap_grCullMode (GrCullMode_t mode) +{ +#define FN_NAME "grCullMode" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_CULLMODE(mode)); + grCullMode(mode); +#undef FN_NAME +} + +void FX_CALL trap_grConstantColorValue (GrColor_t value) +{ +#define FN_NAME "grConstantColorValue" + TRAP_LOG("%s(%08lx)\n", FN_NAME, value); + grConstantColorValue(value); +#undef FN_NAME +} + +void FX_CALL trap_grDepthBiasLevel (FxI32 level) +{ +#define FN_NAME "grDepthBiasLevel" + TRAP_LOG("%s(%ld)\n", FN_NAME, level); + grDepthBiasLevel(level); +#undef FN_NAME +} + +void FX_CALL trap_grDepthBufferFunction (GrCmpFnc_t function) +{ +#define FN_NAME "grDepthBufferFunction" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_CMPFUNC(function)); + grDepthBufferFunction(function); +#undef FN_NAME +} + +void FX_CALL trap_grDepthBufferMode (GrDepthBufferMode_t mode) +{ +#define FN_NAME "grDepthBufferMode" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_DEPTHMODE(mode)); + grDepthBufferMode(mode); +#undef FN_NAME +} + +void FX_CALL trap_grDepthMask (FxBool mask) +{ +#define FN_NAME "grDepthMask" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_BOOL(mask)); + grDepthMask(mask); +#undef FN_NAME +} + +void FX_CALL trap_grDisableAllEffects (void) +{ +#define FN_NAME "grDisableAllEffects" + TRAP_LOG("%s()\n", FN_NAME); + grDisableAllEffects(); +#undef FN_NAME +} + +void FX_CALL trap_grDitherMode (GrDitherMode_t mode) +{ +#define FN_NAME "grDitherMode" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_DITHERMODE(mode)); + grDitherMode(mode); +#undef FN_NAME +} + +void FX_CALL trap_grFogColorValue (GrColor_t fogcolor) +{ +#define FN_NAME "grFogColorValue" + TRAP_LOG("%s(%08lx)\n", FN_NAME, fogcolor); + grFogColorValue(fogcolor); +#undef FN_NAME +} + +void FX_CALL trap_grFogMode (GrFogMode_t mode) +{ +#define FN_NAME "grFogMode" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_FOGMODE(mode)); + grFogMode(mode); +#undef FN_NAME +} + +void FX_CALL trap_grFogTable (const GrFog_t ft[]) +{ +#define FN_NAME "grFogTable" + TRAP_LOG("%s(%p)\n", FN_NAME, ft); + grFogTable(ft); +#undef FN_NAME +} + +void FX_CALL trap_grLoadGammaTable (FxU32 nentries, + FxU32 *red, + FxU32 *green, + FxU32 *blue) +{ +#define FN_NAME "grLoadGammaTable" + TRAP_LOG("%s(%lu, %p, %p, %p)\n", FN_NAME, nentries, (void *)red, (void *)green, (void *)blue); + grLoadGammaTable(nentries, red, green, blue); +#undef FN_NAME +} + +void FX_CALL trap_grSplash (float x, + float y, + float width, + float height, + FxU32 frame) +{ +#define FN_NAME "grSplash" + TRAP_LOG("%s(%f, %f, %f, %f, %lu)\n", FN_NAME, x, y, width, height, frame); + grSplash(x, y, width, height, frame); +#undef FN_NAME +} + +FxU32 FX_CALL trap_grGet (FxU32 pname, + FxU32 plength, + FxI32 *params) +{ +#define FN_NAME "grGet" + FxU32 rv, i; + TRAP_LOG("%s(%s, %lu, %p)\n", FN_NAME, TRP_GETNAME(pname), plength, (void *)params); + rv = grGet(pname, plength, params); + TRAP_LOG(GOT "["); + for (i = 0; i < (rv/sizeof(FxI32)); i++) { + TRAP_LOG("%s%ld", i ? ", " : "", params[i]); + } + TRAP_LOG("]\n"); + return rv; +#undef FN_NAME +} + +const char *FX_CALL trap_grGetString (FxU32 pname) +{ +#define FN_NAME "grGetString" + const char *rv; + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_GETSTRING(pname)); + rv = grGetString(pname); + if (rv) { + TRAP_LOG(GOT "\"%s\"\n", rv); + } else { + TRAP_LOG(GOT "NULL\n"); + } + return rv; +#undef FN_NAME +} + +FxI32 FX_CALL trap_grQueryResolutions (const GrResolution *resTemplate, + GrResolution *output) +{ +#define FN_NAME "grQueryResolutions" + FxI32 rv; + TRAP_LOG("%s(%p, %p)\n", FN_NAME, (void *)resTemplate, (void *)output); + rv = grQueryResolutions(resTemplate, output); + TRAP_LOG(GOT "%ld\n", rv); + return rv; +#undef FN_NAME +} + +FxBool FX_CALL trap_grReset (FxU32 what) +{ +#define FN_NAME "grReset" + FxBool rv; + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_GETNAME(what)); + rv = grReset(what); + TRAP_LOG(GOT "%s\n", TRP_BOOL(rv)); + return rv; +#undef FN_NAME +} + +GrProc FX_CALL trap_grGetProcAddress (char *procName) +{ +#define FN_NAME "grGetProcAddress" + GrProc rv; + TRAP_LOG("%s(%s)\n", FN_NAME, procName); + rv = grGetProcAddress(procName); + TRAP_LOG(GOT "%p\n", (void *)rv); + return rv; +#undef FN_NAME +} + +void FX_CALL trap_grEnable (GrEnableMode_t mode) +{ +#define FN_NAME "grEnable" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_ENABLE(mode)); + grEnable(mode); +#undef FN_NAME +} + +void FX_CALL trap_grDisable (GrEnableMode_t mode) +{ +#define FN_NAME "grDisable" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_ENABLE(mode)); + grDisable(mode); +#undef FN_NAME +} + +void FX_CALL trap_grCoordinateSpace (GrCoordinateSpaceMode_t mode) +{ +#define FN_NAME "grCoordinateSpace" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_COORD(mode)); + grCoordinateSpace(mode); +#undef FN_NAME +} + +void FX_CALL trap_grDepthRange (FxFloat n, + FxFloat f) +{ +#define FN_NAME "grDepthRange" + TRAP_LOG("%s(%f, %f)\n", FN_NAME, n, f); + grDepthRange(n, f); +#undef FN_NAME +} + +void FX_CALL trap_grStippleMode (GrStippleMode_t mode) +{ +#define FN_NAME "grStippleMode" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_STIPPLEMODE(mode)); + grStippleMode(mode); /* some Glide libs don't have it; not used anyway */ +#undef FN_NAME +} + +void FX_CALL trap_grStipplePattern (GrStipplePattern_t mode) +{ +#define FN_NAME "grStipplePattern" + TRAP_LOG("%s(%08lx)\n", FN_NAME, mode); + grStipplePattern(mode); /* some Glide libs don't have it; not used anyway */ +#undef FN_NAME +} + +void FX_CALL trap_grViewport (FxI32 x, + FxI32 y, + FxI32 width, + FxI32 height) +{ +#define FN_NAME "grViewport" + TRAP_LOG("%s(%ld, %ld, %ld, %ld)\n", FN_NAME, x, y, width, height); + grViewport(x, y, width, height); +#undef FN_NAME +} + +/* +** texture mapping control functions +*/ +FxU32 FX_CALL trap_grTexCalcMemRequired (GrLOD_t lodmin, + GrLOD_t lodmax, + GrAspectRatio_t aspect, + GrTextureFormat_t fmt) +{ +#define FN_NAME "grTexCalcMemRequired" + FxU32 rv; + TRAP_LOG("%s(%s, %s, %s, %s)\n", FN_NAME, TRP_LODLEVEL(lodmin), TRP_LODLEVEL(lodmax), TRP_ASPECTRATIO(aspect), TRP_TEXFMT(fmt)); + rv = grTexCalcMemRequired(lodmin, lodmax, aspect, fmt); + TRAP_LOG(GOT "%lu\n", rv); + return rv; +#undef FN_NAME +} + +FxU32 FX_CALL trap_grTexTextureMemRequired (FxU32 evenOdd, + GrTexInfo *info) +{ +#define FN_NAME "grTexTextureMemRequired" + FxU32 rv; + TRAP_LOG("%s(%s, %p)\n", FN_NAME, TRP_EVENODD(evenOdd), (void *)info); + rv = grTexTextureMemRequired(evenOdd, info); + TRAP_LOG(GOT "%lu\n", rv); + return rv; +#undef FN_NAME +} + +FxU32 FX_CALL trap_grTexMinAddress (GrChipID_t tmu) +{ +#define FN_NAME "grTexMinAddress" + FxU32 rv; + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_TMU(tmu)); + rv = grTexMinAddress(tmu); + TRAP_LOG(GOT "%lu\n", rv); + return rv; +#undef FN_NAME +} + +FxU32 FX_CALL trap_grTexMaxAddress (GrChipID_t tmu) +{ +#define FN_NAME "grTexMaxAddress" + FxU32 rv; + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_TMU(tmu)); + rv = grTexMaxAddress(tmu); + TRAP_LOG(GOT "%lu\n", rv); + return rv; +#undef FN_NAME +} + +void FX_CALL trap_grTexNCCTable (GrNCCTable_t table) +{ +#define FN_NAME "grTexNCCTable" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_NCC(table)); + grTexNCCTable(table); +#undef FN_NAME +} + +void FX_CALL trap_grTexSource (GrChipID_t tmu, + FxU32 startAddress, + FxU32 evenOdd, + GrTexInfo *info) +{ +#define FN_NAME "grTexSource" + TRAP_LOG("%s(%s, %08lx, %s, %p)\n", FN_NAME, TRP_TMU(tmu), startAddress, TRP_EVENODD(evenOdd), (void *)info); + grTexSource(tmu, startAddress, evenOdd, info); +#undef FN_NAME +} + +void FX_CALL trap_grTexClampMode (GrChipID_t tmu, + GrTextureClampMode_t s_clampmode, + GrTextureClampMode_t t_clampmode) +{ +#define FN_NAME "grTexClampMode" + TRAP_LOG("%s(%s, %s, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_CLAMPMODE(s_clampmode), TRP_CLAMPMODE(t_clampmode)); + grTexClampMode(tmu, s_clampmode, t_clampmode); +#undef FN_NAME +} + +void FX_CALL trap_grTexCombine (GrChipID_t tmu, + GrCombineFunction_t rgb_function, + GrCombineFactor_t rgb_factor, + GrCombineFunction_t alpha_function, + GrCombineFactor_t alpha_factor, + FxBool rgb_invert, + FxBool alpha_invert) +{ +#define FN_NAME "grTexCombine" + TRAP_LOG("%s(%s, %s, %s, %s, %s, %s, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_CMBFUNC(rgb_function), TRP_CMBFACT(rgb_factor), TRP_CMBFUNC(alpha_function), TRP_CMBFACT(alpha_factor), TRP_BOOL(rgb_invert), TRP_BOOL(alpha_invert)); + grTexCombine(tmu, rgb_function, rgb_factor, alpha_function, alpha_factor, rgb_invert, alpha_invert); +#undef FN_NAME +} + +void FX_CALL trap_grTexDetailControl (GrChipID_t tmu, + int lod_bias, + FxU8 detail_scale, + float detail_max) +{ +#define FN_NAME "grTexDetailControl" + TRAP_LOG("%s(%s, %u, %d, %f)\n", FN_NAME, TRP_TMU(tmu), lod_bias, detail_scale, detail_max); + grTexDetailControl(tmu, lod_bias, detail_scale, detail_max); +#undef FN_NAME +} + +void FX_CALL trap_grTexFilterMode (GrChipID_t tmu, + GrTextureFilterMode_t minfilter_mode, + GrTextureFilterMode_t magfilter_mode) +{ +#define FN_NAME "grTexFilterMode" + TRAP_LOG("%s(%s, %s, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_TEXFILTER(minfilter_mode), TRP_TEXFILTER(magfilter_mode)); + grTexFilterMode(tmu, minfilter_mode, magfilter_mode); +#undef FN_NAME +} + +void FX_CALL trap_grTexLodBiasValue (GrChipID_t tmu, + float bias) +{ +#define FN_NAME "grTexLodBiasValue" + TRAP_LOG("%s(%s, %f)\n", FN_NAME, TRP_TMU(tmu), bias); + grTexLodBiasValue(tmu, bias); +#undef FN_NAME +} + +void FX_CALL trap_grTexDownloadMipMap (GrChipID_t tmu, + FxU32 startAddress, + FxU32 evenOdd, + GrTexInfo *info) +{ +#define FN_NAME "grTexDownloadMipMap" + TRAP_LOG("%s(%s, %08lx, %s, %p)\n", FN_NAME, TRP_TMU(tmu), startAddress, TRP_EVENODD(evenOdd), (void *)info); + grTexDownloadMipMap(tmu, startAddress, evenOdd, info); +#undef FN_NAME +} + +void FX_CALL trap_grTexDownloadMipMapLevel (GrChipID_t tmu, + FxU32 startAddress, + GrLOD_t thisLod, + GrLOD_t largeLod, + GrAspectRatio_t aspectRatio, + GrTextureFormat_t format, + FxU32 evenOdd, + void *data) +{ +#define FN_NAME "grTexDownloadMipMapLevel" + TRAP_LOG("%s(%s, %08lx, %s, %s, %s, %s, %s, %p)\n", FN_NAME, TRP_TMU(tmu), startAddress, TRP_LODLEVEL(thisLod), TRP_LODLEVEL(largeLod), TRP_ASPECTRATIO(aspectRatio), TRP_TEXFMT(format), TRP_EVENODD(evenOdd), data); + grTexDownloadMipMapLevel(tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data); +#undef FN_NAME +} + +FxBool FX_CALL trap_grTexDownloadMipMapLevelPartial (GrChipID_t tmu, + FxU32 startAddress, + GrLOD_t thisLod, + GrLOD_t largeLod, + GrAspectRatio_t aspectRatio, + GrTextureFormat_t format, + FxU32 evenOdd, + void *data, + int start, + int end) +{ +#define FN_NAME "grTexDownloadMipMapLevelPartial" + FxBool rv; + TRAP_LOG("%s(%s, %08lx, %s, %s, %s, %s, %s, %p, %d, %d)\n", FN_NAME, TRP_TMU(tmu), startAddress, TRP_LODLEVEL(thisLod), TRP_LODLEVEL(largeLod), TRP_ASPECTRATIO(aspectRatio), TRP_TEXFMT(format), TRP_EVENODD(evenOdd), data, start, end); + rv = grTexDownloadMipMapLevelPartial(tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data, start, end); + TRAP_LOG(GOT "%s\n", TRP_BOOL(rv)); + return rv; +#undef FN_NAME +} + +void FX_CALL trap_grTexDownloadTable (GrTexTable_t type, + void *data) +{ +#define FN_NAME "grTexDownloadTable" + TRAP_LOG("%s(%s, %p)\n", FN_NAME, TRP_TABLE(type), data); + grTexDownloadTable(type, data); +#undef FN_NAME +} + +void FX_CALL trap_grTexDownloadTablePartial (GrTexTable_t type, + void *data, + int start, + int end) +{ +#define FN_NAME "grTexDownloadTablePartial" + TRAP_LOG("%s(%s, %p, %d, %d)\n", FN_NAME, TRP_TABLE(type), data, start, end); + grTexDownloadTablePartial(type, data, start, end); +#undef FN_NAME +} + +void FX_CALL trap_grTexMipMapMode (GrChipID_t tmu, + GrMipMapMode_t mode, + FxBool lodBlend) +{ +#define FN_NAME "grTexMipMapMode" + TRAP_LOG("%s(%s, %s, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_MIPMODE(mode), TRP_BOOL(lodBlend)); + grTexMipMapMode(tmu, mode, lodBlend); +#undef FN_NAME +} + +void FX_CALL trap_grTexMultibase (GrChipID_t tmu, + FxBool enable) +{ +#define FN_NAME "grTexMultibase" + TRAP_LOG("%s(%s, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_BOOL(enable)); + grTexMultibase(tmu, enable); +#undef FN_NAME +} + +void FX_CALL trap_grTexMultibaseAddress (GrChipID_t tmu, + GrTexBaseRange_t range, + FxU32 startAddress, + FxU32 evenOdd, + GrTexInfo *info) +{ +#define FN_NAME "grTexMultibaseAddress" + TRAP_LOG("%s(%s, %s, %08lx, %s, %p)\n", FN_NAME, TRP_TMU(tmu), TRP_TEXBASERANGE(range), startAddress, TRP_EVENODD(evenOdd), (void *)info); + grTexMultibaseAddress(tmu, range, startAddress, evenOdd, info); +#undef FN_NAME +} + +/* +** linear frame buffer functions +*/ +FxBool FX_CALL trap_grLfbLock (GrLock_t type, + GrBuffer_t buffer, + GrLfbWriteMode_t writeMode, + GrOriginLocation_t origin, + FxBool pixelPipeline, + GrLfbInfo_t *info) +{ +#define FN_NAME "grLfbLock" + FxBool rv; + TRAP_LOG("%s(%s, %s, %s, %s, %s, %p)\n", FN_NAME, TRP_LOCKTYPE(type), TRP_BUFFER(buffer), TRP_WRITEMODE(writeMode), TRP_ORIGIN(origin), TRP_BOOL(pixelPipeline), (void *)info); + rv = grLfbLock(type, buffer, writeMode, origin, pixelPipeline, info); + TRAP_LOG(GOT "%s\n", TRP_BOOL(rv)); + return rv; +#undef FN_NAME +} + +FxBool FX_CALL trap_grLfbUnlock (GrLock_t type, + GrBuffer_t buffer) +{ +#define FN_NAME "grLfbUnlock" + FxBool rv; + TRAP_LOG("%s(%s, %s)\n", FN_NAME, TRP_LOCKTYPE(type), TRP_BUFFER(buffer)); + rv = grLfbUnlock(type, buffer); + TRAP_LOG(GOT "%s\n", TRP_BOOL(rv)); + return rv; +#undef FN_NAME +} + +void FX_CALL trap_grLfbConstantAlpha (GrAlpha_t alpha) +{ +#define FN_NAME "grLfbConstantAlpha" + TRAP_LOG("%s(%02x)\n", FN_NAME, alpha); + grLfbConstantAlpha(alpha); +#undef FN_NAME +} + +void FX_CALL trap_grLfbConstantDepth (FxU32 depth) +{ +#define FN_NAME "grLfbConstantDepth" + TRAP_LOG("%s(%08lx)\n", FN_NAME, depth); + grLfbConstantDepth(depth); +#undef FN_NAME +} + +void FX_CALL trap_grLfbWriteColorSwizzle (FxBool swizzleBytes, + FxBool swapWords) +{ +#define FN_NAME "grLfbWriteColorSwizzle" + TRAP_LOG("%s(%s, %s)\n", FN_NAME, TRP_BOOL(swizzleBytes), TRP_BOOL(swapWords)); + grLfbWriteColorSwizzle(swizzleBytes, swapWords); +#undef FN_NAME +} + +void FX_CALL trap_grLfbWriteColorFormat (GrColorFormat_t colorFormat) +{ +#define FN_NAME "grLfbWriteColorFormat" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_COLFMT(colorFormat)); + grLfbWriteColorFormat(colorFormat); +#undef FN_NAME +} + +FxBool FX_CALL trap_grLfbWriteRegion (GrBuffer_t dst_buffer, + FxU32 dst_x, + FxU32 dst_y, + GrLfbSrcFmt_t src_format, + FxU32 src_width, + FxU32 src_height, + FxBool pixelPipeline, + FxI32 src_stride, + void *src_data) +{ +#define FN_NAME "grLfbWriteRegion" + FxBool rv; + TRAP_LOG("%s(%s, %lu, %lu, %s, %lu, %lu, %s, %ld, %p)\n", FN_NAME, TRP_BUFFER(dst_buffer), dst_x, dst_y, TRP_SRCFMT(src_format), src_width, src_height, TRP_BOOL(pixelPipeline), src_stride, src_data); + rv = grLfbWriteRegion(dst_buffer, dst_x, dst_y, src_format, src_width, src_height, pixelPipeline, src_stride, src_data); + TRAP_LOG(GOT "%s\n", TRP_BOOL(rv)); + return rv; +#undef FN_NAME +} + +FxBool FX_CALL trap_grLfbReadRegion (GrBuffer_t src_buffer, + FxU32 src_x, + FxU32 src_y, + FxU32 src_width, + FxU32 src_height, + FxU32 dst_stride, + void *dst_data) +{ +#define FN_NAME "grLfbReadRegion" + FxBool rv; + TRAP_LOG("%s(%s, %lu, %lu, %lu, %lu, %ld, %p)\n", FN_NAME, TRP_BUFFER(src_buffer), src_x, src_y, src_width, src_height, dst_stride, dst_data); + rv = grLfbReadRegion(src_buffer, src_x, src_y, src_width, src_height, dst_stride, dst_data); + TRAP_LOG(GOT "%s\n", TRP_BOOL(rv)); + return rv; +#undef FN_NAME +} + +/* +** glide management functions +*/ +void FX_CALL trap_grGlideInit (void) +{ +#define FN_NAME "grGlideInit" + TRAP_LOG("%s()\n", FN_NAME); + grGlideInit(); +#undef FN_NAME +} + +void FX_CALL trap_grGlideShutdown (void) +{ +#define FN_NAME "grGlideShutdown" + TRAP_LOG("%s()\n", FN_NAME); + grGlideShutdown(); +#undef FN_NAME +} + +void FX_CALL trap_grGlideGetState (void *state) +{ +#define FN_NAME "grGlideGetState" + TRAP_LOG("%s(%p)\n", FN_NAME, state); + grGlideGetState(state); +#undef FN_NAME +} + +void FX_CALL trap_grGlideSetState (const void *state) +{ +#define FN_NAME "grGlideSetState" + TRAP_LOG("%s(%p)\n", FN_NAME, state); + grGlideSetState(state); +#undef FN_NAME +} + +void FX_CALL trap_grGlideGetVertexLayout (void *layout) +{ +#define FN_NAME "grGlideGetVertexLayout" + TRAP_LOG("%s(%p)\n", FN_NAME, layout); + grGlideGetVertexLayout(layout); +#undef FN_NAME +} + +void FX_CALL trap_grGlideSetVertexLayout (const void *layout) +{ +#define FN_NAME "grGlideSetVertexLayout" + TRAP_LOG("%s(%p)\n", FN_NAME, layout); + grGlideSetVertexLayout(layout); +#undef FN_NAME +} + +/* +** glide utility functions +*/ +void FX_CALL trap_guGammaCorrectionRGB (FxFloat red, + FxFloat green, + FxFloat blue) +{ +#define FN_NAME "guGammaCorrectionRGB" + TRAP_LOG("%s(%f, %f, %f)\n", FN_NAME, red, green, blue); + guGammaCorrectionRGB(red, green, blue); +#undef FN_NAME +} + +float FX_CALL trap_guFogTableIndexToW (int i) +{ +#define FN_NAME "guFogTableIndexToW" + float rv; + TRAP_LOG("%s(%d)\n", FN_NAME, i); + rv = guFogTableIndexToW(i); + TRAP_LOG(GOT "%f\n", rv); + return rv; +#undef FN_NAME +} + +void FX_CALL trap_guFogGenerateExp (GrFog_t *fogtable, + float density) +{ +#define FN_NAME "guFogGenerateExp" + TRAP_LOG("%s(%p, %f)\n", FN_NAME, fogtable, density); + guFogGenerateExp(fogtable, density); +#undef FN_NAME +} + +void FX_CALL trap_guFogGenerateExp2 (GrFog_t *fogtable, + float density) +{ +#define FN_NAME "guFogGenerateExp2" + TRAP_LOG("%s(%p, %f)\n", FN_NAME, fogtable, density); + guFogGenerateExp2(fogtable, density); +#undef FN_NAME +} + +void FX_CALL trap_guFogGenerateLinear (GrFog_t *fogtable, + float nearZ, + float farZ) +{ +#define FN_NAME "guFogGenerateLinear" + TRAP_LOG("%s(%p, %f, %f)\n", FN_NAME, fogtable, nearZ, farZ); + guFogGenerateLinear(fogtable, nearZ, farZ); +#undef FN_NAME +} + +/* +** glide extensions +*/ +void FX_CALL trap_grSetNumPendingBuffers (FxI32 NumPendingBuffers) +{ +#define FN_NAME "grSetNumPendingBuffers" + TRAP_LOG("%s(%ld)\n", FN_NAME, NumPendingBuffers); + assert(real_grSetNumPendingBuffers); + (*real_grSetNumPendingBuffers)(NumPendingBuffers); +#undef FN_NAME +} + +char *FX_CALL trap_grGetRegistryOrEnvironmentStringExt (char *theEntry) +{ +#define FN_NAME "grGetRegistryOrEnvironmentStringExt" + char *rv; + TRAP_LOG("%s(\"%s\")\n", FN_NAME, theEntry); + assert(real_grGetRegistryOrEnvironmentStringExt); + rv = (*real_grGetRegistryOrEnvironmentStringExt)(theEntry); + if (rv) { + TRAP_LOG(GOT "\"%s\"\n", rv); + } else { + TRAP_LOG(GOT "NULL\n"); + } + return rv; +#undef FN_NAME +} + +void FX_CALL trap_grGetGammaTableExt (FxU32 nentries, + FxU32 *red, + FxU32 *green, + FxU32 *blue) +{ +#define FN_NAME "grGetGammaTableExt" + TRAP_LOG("%s(%lu, %p, %p, %p)\n", FN_NAME, nentries, (void *)red, (void *)green, (void *)blue); + assert(real_grGetGammaTableExt); + (*real_grGetGammaTableExt)(nentries, red, green, blue); +#undef FN_NAME +} + +void FX_CALL trap_grChromaRangeModeExt (GrChromakeyMode_t mode) +{ +#define FN_NAME "grChromaRangeModeExt" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_CKMODE(mode)); + assert(real_grChromaRangeModeExt); + (*real_grChromaRangeModeExt)(mode); +#undef FN_NAME +} + +void FX_CALL trap_grChromaRangeExt (GrColor_t color, + GrColor_t range, + GrChromaRangeMode_t match_mode) +{ +#define FN_NAME "grChromaRangeExt" + TRAP_LOG("%s(%08lx, %08lx, %s)\n", FN_NAME, color, range, TRP_CRMODE(match_mode)); + assert(real_grChromaRangeExt); + (*real_grChromaRangeExt)(color, range, match_mode); +#undef FN_NAME +} + +void FX_CALL trap_grTexChromaModeExt (GrChipID_t tmu, + GrChromakeyMode_t mode) +{ +#define FN_NAME "grTexChromaModeExt" + TRAP_LOG("%s(%s, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_CKMODE(mode)); + assert(real_grTexChromaModeExt); + (*real_grTexChromaModeExt)(tmu, mode); +#undef FN_NAME +} + +void FX_CALL trap_grTexChromaRangeExt (GrChipID_t tmu, + GrColor_t min, + GrColor_t max, + GrTexChromakeyMode_t mode) +{ +#define FN_NAME "grTexChromaRangeExt" + TRAP_LOG("%s(%s, %08lx, %08lx, %s)\n", FN_NAME, TRP_TMU(tmu), min, max, TRP_CRMODE(mode)); + assert(real_grTexChromaRangeExt); + (*real_grTexChromaRangeExt)(tmu, min, max, mode); +#undef FN_NAME +} + + /* pointcast */ +void FX_CALL trap_grTexDownloadTableExt (GrChipID_t tmu, + GrTexTable_t type, + void *data) +{ +#define FN_NAME "grTexDownloadTableExt" + TRAP_LOG("%s(%s, %s, %p)\n", FN_NAME, TRP_TMU(tmu), TRP_TABLE(type), data); + assert(real_grTexDownloadTableExt); + (*real_grTexDownloadTableExt)(tmu, type, data); +#undef FN_NAME +} + +void FX_CALL trap_grTexDownloadTablePartialExt (GrChipID_t tmu, + GrTexTable_t type, + void *data, + int start, + int end) +{ +#define FN_NAME "grTexDownloadTablePartialExt" + TRAP_LOG("%s(%s, %s, %p, %d, %d)\n", FN_NAME, TRP_TMU(tmu), TRP_TABLE(type), data, start, end); + assert(real_grTexDownloadTablePartialExt); + (*real_grTexDownloadTablePartialExt)(tmu, type, data, start, end); +#undef FN_NAME +} + +void FX_CALL trap_grTexNCCTableExt (GrChipID_t tmu, + GrNCCTable_t table) +{ +#define FN_NAME "grTexNCCTableExt" + TRAP_LOG("%s(%s, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_NCC(table)); + assert(real_grTexNCCTableExt); + (*real_grTexNCCTableExt)(tmu, table); +#undef FN_NAME +} + + /* tbext */ +void FX_CALL trap_grTextureBufferExt (GrChipID_t tmu, + FxU32 startAddress, + GrLOD_t thisLOD, + GrLOD_t largeLOD, + GrAspectRatio_t aspectRatio, + GrTextureFormat_t format, + FxU32 odd_even_mask) +{ +#define FN_NAME "grTextureBufferExt" + TRAP_LOG("%s(%s, %08lx, %s, %s, %s, %s, %s)\n", FN_NAME, TRP_TMU(tmu), startAddress, TRP_LODLEVEL(thisLOD), TRP_LODLEVEL(largeLOD), TRP_ASPECTRATIO(aspectRatio), TRP_TEXFMT(format), TRP_EVENODD(odd_even_mask)); + assert(real_grTextureBufferExt); + (*real_grTextureBufferExt)(tmu, startAddress, thisLOD, largeLOD, aspectRatio, format, odd_even_mask); +#undef FN_NAME +} + +void FX_CALL trap_grTextureAuxBufferExt (GrChipID_t tmu, + FxU32 startAddress, + GrLOD_t thisLOD, + GrLOD_t largeLOD, + GrAspectRatio_t aspectRatio, + GrTextureFormat_t format, + FxU32 odd_even_mask) +{ +#define FN_NAME "grTextureAuxBufferExt" + TRAP_LOG("%s(%s, %08lx, %s, %s, %s, %s, %s)\n", FN_NAME, TRP_TMU(tmu), startAddress, TRP_LODLEVEL(thisLOD), TRP_LODLEVEL(largeLOD), TRP_ASPECTRATIO(aspectRatio), TRP_TEXFMT(format), TRP_EVENODD(odd_even_mask)); + assert(real_grTextureAuxBufferExt); + (*real_grTextureAuxBufferExt)(tmu, startAddress, thisLOD, largeLOD, aspectRatio, format, odd_even_mask); +#undef FN_NAME +} + +void FX_CALL trap_grAuxBufferExt (GrBuffer_t buffer) +{ +#define FN_NAME "grAuxBufferExt" + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_BUFFER(buffer)); + assert(real_grAuxBufferExt); + (*real_grAuxBufferExt)(buffer); +#undef FN_NAME +} + + /* napalm */ +GrContext_t FX_CALL trap_grSstWinOpenExt (FxU32 hWnd, + GrScreenResolution_t resolution, + GrScreenRefresh_t refresh, + GrColorFormat_t format, + GrOriginLocation_t origin, + GrPixelFormat_t pixelformat, + int nColBuffers, + int nAuxBuffers) +{ +#define FN_NAME "grSstWinOpenExt" + GrContext_t rv; + TRAP_LOG("%s(%08lx, %s, %s, %s, %s, %s, %d, %d)\n", FN_NAME, hWnd, TRP_RESOLUTION(resolution), TRP_REFRESH(refresh), TRP_COLFMT(format), TRP_ORIGIN(origin), TRP_PIXFMT(pixelformat), nColBuffers, nAuxBuffers); + assert(real_grSstWinOpenExt); + rv = (*real_grSstWinOpenExt)(hWnd, resolution, refresh, format, origin, pixelformat, nColBuffers, nAuxBuffers); + TRAP_LOG(GOT "%p\n", (void *)rv); + return rv; +#undef FN_NAME +} + +void FX_CALL trap_grStencilFuncExt (GrCmpFnc_t fnc, + GrStencil_t ref, + GrStencil_t mask) +{ +#define FN_NAME "grStencilFuncExt" + TRAP_LOG("%s(%s, %02x, %02x)\n", FN_NAME, TRP_CMPFUNC(fnc), ref, mask); + assert(real_grStencilFuncExt); + (*real_grStencilFuncExt)(fnc, ref, mask); +#undef FN_NAME +} + +void FX_CALL trap_grStencilMaskExt (GrStencil_t value) +{ +#define FN_NAME "grStencilMaskExt" + TRAP_LOG("%s(%02x)\n", FN_NAME, value); + assert(real_grStencilMaskExt); + (*real_grStencilMaskExt)(value); +#undef FN_NAME +} + +void FX_CALL trap_grStencilOpExt (GrStencilOp_t stencil_fail, + GrStencilOp_t depth_fail, + GrStencilOp_t depth_pass) +{ +#define FN_NAME "grStencilOpExt" + TRAP_LOG("%s(%s, %s, %s)\n", FN_NAME, TRP_STENCILOP(stencil_fail), TRP_STENCILOP(depth_fail), TRP_STENCILOP(depth_pass)); + assert(real_grStencilOpExt); + (*real_grStencilOpExt)(stencil_fail, depth_fail, depth_pass); +#undef FN_NAME +} + +void FX_CALL trap_grLfbConstantStencilExt (GrStencil_t value) +{ +#define FN_NAME "grLfbConstantStencilExt" + TRAP_LOG("%s(%02x)\n", FN_NAME, value); + assert(real_grLfbConstantStencilExt); + (*real_grLfbConstantStencilExt)(value); +#undef FN_NAME +} + +void FX_CALL trap_grBufferClearExt (GrColor_t color, + GrAlpha_t alpha, + FxU32 depth, + GrStencil_t stencil) +{ +#define FN_NAME "grBufferClearExt" + TRAP_LOG("%s(%08lx, %02x, %08lx, %02x)\n", FN_NAME, color, alpha, depth, stencil); + assert(real_grBufferClearExt); + (*real_grBufferClearExt)(color, alpha, depth, stencil); +#undef FN_NAME +} + +void FX_CALL trap_grColorCombineExt (GrCCUColor_t a, + GrCombineMode_t a_mode, + GrCCUColor_t b, + GrCombineMode_t b_mode, + GrCCUColor_t c, + FxBool c_invert, + GrCCUColor_t d, + FxBool d_invert, + FxU32 shift, + FxBool invert) +{ +#define FN_NAME "grColorCombineExt" + TRAP_LOG("%s(%s, %s, %s, %s, %s, %s, %s, %s, %lu, %s)\n", FN_NAME, TRP_CU(a), TRP_CMBMODE(a_mode), TRP_CU(b), TRP_CMBMODE(b_mode), TRP_CU(c), TRP_BOOL(c_invert), TRP_CU(d), TRP_BOOL(d_invert), shift, TRP_BOOL(invert)); + assert(real_grColorCombineExt); + (*real_grColorCombineExt)(a, a_mode, b, b_mode, c, c_invert, d, d_invert, shift, invert); +#undef FN_NAME +} + +void FX_CALL trap_grAlphaCombineExt (GrACUColor_t a, + GrCombineMode_t a_mode, + GrACUColor_t b, + GrCombineMode_t b_mode, + GrACUColor_t c, + FxBool c_invert, + GrACUColor_t d, + FxBool d_invert, + FxU32 shift, + FxBool invert) +{ +#define FN_NAME "grAlphaCombineExt" + TRAP_LOG("%s(%s, %s, %s, %s, %s, %s, %s, %s, %lu, %s)\n", FN_NAME, TRP_CU(a), TRP_CMBMODE(a_mode), TRP_CU(b), TRP_CMBMODE(b_mode), TRP_CU(c), TRP_BOOL(c_invert), TRP_CU(d), TRP_BOOL(d_invert), shift, TRP_BOOL(invert)); + assert(real_grAlphaCombineExt); + (*real_grAlphaCombineExt)(a, a_mode, b, b_mode, c, c_invert, d, d_invert, shift, invert); +#undef FN_NAME +} + +void FX_CALL trap_grTexColorCombineExt (GrChipID_t tmu, + GrTCCUColor_t a, + GrCombineMode_t a_mode, + GrTCCUColor_t b, + GrCombineMode_t b_mode, + GrTCCUColor_t c, + FxBool c_invert, + GrTCCUColor_t d, + FxBool d_invert, + FxU32 shift, + FxBool invert) +{ +#define FN_NAME "grTexColorCombineExt" + TRAP_LOG("%s(%s, %s, %s, %s, %s, %s, %s, %s, %s, %lu, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_CU(a), TRP_CMBMODE(a_mode), TRP_CU(b), TRP_CMBMODE(b_mode), TRP_CU(c), TRP_BOOL(c_invert), TRP_CU(d), TRP_BOOL(d_invert), shift, TRP_BOOL(invert)); + assert(real_grTexColorCombineExt); + (*real_grTexColorCombineExt)(tmu, a, a_mode, b, b_mode, c, c_invert, d, d_invert, shift, invert); +#undef FN_NAME +} + +void FX_CALL trap_grTexAlphaCombineExt (GrChipID_t tmu, + GrTACUColor_t a, + GrCombineMode_t a_mode, + GrTACUColor_t b, + GrCombineMode_t b_mode, + GrTACUColor_t c, + FxBool c_invert, + GrTACUColor_t d, + FxBool d_invert, + FxU32 shift, + FxBool invert) +{ +#define FN_NAME "grTexAlphaCombineExt" + TRAP_LOG("%s(%s, %s, %s, %s, %s, %s, %s, %s, %s, %lu, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_CU(a), TRP_CMBMODE(a_mode), TRP_CU(b), TRP_CMBMODE(b_mode), TRP_CU(c), TRP_BOOL(c_invert), TRP_CU(d), TRP_BOOL(d_invert), shift, TRP_BOOL(invert)); + assert(real_grTexAlphaCombineExt); + (*real_grTexAlphaCombineExt)(tmu, a, a_mode, b, b_mode, c, c_invert, d, d_invert, shift, invert); +#undef FN_NAME +} + +void FX_CALL trap_grConstantColorValueExt (GrChipID_t tmu, + GrColor_t value) +{ +#define FN_NAME "grConstantColorValueExt" + TRAP_LOG("%s(%s, %08lx)\n", FN_NAME, TRP_TMU(tmu), value); + assert(real_grConstantColorValueExt); + (*real_grConstantColorValueExt)(tmu, value); +#undef FN_NAME +} + +void FX_CALL trap_grColorMaskExt (FxBool r, + FxBool g, + FxBool b, + FxBool a) +{ +#define FN_NAME "grColorMaskExt" + TRAP_LOG("%s(%s, %s, %s, %s)\n", FN_NAME, TRP_BOOL(r), TRP_BOOL(g), TRP_BOOL(b), TRP_BOOL(a)); + assert(real_grColorMaskExt); + (*real_grColorMaskExt)(r, g, b, a); +#undef FN_NAME +} + +void FX_CALL trap_grAlphaBlendFunctionExt (GrAlphaBlendFnc_t rgb_sf, + GrAlphaBlendFnc_t rgb_df, + GrAlphaBlendOp_t rgb_op, + GrAlphaBlendFnc_t alpha_sf, + GrAlphaBlendFnc_t alpha_df, + GrAlphaBlendOp_t alpha_op) +{ +#define FN_NAME "grAlphaBlendFunctionExt" + TRAP_LOG("%s(%s, %s, %s, %s, %s, %s)\n", FN_NAME, TRP_BLEND(rgb_sf), TRP_BLEND(rgb_df), TRP_BLENDOP(rgb_op), TRP_BLEND(alpha_sf), TRP_BLEND(alpha_df), TRP_BLENDOP(alpha_op)); + assert(real_grAlphaBlendFunctionExt); + (*real_grAlphaBlendFunctionExt)(rgb_sf, rgb_df, rgb_op, alpha_sf, alpha_df, alpha_op); +#undef FN_NAME +} + +void FX_CALL trap_grTBufferWriteMaskExt (FxU32 tmask) +{ +#define FN_NAME "grTBufferWriteMaskExt" + TRAP_LOG("%s(%08lx)\n", FN_NAME, tmask); + assert(real_grTBufferWriteMaskExt); + (*real_grTBufferWriteMaskExt)(tmask); +#undef FN_NAME +} + +/* +** texus functions +*/ +void FX_CALL trap_txImgQuantize (char *dst, + char *src, + int w, + int h, + FxU32 format, + FxU32 dither) +{ +#define FN_NAME "txImgQuantize" + TRAP_LOG("%s(%p, %p, %d, %d, %s, %s)\n", FN_NAME, dst, src, w, h, TRP_TEXFMT(format), TRP_TXDITHER(dither)); + assert(real_txImgQuantize); + (*real_txImgQuantize)(dst, src, w, h, format, dither); +#undef FN_NAME +} + +void FX_CALL trap_txMipQuantize (TxMip *pxMip, + TxMip *txMip, + int fmt, + FxU32 d, + FxU32 comp) +{ +#define FN_NAME "txMipQuantize" + TRAP_LOG("%s(%p, %p, %s, %s, %s)\n", FN_NAME, (void *)pxMip, (void *)txMip, TRP_TEXFMT(fmt), TRP_TXDITHER(d), TRP_TXCOMPRESS(comp)); + assert(real_txMipQuantize); + (*real_txMipQuantize)(pxMip, txMip, fmt, d, comp); +#undef FN_NAME +} + +void FX_CALL trap_txPalToNcc (GuNccTable *ncc_table, + const FxU32 *pal) +{ +#define FN_NAME "txPalToNcc" + TRAP_LOG("%s(%p, %p)\n", FN_NAME, (void *)ncc_table, (void *)pal); + assert(real_txPalToNcc); + (*real_txPalToNcc)(ncc_table, pal); +#undef FN_NAME +} +#endif + + + +/****************************************************************************\ +* housekeeping (fake pointers) * +\****************************************************************************/ +char *FX_CALL fake_grGetRegistryOrEnvironmentStringExt (char *theEntry) +{ + return getenv(theEntry); +} + +void FX_CALL fake_grTexDownloadTableExt (GrChipID_t tmu, + GrTexTable_t type, + void *data) +{ + (void)tmu; + grTexDownloadTable(type, data); +} + +void FX_CALL fake_grTexDownloadTablePartialExt (GrChipID_t tmu, + GrTexTable_t type, + void *data, + int start, + int end) +{ + (void)tmu; + grTexDownloadTablePartial(type, data, start, end); +} + +void FX_CALL fake_grTexNCCTableExt (GrChipID_t tmu, + GrNCCTable_t table) +{ + (void)tmu; + grTexNCCTable(table); +} + + + +/****************************************************************************\ +* interface * +\****************************************************************************/ +void tdfx_hook_glide (struct tdfx_glide *Glide, int pointcast) +{ +/* GET_EXT_ADDR: get function pointer + * GET_EXT_FAKE: get function pointer if possible, else use a fake function + * GET_EXT_NULL: get function pointer if possible, else leave NULL pointer + */ +#if FX_TRAP_GLIDE +#define GET_EXT_ADDR(name) *(GrProc *)&real_##name = grGetProcAddress(#name), Glide->name = trap_##name +#define GET_EXT_FAKE(name) GET_EXT_ADDR(name); if (real_##name == NULL) real_##name = fake_##name +#define GET_EXT_NULL(name) GET_EXT_ADDR(name); if (real_##name == NULL) Glide->name = NULL +#else /* FX_TRAP_GLIDE */ +#define GET_EXT_ADDR(name) *(GrProc *)&Glide->name = grGetProcAddress(#name) +#define GET_EXT_FAKE(name) GET_EXT_ADDR(name); if (Glide->name == NULL) Glide->name = fake_##name +#define GET_EXT_NULL(name) GET_EXT_ADDR(name) +#endif /* FX_TRAP_GLIDE */ + + /* + ** glide extensions + */ + GET_EXT_NULL(grSetNumPendingBuffers); + GET_EXT_FAKE(grGetRegistryOrEnvironmentStringExt); + GET_EXT_ADDR(grGetGammaTableExt); + GET_EXT_ADDR(grChromaRangeModeExt); + GET_EXT_ADDR(grChromaRangeExt); + GET_EXT_ADDR(grTexChromaModeExt); + GET_EXT_ADDR(grTexChromaRangeExt); + /* pointcast */ + if (pointcast) { + GET_EXT_FAKE(grTexDownloadTableExt); + GET_EXT_FAKE(grTexDownloadTablePartialExt); + GET_EXT_FAKE(grTexNCCTableExt); + } else { + Glide->grTexDownloadTableExt = fake_grTexDownloadTableExt; + Glide->grTexDownloadTablePartialExt = fake_grTexDownloadTablePartialExt; + Glide->grTexNCCTableExt = fake_grTexNCCTableExt; + } + /* tbext */ + GET_EXT_ADDR(grTextureBufferExt); + GET_EXT_ADDR(grTextureAuxBufferExt); + GET_EXT_ADDR(grAuxBufferExt); + /* napalm */ + GET_EXT_ADDR(grSstWinOpenExt); + GET_EXT_ADDR(grStencilFuncExt); + GET_EXT_ADDR(grStencilMaskExt); + GET_EXT_ADDR(grStencilOpExt); + GET_EXT_ADDR(grLfbConstantStencilExt); + GET_EXT_ADDR(grBufferClearExt); + GET_EXT_ADDR(grColorCombineExt); + GET_EXT_ADDR(grAlphaCombineExt); + GET_EXT_ADDR(grTexColorCombineExt); + GET_EXT_ADDR(grTexAlphaCombineExt); + GET_EXT_ADDR(grConstantColorValueExt); + GET_EXT_ADDR(grColorMaskExt); + GET_EXT_ADDR(grAlphaBlendFunctionExt); + GET_EXT_ADDR(grTBufferWriteMaskExt); + + /* + ** texus + */ + GET_EXT_NULL(txImgQuantize); + GET_EXT_NULL(txMipQuantize); + GET_EXT_NULL(txPalToNcc); + +#undef GET_EXT_ADDR +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.h b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.h new file mode 100644 index 000000000..e71201116 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.h @@ -0,0 +1,382 @@ +/* + * Mesa 3-D graphics library + * Version: 5.0.1 + * + * Copyright (C) 1999-2003 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. + */ + +/* + * Mesa/FX device driver. Interface to Glide3. + * + * Copyright (c) 2003 - Daniel Borca + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + */ + + +#ifndef TDFX_GLIDE_H_included +#define TDFX_GLIDE_H_included + +#include <glide.h> +#include <g3ext.h> + +#ifndef FX_TRAP_GLIDE +#define FX_TRAP_GLIDE 0 +#endif + +#if FX_TRAP_GLIDE +/* +** rendering functions +*/ +void FX_CALL trap_grDrawPoint (const void *pt); +void FX_CALL trap_grDrawLine (const void *v1, const void *v2); +void FX_CALL trap_grDrawTriangle (const void *a, const void *b, const void *c); +void FX_CALL trap_grVertexLayout (FxU32 param, FxI32 offset, FxU32 mode); +void FX_CALL trap_grDrawVertexArray (FxU32 mode, FxU32 Count, void *pointers); +void FX_CALL trap_grDrawVertexArrayContiguous (FxU32 mode, FxU32 Count, void *pointers, FxU32 stride); + +/* +** Antialiasing Functions +*/ +void FX_CALL trap_grAADrawTriangle (const void *a, const void *b, const void *c, FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias); + +/* +** buffer management +*/ +void FX_CALL trap_grBufferClear (GrColor_t color, GrAlpha_t alpha, FxU32 depth); +void FX_CALL trap_grBufferSwap (FxU32 swap_interval); +void FX_CALL trap_grRenderBuffer (GrBuffer_t buffer); + +/* +** error management +*/ +void FX_CALL trap_grErrorSetCallback (GrErrorCallbackFnc_t fnc); + +/* +** SST routines +*/ +void FX_CALL trap_grFinish (void); +void FX_CALL trap_grFlush (void); +GrContext_t FX_CALL trap_grSstWinOpen (FxU32 hWnd, GrScreenResolution_t screen_resolution, GrScreenRefresh_t refresh_rate, GrColorFormat_t color_format, GrOriginLocation_t origin_location, int nColBuffers, int nAuxBuffers); +FxBool FX_CALL trap_grSstWinClose (GrContext_t context); +FxBool FX_CALL trap_grSelectContext (GrContext_t context); +void FX_CALL trap_grSstOrigin (GrOriginLocation_t origin); +void FX_CALL trap_grSstSelect (int which_sst); + +/* +** Glide configuration and special effect maintenance functions +*/ +void FX_CALL trap_grAlphaBlendFunction (GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df); +void FX_CALL trap_grAlphaCombine (GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert); +void FX_CALL trap_grAlphaControlsITRGBLighting (FxBool enable); +void FX_CALL trap_grAlphaTestFunction (GrCmpFnc_t function); +void FX_CALL trap_grAlphaTestReferenceValue (GrAlpha_t value); +void FX_CALL trap_grChromakeyMode (GrChromakeyMode_t mode); +void FX_CALL trap_grChromakeyValue (GrColor_t value); +void FX_CALL trap_grClipWindow (FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy); +void FX_CALL trap_grColorCombine (GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert); +void FX_CALL trap_grColorMask (FxBool rgb, FxBool a); +void FX_CALL trap_grCullMode (GrCullMode_t mode); +void FX_CALL trap_grConstantColorValue (GrColor_t value); +void FX_CALL trap_grDepthBiasLevel (FxI32 level); +void FX_CALL trap_grDepthBufferFunction (GrCmpFnc_t function); +void FX_CALL trap_grDepthBufferMode (GrDepthBufferMode_t mode); +void FX_CALL trap_grDepthMask (FxBool mask); +void FX_CALL trap_grDisableAllEffects (void); +void FX_CALL trap_grDitherMode (GrDitherMode_t mode); +void FX_CALL trap_grFogColorValue (GrColor_t fogcolor); +void FX_CALL trap_grFogMode (GrFogMode_t mode); +void FX_CALL trap_grFogTable (const GrFog_t ft[]); +void FX_CALL trap_grLoadGammaTable (FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue); +void FX_CALL trap_grSplash (float x, float y, float width, float height, FxU32 frame); +FxU32 FX_CALL trap_grGet (FxU32 pname, FxU32 plength, FxI32 *params); +const char * FX_CALL trap_grGetString (FxU32 pname); +FxI32 FX_CALL trap_grQueryResolutions (const GrResolution *resTemplate, GrResolution *output); +FxBool FX_CALL trap_grReset (FxU32 what); +GrProc FX_CALL trap_grGetProcAddress (char *procName); +void FX_CALL trap_grEnable (GrEnableMode_t mode); +void FX_CALL trap_grDisable (GrEnableMode_t mode); +void FX_CALL trap_grCoordinateSpace (GrCoordinateSpaceMode_t mode); +void FX_CALL trap_grDepthRange (FxFloat n, FxFloat f); +void FX_CALL trap_grStippleMode (GrStippleMode_t mode); +void FX_CALL trap_grStipplePattern (GrStipplePattern_t mode); +void FX_CALL trap_grViewport (FxI32 x, FxI32 y, FxI32 width, FxI32 height); + +/* +** texture mapping control functions +*/ +FxU32 FX_CALL trap_grTexCalcMemRequired (GrLOD_t lodmin, GrLOD_t lodmax, GrAspectRatio_t aspect, GrTextureFormat_t fmt); +FxU32 FX_CALL trap_grTexTextureMemRequired (FxU32 evenOdd, GrTexInfo *info); +FxU32 FX_CALL trap_grTexMinAddress (GrChipID_t tmu); +FxU32 FX_CALL trap_grTexMaxAddress (GrChipID_t tmu); +void FX_CALL trap_grTexNCCTable (GrNCCTable_t table); +void FX_CALL trap_grTexSource (GrChipID_t tmu, FxU32 startAddress, FxU32 evenOdd, GrTexInfo *info); +void FX_CALL trap_grTexClampMode (GrChipID_t tmu, GrTextureClampMode_t s_clampmode, GrTextureClampMode_t t_clampmode); +void FX_CALL trap_grTexCombine (GrChipID_t tmu, GrCombineFunction_t rgb_function, GrCombineFactor_t rgb_factor, GrCombineFunction_t alpha_function, GrCombineFactor_t alpha_factor, FxBool rgb_invert, FxBool alpha_invert); +void FX_CALL trap_grTexDetailControl (GrChipID_t tmu, int lod_bias, FxU8 detail_scale, float detail_max); +void FX_CALL trap_grTexFilterMode (GrChipID_t tmu, GrTextureFilterMode_t minfilter_mode, GrTextureFilterMode_t magfilter_mode); +void FX_CALL trap_grTexLodBiasValue (GrChipID_t tmu, float bias); +void FX_CALL trap_grTexDownloadMipMap (GrChipID_t tmu, FxU32 startAddress, FxU32 evenOdd, GrTexInfo *info); +void FX_CALL trap_grTexDownloadMipMapLevel (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLod, GrLOD_t largeLod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 evenOdd, void *data); +FxBool FX_CALL trap_grTexDownloadMipMapLevelPartial (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLod, GrLOD_t largeLod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 evenOdd, void *data, int start, int end); +void FX_CALL trap_grTexDownloadTable (GrTexTable_t type, void *data); +void FX_CALL trap_grTexDownloadTablePartial (GrTexTable_t type, void *data, int start, int end); +void FX_CALL trap_grTexMipMapMode (GrChipID_t tmu, GrMipMapMode_t mode, FxBool lodBlend); +void FX_CALL trap_grTexMultibase (GrChipID_t tmu, FxBool enable); +void FX_CALL trap_grTexMultibaseAddress (GrChipID_t tmu, GrTexBaseRange_t range, FxU32 startAddress, FxU32 evenOdd, GrTexInfo *info); + +/* +** linear frame buffer functions +*/ +FxBool FX_CALL trap_grLfbLock (GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode, GrOriginLocation_t origin, FxBool pixelPipeline, GrLfbInfo_t *info); +FxBool FX_CALL trap_grLfbUnlock (GrLock_t type, GrBuffer_t buffer); +void FX_CALL trap_grLfbConstantAlpha (GrAlpha_t alpha); +void FX_CALL trap_grLfbConstantDepth (FxU32 depth); +void FX_CALL trap_grLfbWriteColorSwizzle (FxBool swizzleBytes, FxBool swapWords); +void FX_CALL trap_grLfbWriteColorFormat (GrColorFormat_t colorFormat); +FxBool FX_CALL trap_grLfbWriteRegion (GrBuffer_t dst_buffer, FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format, FxU32 src_width, FxU32 src_height, FxBool pixelPipeline, FxI32 src_stride, void *src_data); +FxBool FX_CALL trap_grLfbReadRegion (GrBuffer_t src_buffer, FxU32 src_x, FxU32 src_y, FxU32 src_width, FxU32 src_height, FxU32 dst_stride, void *dst_data); + +/* +** glide management functions +*/ +void FX_CALL trap_grGlideInit (void); +void FX_CALL trap_grGlideShutdown (void); +void FX_CALL trap_grGlideGetState (void *state); +void FX_CALL trap_grGlideSetState (const void *state); +void FX_CALL trap_grGlideGetVertexLayout (void *layout); +void FX_CALL trap_grGlideSetVertexLayout (const void *layout); + +/* +** glide utility functions +*/ +void FX_CALL trap_guGammaCorrectionRGB (FxFloat red, FxFloat green, FxFloat blue); +float FX_CALL trap_guFogTableIndexToW (int i); +void FX_CALL trap_guFogGenerateExp (GrFog_t *fogtable, float density); +void FX_CALL trap_guFogGenerateExp2 (GrFog_t *fogtable, float density); +void FX_CALL trap_guFogGenerateLinear (GrFog_t *fogtable, float nearZ, float farZ); + +#ifndef FX_TRAP_GLIDE_internal +/* +** rendering functions +*/ +#define grDrawPoint trap_grDrawPoint +#define grDrawLine trap_grDrawLine +#define grDrawTriangle trap_grDrawTriangle +#define grVertexLayout trap_grVertexLayout +#define grDrawVertexArray trap_grDrawVertexArray +#define grDrawVertexArrayContiguous trap_grDrawVertexArrayContiguous + +/* +** Antialiasing Functions +*/ +#define grAADrawTriangle trap_grAADrawTriangle + +/* +** buffer management +*/ +#define grBufferClear trap_grBufferClear +#define grBufferSwap trap_grBufferSwap +#define grRenderBuffer trap_grRenderBuffer + +/* +** error management +*/ +#define grErrorSetCallback trap_grErrorSetCallback + +/* +** SST routines +*/ +#define grFinish trap_grFinish +#define grFlush trap_grFlush +#define grSstWinOpen trap_grSstWinOpen +#define grSstWinClose trap_grSstWinClose +#define grSelectContext trap_grSelectContext +#define grSstOrigin trap_grSstOrigin +#define grSstSelect trap_grSstSelect + +/* +** Glide configuration and special effect maintenance functions +*/ +#define grAlphaBlendFunction trap_grAlphaBlendFunction +#define grAlphaCombine trap_grAlphaCombine +#define grAlphaControlsITRGBLighting trap_grAlphaControlsITRGBLighting +#define grAlphaTestFunction trap_grAlphaTestFunction +#define grAlphaTestReferenceValue trap_grAlphaTestReferenceValue +#define grChromakeyMode trap_grChromakeyMode +#define grChromakeyValue trap_grChromakeyValue +#define grClipWindow trap_grClipWindow +#define grColorCombine trap_grColorCombine +#define grColorMask trap_grColorMask +#define grCullMode trap_grCullMode +#define grConstantColorValue trap_grConstantColorValue +#define grDepthBiasLevel trap_grDepthBiasLevel +#define grDepthBufferFunction trap_grDepthBufferFunction +#define grDepthBufferMode trap_grDepthBufferMode +#define grDepthMask trap_grDepthMask +#define grDisableAllEffects trap_grDisableAllEffects +#define grDitherMode trap_grDitherMode +#define grFogColorValue trap_grFogColorValue +#define grFogMode trap_grFogMode +#define grFogTable trap_grFogTable +#define grLoadGammaTable trap_grLoadGammaTable +#define grSplash trap_grSplash +#define grGet trap_grGet +#define grGetString trap_grGetString +#define grQueryResolutions trap_grQueryResolutions +#define grReset trap_grReset +#define grGetProcAddress trap_grGetProcAddress +#define grEnable trap_grEnable +#define grDisable trap_grDisable +#define grCoordinateSpace trap_grCoordinateSpace +#define grDepthRange trap_grDepthRange +#define grStippleMode trap_grStippleMode +#define grStipplePattern trap_grStipplePattern +#define grViewport trap_grViewport + +/* +** texture mapping control functions +*/ +#define grTexCalcMemRequired trap_grTexCalcMemRequired +#define grTexTextureMemRequired trap_grTexTextureMemRequired +#define grTexMinAddress trap_grTexMinAddress +#define grTexMaxAddress trap_grTexMaxAddress +#define grTexNCCTable trap_grTexNCCTable +#define grTexSource trap_grTexSource +#define grTexClampMode trap_grTexClampMode +#define grTexCombine trap_grTexCombine +#define grTexDetailControl trap_grTexDetailControl +#define grTexFilterMode trap_grTexFilterMode +#define grTexLodBiasValue trap_grTexLodBiasValue +#define grTexDownloadMipMap trap_grTexDownloadMipMap +#define grTexDownloadMipMapLevel trap_grTexDownloadMipMapLevel +#define grTexDownloadMipMapLevelPartial trap_grTexDownloadMipMapLevelPartial +#define grTexDownloadTable trap_grTexDownloadTable +#define grTexDownloadTablePartial trap_grTexDownloadTablePartial +#define grTexMipMapMode trap_grTexMipMapMode +#define grTexMultibase trap_grTexMultibase +#define grTexMultibaseAddress trap_grTexMultibaseAddress + +/* +** linear frame buffer functions +*/ +#define grLfbLock trap_grLfbLock +#define grLfbUnlock trap_grLfbUnlock +#define grLfbConstantAlpha trap_grLfbConstantAlpha +#define grLfbConstantDepth trap_grLfbConstantDepth +#define grLfbWriteColorSwizzle trap_grLfbWriteColorSwizzle +#define grLfbWriteColorFormat trap_grLfbWriteColorFormat +#define grLfbWriteRegion trap_grLfbWriteRegion +#define grLfbReadRegion trap_grLfbReadRegion + +/* +** glide management functions +*/ +#define grGlideInit trap_grGlideInit +#define grGlideShutdown trap_grGlideShutdown +#define grGlideGetState trap_grGlideGetState +#define grGlideSetState trap_grGlideSetState +#define grGlideGetVertexLayout trap_grGlideGetVertexLayout +#define grGlideSetVertexLayout trap_grGlideSetVertexLayout + +/* +** glide utility functions +*/ +#define guGammaCorrectionRGB trap_guGammaCorrectionRGB +#define guFogTableIndexToW trap_guFogTableIndexToW +#define guFogGenerateExp trap_guFogGenerateExp +#define guFogGenerateExp2 trap_guFogGenerateExp2 +#define guFogGenerateLinear trap_guFogGenerateLinear +#endif /* FX_TRAP_GLIDE_internal */ +#endif /* FX_TRAP_GLIDE */ + + + +/* <texus.h> */ +#define TX_MAX_LEVEL 16 +typedef struct _TxMip { + int format; + int width; + int height; + int depth; + int size; + void *data[TX_MAX_LEVEL]; + FxU32 pal[256]; +} TxMip; + +#define TX_DITHER_NONE 0x00000000 +#define TX_DITHER_4x4 0x00000001 +#define TX_DITHER_ERR 0x00000002 + +#define TX_COMPRESSION_STATISTICAL 0x00000000 +#define TX_COMPRESSION_HEURISTIC 0x00000010 +/* <texus.h> */ + + + +struct tdfx_glide { + /* + ** glide extensions + */ + void (FX_CALL *grSetNumPendingBuffers) (FxI32 NumPendingBuffers); + char * (FX_CALL *grGetRegistryOrEnvironmentStringExt) (char *theEntry); + void (FX_CALL *grGetGammaTableExt) (FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue); + void (FX_CALL *grChromaRangeModeExt) (GrChromakeyMode_t mode); + void (FX_CALL *grChromaRangeExt) (GrColor_t color, GrColor_t range, GrChromaRangeMode_t match_mode); + void (FX_CALL *grTexChromaModeExt) (GrChipID_t tmu, GrChromakeyMode_t mode); + void (FX_CALL *grTexChromaRangeExt) (GrChipID_t tmu, GrColor_t min, GrColor_t max, GrTexChromakeyMode_t mode); + + /* pointcast */ + void (FX_CALL *grTexDownloadTableExt) (GrChipID_t tmu, GrTexTable_t type, void *data); + void (FX_CALL *grTexDownloadTablePartialExt) (GrChipID_t tmu, GrTexTable_t type, void *data, int start, int end); + void (FX_CALL *grTexNCCTableExt) (GrChipID_t tmu, GrNCCTable_t table); + + /* tbext */ + void (FX_CALL *grTextureBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask); + void (FX_CALL *grTextureAuxBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask); + void (FX_CALL *grAuxBufferExt) (GrBuffer_t buffer); + + /* napalm */ + GrContext_t (FX_CALL *grSstWinOpenExt) (FxU32 hWnd, GrScreenResolution_t resolution, GrScreenRefresh_t refresh, GrColorFormat_t format, GrOriginLocation_t origin, GrPixelFormat_t pixelformat, int nColBuffers, int nAuxBuffers); + void (FX_CALL *grStencilFuncExt) (GrCmpFnc_t fnc, GrStencil_t ref, GrStencil_t mask); + void (FX_CALL *grStencilMaskExt) (GrStencil_t value); + void (FX_CALL *grStencilOpExt) (GrStencilOp_t stencil_fail, GrStencilOp_t depth_fail, GrStencilOp_t depth_pass); + void (FX_CALL *grLfbConstantStencilExt) (GrStencil_t value); + void (FX_CALL *grBufferClearExt) (GrColor_t color, GrAlpha_t alpha, FxU32 depth, GrStencil_t stencil); + void (FX_CALL *grColorCombineExt) (GrCCUColor_t a, GrCombineMode_t a_mode, GrCCUColor_t b, GrCombineMode_t b_mode, GrCCUColor_t c, FxBool c_invert, GrCCUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); + void (FX_CALL *grAlphaCombineExt) (GrACUColor_t a, GrCombineMode_t a_mode, GrACUColor_t b, GrCombineMode_t b_mode, GrACUColor_t c, FxBool c_invert, GrACUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); + void (FX_CALL *grTexColorCombineExt) (GrChipID_t tmu, GrTCCUColor_t a, GrCombineMode_t a_mode, GrTCCUColor_t b, GrCombineMode_t b_mode, GrTCCUColor_t c, FxBool c_invert, GrTCCUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); + void (FX_CALL *grTexAlphaCombineExt) (GrChipID_t tmu, GrTACUColor_t a, GrCombineMode_t a_mode, GrTACUColor_t b, GrCombineMode_t b_mode, GrTACUColor_t c, FxBool c_invert, GrTACUColor_t d, FxBool d_invert, FxU32 shift, FxBool invert); + void (FX_CALL *grConstantColorValueExt) (GrChipID_t tmu, GrColor_t value); + void (FX_CALL *grColorMaskExt) (FxBool r, FxBool g, FxBool b, FxBool a); + void (FX_CALL *grAlphaBlendFunctionExt) (GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendOp_t rgb_op, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df, GrAlphaBlendOp_t alpha_op); + void (FX_CALL *grTBufferWriteMaskExt) (FxU32 tmask); + + /* + ** Texus2 functions + */ + void (FX_CALL *txImgQuantize) (char *dst, char *src, int w, int h, FxU32 format, FxU32 dither); + void (FX_CALL *txMipQuantize) (TxMip *pxMip, TxMip *txMip, int fmt, FxU32 d, FxU32 comp); + void (FX_CALL *txPalToNcc) (GuNccTable *ncc_table, const FxU32 *pal); +}; + +void tdfx_hook_glide (struct tdfx_glide *Glide, int pointcast); + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.c new file mode 100644 index 000000000..1fedf2ab9 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.c @@ -0,0 +1,269 @@ +/* + * 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 + */ + +/* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */ + + +#ifdef HAVE_CONFIG_H +#include "conf.h" +#endif + +#if defined(FX) +#include "fxglidew.h" +#include "fxdrv.h" + +#include <stdlib.h> +#include <string.h> + +FxI32 +FX_grGetInteger_NoLock(FxU32 pname) +{ + FxI32 result; + + if (grGet(pname, 4, &result)) { + return result; + } + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "FX_grGetInteger_NoLock: wrong parameter (%lx)\n", pname); + } + return -1; +} + +FxBool +FX_grSstControl(FxU32 code) +{ + /* The glide 3 sources call for grEnable/grDisable to be called in exchange + * for grSstControl. */ + switch (code) { + case GR_CONTROL_ACTIVATE: + grEnable(GR_PASSTHRU); + break; + case GR_CONTROL_DEACTIVATE: + grDisable(GR_PASSTHRU); + break; + } + /* Appearently GR_CONTROL_RESIZE can be ignored. */ + return 1; /* OK? */ +} + + +int +FX_grSstScreenWidth() +{ + FxI32 result[4]; + + BEGIN_BOARD_LOCK(); + grGet(GR_VIEWPORT, sizeof(FxI32) * 4, result); + END_BOARD_LOCK(); + + return result[2]; +} + +int +FX_grSstScreenHeight() +{ + FxI32 result[4]; + + BEGIN_BOARD_LOCK(); + grGet(GR_VIEWPORT, sizeof(FxI32) * 4, result); + END_BOARD_LOCK(); + + return result[3]; +} + +void +FX_grSstPerfStats(GrSstPerfStats_t * st) +{ + FxI32 n; + grGet(GR_STATS_PIXELS_IN, 4, &n); + st->pixelsIn = n; + grGet(GR_STATS_PIXELS_CHROMA_FAIL, 4, &n); + st->chromaFail = n; + grGet(GR_STATS_PIXELS_DEPTHFUNC_FAIL, 4, &n); + st->zFuncFail = n; + grGet(GR_STATS_PIXELS_AFUNC_FAIL, 4, &n); + st->aFuncFail = n; + grGet(GR_STATS_PIXELS_OUT, 4, &n); + st->pixelsOut = n; +} + +void +FX_setupGrVertexLayout(void) +{ + BEGIN_BOARD_LOCK(); + grReset(GR_VERTEX_PARAMETER); + + grCoordinateSpace(GR_WINDOW_COORDS); + grVertexLayout(GR_PARAM_XY, GR_VERTEX_X_OFFSET << 2, GR_PARAM_ENABLE); +#if FX_PACKEDCOLOR + grVertexLayout(GR_PARAM_PARGB, GR_VERTEX_PARGB_OFFSET << 2, GR_PARAM_ENABLE); +#else /* !FX_PACKEDCOLOR */ + grVertexLayout(GR_PARAM_RGB, GR_VERTEX_RGB_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_A, GR_VERTEX_A_OFFSET << 2, GR_PARAM_ENABLE); +#endif /* !FX_PACKEDCOLOR */ + grVertexLayout(GR_PARAM_Q, GR_VERTEX_OOW_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_Z, GR_VERTEX_OOZ_OFFSET << 2, GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_ST0, GR_VERTEX_SOW_TMU0_OFFSET << 2, + GR_PARAM_ENABLE); + grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, + GR_PARAM_DISABLE); + grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + END_BOARD_LOCK(); +} + +void +FX_grHints_NoLock(GrHint_t hintType, FxU32 hintMask) +{ + switch (hintType) { + case GR_HINT_STWHINT: + { + if (hintMask & GR_STWHINT_W_DIFF_TMU0) + grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, + GR_PARAM_ENABLE); + else + grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, + GR_PARAM_DISABLE); + + if (hintMask & GR_STWHINT_ST_DIFF_TMU1) + grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, + GR_PARAM_ENABLE); + else + grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + + if (hintMask & GR_STWHINT_W_DIFF_TMU1) + grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, + GR_PARAM_ENABLE); + else + grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, + GR_PARAM_DISABLE); + + } + } +} + +/* + * Glide3 doesn't have the grSstQueryHardware function anymore. + * Instead, we call grGet() and fill in the data structures ourselves. + */ +int +FX_grSstQueryHardware(GrHwConfiguration * config) +{ + int i, j; + int numFB; + + BEGIN_BOARD_LOCK(); + + grGet(GR_NUM_BOARDS, 4, (void *) &(config->num_sst)); + if (config->num_sst == 0) + return 0; + + for (i = 0; i < config->num_sst; i++) { + FxI32 result; + const char *extension; + + grSstSelect(i); + + extension = grGetString(GR_HARDWARE); + if (strstr(extension, "Rush")) { + config->SSTs[i].type = GR_SSTTYPE_SST96; + } else if (strstr(extension, "Voodoo2")) { + config->SSTs[i].type = GR_SSTTYPE_Voodoo2; + } else if (strstr(extension, "Voodoo Banshee")) { + config->SSTs[i].type = GR_SSTTYPE_Banshee; + } else if (strstr(extension, "Voodoo3")) { + config->SSTs[i].type = GR_SSTTYPE_Voodoo3; + } else if (strstr(extension, "Voodoo4")) { + config->SSTs[i].type = GR_SSTTYPE_Voodoo4; + } else if (strstr(extension, "Voodoo5")) { + config->SSTs[i].type = GR_SSTTYPE_Voodoo5; + } else { + config->SSTs[i].type = GR_SSTTYPE_VOODOO; + } + + grGet(GR_MEMORY_FB, 4, &result); + config->SSTs[i].fbRam = result / (1024 * 1024); + + grGet(GR_NUM_TMU, 4, &result); + config->SSTs[i].nTexelfx = result; + + grGet(GR_REVISION_FB, 4, &result); + config->SSTs[i].fbiRev = result; + + for (j = 0; j < config->SSTs[i].nTexelfx; j++) { + grGet(GR_MEMORY_TMU, 4, &result); + config->SSTs[i].tmuConfig[j].tmuRam = result / (1024 * 1024); + grGet(GR_REVISION_TMU, 4, &result); + config->SSTs[i].tmuConfig[j].tmuRev = result; + } + + extension = grGetString(GR_EXTENSION); + config->SSTs[i].HavePalExt = (strstr(extension, " PALETTE6666 ") != NULL); + config->SSTs[i].HavePixExt = (strstr(extension, " PIXEXT ") != NULL); + config->SSTs[i].HaveTexFmt = (strstr(extension, " TEXFMT ") != NULL); + config->SSTs[i].HaveCmbExt = (strstr(extension, " COMBINE ") != NULL); + config->SSTs[i].HaveMirExt = (strstr(extension, " TEXMIRROR ") != NULL); + config->SSTs[i].HaveTexUma = (strstr(extension, " TEXUMA ") != NULL); + + /* number of Voodoo chips */ + grGet(GR_NUM_FB, 4, (void *) &numFB); + config->SSTs[i].numChips = numFB; + + } + + tdfx_hook_glide(&config->Glide, getenv("MESA_FX_POINTCAST") != NULL); + + END_BOARD_LOCK(); + return 1; +} + + + +#else + +/* + * Need this to provide at least one external definition. + */ + +extern int gl_fx_dummy_function_glidew(void); +int +gl_fx_dummy_function_glidew(void) +{ + return 0; +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.h b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.h new file mode 100644 index 000000000..a19d0b58c --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.h @@ -0,0 +1,228 @@ +/* + * 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 + */ + + +#ifndef __FX_GLIDE_WARPER__ +#define __FX_GLIDE_WARPER__ + + +#include "fxg.h" + +#ifndef FX_PACKEDCOLOR +#define FX_PACKEDCOLOR 1 +#endif + +#define MAX_NUM_SST 4 + +enum { + GR_SSTTYPE_VOODOO = 0, + GR_SSTTYPE_SST96 = 1, + GR_SSTTYPE_AT3D = 2, + GR_SSTTYPE_Voodoo2 = 3, + GR_SSTTYPE_Banshee = 4, + GR_SSTTYPE_Voodoo3 = 5, + GR_SSTTYPE_Voodoo4 = 6, + GR_SSTTYPE_Voodoo5 = 7 +}; + +#define GrState void + +typedef int GrSstType; + +typedef struct GrTMUConfig_St { + int tmuRev; /* Rev of Texelfx chip */ + int tmuRam; /* 1, 2, or 4 MB */ +} GrTMUConfig_t; + +typedef struct { + int num_sst; /* # of HW units in the system */ + struct SstCard_St { + GrSstType type; /* Which hardware is it? */ + int fbRam; /* 1, 2, or 4 MB */ + int fbiRev; /* Rev of Pixelfx chip */ + int nTexelfx; /* How many texelFX chips are there? */ + int numChips; /* Number of Voodoo chips */ + GrTMUConfig_t tmuConfig[GLIDE_NUM_TMU]; /* Configuration of the Texelfx chips */ + /* Glide3 extensions */ + FxBool HavePalExt; /* PALETTE6666 */ + FxBool HavePixExt; /* PIXEXT */ + FxBool HaveTexFmt; /* TEXFMT */ + FxBool HaveCmbExt; /* COMBINE */ + FxBool HaveMirExt; /* TEXMIRROR */ + FxBool HaveTexUma; /* TEXUMA */ + } + SSTs[MAX_NUM_SST]; /* configuration for each board */ + struct tdfx_glide Glide; +} GrHwConfiguration; + + + +typedef FxU32 GrHint_t; +#define GR_HINTTYPE_MIN 0 +#define GR_HINT_STWHINT 0 + +typedef FxU32 GrSTWHint_t; +#define GR_STWHINT_W_DIFF_FBI FXBIT(0) +#define GR_STWHINT_W_DIFF_TMU0 FXBIT(1) +#define GR_STWHINT_ST_DIFF_TMU0 FXBIT(2) +#define GR_STWHINT_W_DIFF_TMU1 FXBIT(3) +#define GR_STWHINT_ST_DIFF_TMU1 FXBIT(4) +#define GR_STWHINT_W_DIFF_TMU2 FXBIT(5) +#define GR_STWHINT_ST_DIFF_TMU2 FXBIT(6) + +#define GR_CONTROL_ACTIVATE 1 +#define GR_CONTROL_DEACTIVATE 0 + + + +/* +** move the vertex layout defintion to application +*/ +typedef struct { + float sow; /* s texture ordinate (s over w) */ + float tow; /* t texture ordinate (t over w) */ + float oow; /* 1/w (used mipmapping - really 0xfff/w) */ +} GrTmuVertex; + +#if FX_PACKEDCOLOR +typedef struct { + float x, y; /* X and Y in screen space */ + float ooz; /* 65535/Z (used for Z-buffering) */ + float oow; /* 1/W (used for W-buffering, texturing) */ + unsigned char pargb[4]; /* B, G, R, A [0..255] */ + GrTmuVertex tmuvtx[GLIDE_NUM_TMU]; + float fog; /* fog coordinate */ + unsigned char pspec[4]; /* B, G, R, A [0..255] */ + float psize; /* point size */ + long pad[16 - 14]; /* ensure 64b structure */ +} GrVertex; + +#define GR_VERTEX_X_OFFSET 0 +#define GR_VERTEX_Y_OFFSET 1 +#define GR_VERTEX_OOZ_OFFSET 2 +#define GR_VERTEX_OOW_OFFSET 3 +#define GR_VERTEX_PARGB_OFFSET 4 +#define GR_VERTEX_SOW_TMU0_OFFSET 5 +#define GR_VERTEX_TOW_TMU0_OFFSET 6 +#define GR_VERTEX_OOW_TMU0_OFFSET 7 +#define GR_VERTEX_SOW_TMU1_OFFSET 8 +#define GR_VERTEX_TOW_TMU1_OFFSET 9 +#define GR_VERTEX_OOW_TMU1_OFFSET 10 +#define GR_VERTEX_FOG_OFFSET 11 +#define GR_VERTEX_PSPEC_OFFSET 12 +#else /* !FX_PACKEDCOLOR */ +typedef struct { + float x, y; /* X and Y in screen space */ + float ooz; /* 65535/Z (used for Z-buffering) */ + float oow; /* 1/W (used for W-buffering, texturing) */ + float r, g, b, a; /* R, G, B, A [0..255] */ + GrTmuVertex tmuvtx[GLIDE_NUM_TMU]; + float fog; /* fog coordinate */ + float r1, g1, b1; /* R, G, B [0..255] */ + float psize; /* point size */ + long pad[20 - 19]; /* ensure multiple of 16 */ +} GrVertex; + +#define GR_VERTEX_X_OFFSET 0 +#define GR_VERTEX_Y_OFFSET 1 +#define GR_VERTEX_OOZ_OFFSET 2 +#define GR_VERTEX_OOW_OFFSET 3 +#define GR_VERTEX_RGB_OFFSET 4 +#define GR_VERTEX_A_OFFSET 7 +#define GR_VERTEX_SOW_TMU0_OFFSET 8 +#define GR_VERTEX_TOW_TMU0_OFFSET 9 +#define GR_VERTEX_OOW_TMU0_OFFSET 10 +#define GR_VERTEX_SOW_TMU1_OFFSET 11 +#define GR_VERTEX_TOW_TMU1_OFFSET 12 +#define GR_VERTEX_OOW_TMU1_OFFSET 13 +#define GR_VERTEX_FOG_OFFSET 14 +#define GR_VERTEX_SPEC_OFFSET 15 +#endif /* !FX_PACKEDCOLOR */ + + + +/* + * For Lod/LodLog2 conversion. + */ +#define FX_largeLodLog2(info) (info).largeLodLog2 +#define FX_aspectRatioLog2(info) (info).aspectRatioLog2 +#define FX_smallLodLog2(info) (info).smallLodLog2 +#define FX_lodToValue(val) ((int)(GR_LOD_LOG2_256-val)) +#define FX_largeLodValue(info) ((int)(GR_LOD_LOG2_256-(info).largeLodLog2)) +#define FX_smallLodValue(info) ((int)(GR_LOD_LOG2_256-(info).smallLodLog2)) +#define FX_valueToLod(val) ((GrLOD_t)(GR_LOD_LOG2_256-val)) + + + +/* + * Query + */ +extern int FX_grSstScreenWidth(void); +extern int FX_grSstScreenHeight(void); +extern void FX_grSstPerfStats(GrSstPerfStats_t *st); +extern int FX_grSstQueryHardware(GrHwConfiguration *config); +#define FX_grGetInteger FX_grGetInteger_NoLock +extern FxI32 FX_grGetInteger_NoLock(FxU32 pname); + + + +/* + * GrHints + */ +#define FX_grHints FX_grHints_NoLock +extern void FX_grHints_NoLock(GrHint_t hintType, FxU32 hintMask); + + + +/* + * Needed for Glide3 only, to set up Glide2 compatible vertex layout. + */ +extern void FX_setupGrVertexLayout(void); + + + +/* + * grSstControl stuff + */ +extern FxBool FX_grSstControl(FxU32 code); + +#define FX_grBufferClear(c, a, d) \ + do { \ + BEGIN_CLIP_LOOP(); \ + grBufferClear(c, a, d); \ + END_CLIP_LOOP(); \ + } while (0) + + + +#endif /* __FX_GLIDE_WARPER__ */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.c new file mode 100644 index 000000000..360a42f7e --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.c @@ -0,0 +1,2217 @@ +/* + * 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 + */ + +/* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */ + + +#ifdef HAVE_CONFIG_H +#include "conf.h" +#endif + +#if defined(FX) + +#include "fxdrv.h" +#include "enums.h" +#include "tnl.h" +#include "tnl/t_context.h" +#include "swrast.h" +#include "texstore.h" + + +static void +fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + GLint minl, maxl; + + if (ti->validated) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxTexValidate(NOP)\n"); + } + return; + } + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxTexValidate(%p (%d))\n", (void *)tObj, tObj->Name); + } + + ti->tObj = tObj; + minl = ti->minLevel = tObj->BaseLevel; + maxl = ti->maxLevel = MIN2(tObj->MaxLevel, tObj->Image[0][0]->MaxLog2); + +#if FX_RESCALE_BIG_TEXURES_HACK +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + /* [dBorca] + * Fake textures larger than HW supports: + * 1) we have mipmaps. Then we just push up to the first supported + * LOD. A possible drawback is that Mesa will ignore the skipped + * LODs on further texture handling. + * Will this interfere with GL_TEXTURE_[MIN|BASE]_LEVEL? How? + * 2) we don't have mipmaps. We need to rescale the big LOD in place. + * The above approach is somehow dumb! we might have rescaled + * once in TexImage2D to accomodate aspect ratio, and now we + * are rescaling again. The thing is, in TexImage2D we don't + * know whether we'll hit 1) or 2) by the time of validation. + */ + if ((tObj->MinFilter == GL_NEAREST) || (tObj->MinFilter == GL_LINEAR)) { + /* no mipmaps! */ + struct gl_texture_image *texImage = tObj->Image[0][minl]; + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + GLint _w, _h, maxSize = 1 << fxMesa->textureMaxLod; + if ((mml->width > maxSize) || (mml->height > maxSize)) { + /* need to rescale */ + GLint texelBytes = texImage->TexFormat->TexelBytes; + GLvoid *texImage_Data = texImage->Data; + _w = MIN2(texImage->Width, maxSize); + _h = MIN2(texImage->Height, maxSize); + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTexValidate: rescaling %d x %d -> %d x %d\n", + texImage->Width, texImage->Height, _w, _h); + } + /* we should leave these as is and... (!) */ + texImage->Width = _w; + texImage->Height = _h; + fxTexGetInfo(_w, _h, NULL, NULL, NULL, NULL, + &(mml->wScale), &(mml->hScale)); + _w *= mml->wScale; + _h *= mml->hScale; + texImage->Data = _mesa_malloc(_w * _h * texelBytes); + _mesa_rescale_teximage2d(texelBytes, + mml->width, + _w * texelBytes, /* dst stride */ + mml->width, mml->height, /* src */ + _w, _h, /* dst */ + texImage_Data /*src*/, texImage->Data /*dst*/ ); + _mesa_free(texImage_Data); + mml->width = _w; + mml->height = _h; + /* (!) ... and set mml->wScale = _w / texImage->Width */ + } + } else { + /* mipmapping */ + if (maxl - minl > fxMesa->textureMaxLod) { + /* skip a certain number of LODs */ + minl += maxl - fxMesa->textureMaxLod; + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTexValidate: skipping %d LODs\n", minl - ti->minLevel); + } + ti->minLevel = tObj->BaseLevel = minl; + } + } +} +#endif + + fxTexGetInfo(tObj->Image[0][minl]->Width, tObj->Image[0][minl]->Height, + &(FX_largeLodLog2(ti->info)), &(FX_aspectRatioLog2(ti->info)), + &(ti->sScale), &(ti->tScale), + NULL, NULL); + + if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) + fxTexGetInfo(tObj->Image[0][maxl]->Width, tObj->Image[0][maxl]->Height, + &(FX_smallLodLog2(ti->info)), NULL, + NULL, NULL, NULL, NULL); + else + FX_smallLodLog2(ti->info) = FX_largeLodLog2(ti->info); + + /* [dBorca] this is necessary because of fxDDCompressedTexImage2D */ + if (ti->padded) { + struct gl_texture_image *texImage = tObj->Image[0][minl]; + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + if (mml->wScale != 1 || mml->hScale != 1) { + ti->sScale /= mml->wScale; + ti->tScale /= mml->hScale; + } + } + + ti->baseLevelInternalFormat = tObj->Image[0][minl]->Format; + + ti->validated = GL_TRUE; + + ti->info.data = NULL; +} + +static void +fxPrintUnitsMode(const char *msg, GLuint mode) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + msg, + mode, + (mode & FX_UM_E0_REPLACE) ? "E0_REPLACE, " : "", + (mode & FX_UM_E0_MODULATE) ? "E0_MODULATE, " : "", + (mode & FX_UM_E0_DECAL) ? "E0_DECAL, " : "", + (mode & FX_UM_E0_BLEND) ? "E0_BLEND, " : "", + (mode & FX_UM_E1_REPLACE) ? "E1_REPLACE, " : "", + (mode & FX_UM_E1_MODULATE) ? "E1_MODULATE, " : "", + (mode & FX_UM_E1_DECAL) ? "E1_DECAL, " : "", + (mode & FX_UM_E1_BLEND) ? "E1_BLEND, " : "", + (mode & FX_UM_E0_ALPHA) ? "E0_ALPHA, " : "", + (mode & FX_UM_E0_LUMINANCE) ? "E0_LUMINANCE, " : "", + (mode & FX_UM_E0_LUMINANCE_ALPHA) ? "E0_LUMINANCE_ALPHA, " : "", + (mode & FX_UM_E0_INTENSITY) ? "E0_INTENSITY, " : "", + (mode & FX_UM_E0_RGB) ? "E0_RGB, " : "", + (mode & FX_UM_E0_RGBA) ? "E0_RGBA, " : "", + (mode & FX_UM_E1_ALPHA) ? "E1_ALPHA, " : "", + (mode & FX_UM_E1_LUMINANCE) ? "E1_LUMINANCE, " : "", + (mode & FX_UM_E1_LUMINANCE_ALPHA) ? "E1_LUMINANCE_ALPHA, " : "", + (mode & FX_UM_E1_INTENSITY) ? "E1_INTENSITY, " : "", + (mode & FX_UM_E1_RGB) ? "E1_RGB, " : "", + (mode & FX_UM_E1_RGBA) ? "E1_RGBA, " : "", + (mode & FX_UM_COLOR_ITERATED) ? "COLOR_ITERATED, " : "", + (mode & FX_UM_COLOR_CONSTANT) ? "COLOR_CONSTANT, " : "", + (mode & FX_UM_ALPHA_ITERATED) ? "ALPHA_ITERATED, " : "", + (mode & FX_UM_ALPHA_CONSTANT) ? "ALPHA_CONSTANT, " : ""); +} + +static GLuint +fxGetTexSetConfiguration(GLcontext * ctx, + struct gl_texture_object *tObj0, + struct gl_texture_object *tObj1) +{ + GLuint unitsmode = 0; + GLuint envmode = 0; + GLuint ifmt = 0; + + if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 || + (ctx->Point.SmoothFlag) || + (ctx->Line.SmoothFlag) || + (ctx->Polygon.SmoothFlag)) unitsmode |= FX_UM_ALPHA_ITERATED; + else + unitsmode |= FX_UM_ALPHA_CONSTANT; + + if (ctx->Light.ShadeModel == GL_SMOOTH || 1) + unitsmode |= FX_UM_COLOR_ITERATED; + else + unitsmode |= FX_UM_COLOR_CONSTANT; + + + + /* + OpenGL Feeds Texture 0 into Texture 1 + Glide Feeds Texture 1 into Texture 0 + */ + if (tObj0) { + tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0); + + switch (ti0->baseLevelInternalFormat) { + case GL_ALPHA: + ifmt |= FX_UM_E0_ALPHA; + break; + case GL_LUMINANCE: + ifmt |= FX_UM_E0_LUMINANCE; + break; + case GL_LUMINANCE_ALPHA: + ifmt |= FX_UM_E0_LUMINANCE_ALPHA; + break; + case GL_INTENSITY: + ifmt |= FX_UM_E0_INTENSITY; + break; + case GL_RGB: + ifmt |= FX_UM_E0_RGB; + break; + case GL_RGBA: + ifmt |= FX_UM_E0_RGBA; + break; + } + + switch (ctx->Texture.Unit[0].EnvMode) { + case GL_DECAL: + envmode |= FX_UM_E0_DECAL; + break; + case GL_MODULATE: + envmode |= FX_UM_E0_MODULATE; + break; + case GL_REPLACE: + envmode |= FX_UM_E0_REPLACE; + break; + case GL_BLEND: + envmode |= FX_UM_E0_BLEND; + break; + case GL_ADD: + envmode |= FX_UM_E0_ADD; + break; + default: + /* do nothing */ + break; + } + } + + if (tObj1) { + tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1); + + switch (ti1->baseLevelInternalFormat) { + case GL_ALPHA: + ifmt |= FX_UM_E1_ALPHA; + break; + case GL_LUMINANCE: + ifmt |= FX_UM_E1_LUMINANCE; + break; + case GL_LUMINANCE_ALPHA: + ifmt |= FX_UM_E1_LUMINANCE_ALPHA; + break; + case GL_INTENSITY: + ifmt |= FX_UM_E1_INTENSITY; + break; + case GL_RGB: + ifmt |= FX_UM_E1_RGB; + break; + case GL_RGBA: + ifmt |= FX_UM_E1_RGBA; + break; + default: + /* do nothing */ + break; + } + + switch (ctx->Texture.Unit[1].EnvMode) { + case GL_DECAL: + envmode |= FX_UM_E1_DECAL; + break; + case GL_MODULATE: + envmode |= FX_UM_E1_MODULATE; + break; + case GL_REPLACE: + envmode |= FX_UM_E1_REPLACE; + break; + case GL_BLEND: + envmode |= FX_UM_E1_BLEND; + break; + case GL_ADD: + envmode |= FX_UM_E1_ADD; + break; + default: + /* do nothing */ + break; + } + } + + unitsmode |= (ifmt | envmode); + + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fxPrintUnitsMode("fxGetTexSetConfiguration", unitsmode); + + return unitsmode; +} + +/************************************************************************/ +/************************* Rendering Mode SetUp *************************/ +/************************************************************************/ + +/************************* Single Texture Set ***************************/ + +static void +fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + int tmu; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupSingleTMU_NoLock(%p (%d))\n", (void *)tObj, tObj->Name); + } + + ti->lastTimeUsed = fxMesa->texBindNumber; + + /* Make sure we're not loaded incorrectly */ + if (ti->isInTM) { + if (ti->LODblend) { + if (ti->whichTMU != FX_TMU_SPLIT) + fxTMMoveOutTM(fxMesa, tObj); + } + else { + if (ti->whichTMU == FX_TMU_SPLIT) + fxTMMoveOutTM(fxMesa, tObj); + } + } + + /* Make sure we're loaded correctly */ + if (!ti->isInTM) { + if (ti->LODblend) + fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU_SPLIT); + else { + if (fxMesa->haveTwoTMUs) { + if (fxTMCheckStartAddr(fxMesa, FX_TMU0, ti)) { + fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0); + } + else { + fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU1); + } + } + else + fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0); + } + } + + if (ti->LODblend && ti->whichTMU == FX_TMU_SPLIT) { + /* broadcast */ + if ((ti->info.format == GR_TEXFMT_P_8) + && (!fxMesa->haveGlobalPaletteTexture)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupSingleTMU_NoLock: uploading texture palette\n"); + } + grTexDownloadTable(ti->paltype, &(ti->palette)); + } + + grTexClampMode(GR_TMU0, ti->sClamp, ti->tClamp); + grTexClampMode(GR_TMU1, ti->sClamp, ti->tClamp); + grTexFilterMode(GR_TMU0, ti->minFilt, ti->maxFilt); + grTexFilterMode(GR_TMU1, ti->minFilt, ti->maxFilt); + grTexMipMapMode(GR_TMU0, ti->mmMode, ti->LODblend); + grTexMipMapMode(GR_TMU1, ti->mmMode, ti->LODblend); + + grTexSource(GR_TMU0, ti->tm[FX_TMU0]->startAddr, + GR_MIPMAPLEVELMASK_ODD, &(ti->info)); + grTexSource(GR_TMU1, ti->tm[FX_TMU1]->startAddr, + GR_MIPMAPLEVELMASK_EVEN, &(ti->info)); + } + else { + if (ti->whichTMU == FX_TMU_BOTH) + tmu = FX_TMU0; + else + tmu = ti->whichTMU; + + /* pointcast */ + if ((ti->info.format == GR_TEXFMT_P_8) + && (!fxMesa->haveGlobalPaletteTexture)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupSingleTMU_NoLock: uploading texture palette\n"); + } + fxMesa->Glide.grTexDownloadTableExt(tmu, ti->paltype, &(ti->palette)); + } + + /* KW: The alternative is to do the download to the other tmu. If + * we get to this point, I think it means we are thrashing the + * texture memory, so perhaps it's not a good idea. + */ + if (ti->LODblend && (TDFX_DEBUG & VERBOSE_DRIVER)) { + fprintf(stderr, "fxSetupSingleTMU_NoLock: not blending texture - only one tmu\n"); + } + + grTexClampMode(tmu, ti->sClamp, ti->tClamp); + grTexFilterMode(tmu, ti->minFilt, ti->maxFilt); + grTexMipMapMode(tmu, ti->mmMode, FXFALSE); + + grTexSource(tmu, ti->tm[tmu]->startAddr, GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + } +} + +static void +fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend) +{ + struct tdfx_texcombine tex0, tex1; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSelectSingleTMUSrc_NoLock(%d, %d)\n", tmu, LODblend); + } + + tex0.InvertRGB = FXFALSE; + tex0.InvertAlpha = FXFALSE; + tex1.InvertRGB = FXFALSE; + tex1.InvertAlpha = FXFALSE; + + if (LODblend) { + tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND; + tex0.FactorRGB = GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND; + tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION; + + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + + fxMesa->tmuSrc = FX_TMU_SPLIT; + } + else { + if (tmu != FX_TMU1) { + tex0.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex0.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex0.FactorAlpha = GR_COMBINE_FACTOR_NONE; + + tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + + fxMesa->tmuSrc = FX_TMU0; + } + else { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + + /* correct values to set TMU0 in passthrough mode */ + tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND; + tex0.FactorRGB = GR_COMBINE_FACTOR_ONE; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND; + tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE; + + fxMesa->tmuSrc = FX_TMU1; + } + } + + grTexCombine(GR_TMU0, + tex0.FunctionRGB, + tex0.FactorRGB, + tex0.FunctionAlpha, + tex0.FactorAlpha, + tex0.InvertRGB, + tex0.InvertAlpha); + if (fxMesa->haveTwoTMUs) { + grTexCombine(GR_TMU1, + tex1.FunctionRGB, + tex1.FactorRGB, + tex1.FunctionAlpha, + tex1.FactorAlpha, + tex1.InvertRGB, + tex1.InvertAlpha); + } +} + +static void +fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + struct tdfx_combine alphaComb, colorComb; + GrCombineLocal_t localc, locala; + GLuint unitsmode; + GLint ifmt; + tfxTexInfo *ti; + struct gl_texture_object *tObj = ctx->Texture.Unit[textureset]._Current; + int tmu; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTextureSingleTMU_NoLock(%d)\n", textureset); + } + + ti = fxTMGetTexInfo(tObj); + + fxTexValidate(ctx, tObj); + + fxSetupSingleTMU_NoLock(fxMesa, tObj); + + if (ti->whichTMU == FX_TMU_BOTH) + tmu = FX_TMU0; + else + tmu = ti->whichTMU; + if (fxMesa->tmuSrc != tmu) + fxSelectSingleTMUSrc_NoLock(fxMesa, tmu, ti->LODblend); + + if (textureset == 0 || !fxMesa->haveTwoTMUs) + unitsmode = fxGetTexSetConfiguration(ctx, tObj, NULL); + else + unitsmode = fxGetTexSetConfiguration(ctx, NULL, tObj); + +/* if(fxMesa->lastUnitsMode==unitsmode) */ +/* return; */ + + fxMesa->lastUnitsMode = unitsmode; + + fxMesa->stw_hint_state = 0; + FX_grHints_NoLock(GR_HINT_STWHINT, 0); + + ifmt = ti->baseLevelInternalFormat; + + if (unitsmode & FX_UM_ALPHA_ITERATED) + locala = GR_COMBINE_LOCAL_ITERATED; + else + locala = GR_COMBINE_LOCAL_CONSTANT; + + if (unitsmode & FX_UM_COLOR_ITERATED) + localc = GR_COMBINE_LOCAL_ITERATED; + else + localc = GR_COMBINE_LOCAL_CONSTANT; + + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fprintf(stderr, "fxSetupTextureSingleTMU_NoLock: envmode is %s\n", + _mesa_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode)); + + alphaComb.Local = locala; + alphaComb.Invert = FXFALSE; + colorComb.Local = localc; + colorComb.Invert = FXFALSE; + + switch (ctx->Texture.Unit[textureset].EnvMode) { + case GL_DECAL: + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; + + colorComb.Function = GR_COMBINE_FUNCTION_BLEND; + colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + break; + case GL_MODULATE: + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + + if (ifmt == GL_ALPHA) { + colorComb.Function = GR_COMBINE_FUNCTION_LOCAL; + colorComb.Factor = GR_COMBINE_FACTOR_NONE; + colorComb.Other = GR_COMBINE_OTHER_NONE; + } else { + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_LOCAL; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + break; + case GL_BLEND: + if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { + /* Av = Af */ + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; + } + else if (ifmt == GL_INTENSITY) { + /* Av = Af * (1 - It) + Ac * It */ + alphaComb.Function = GR_COMBINE_FUNCTION_BLEND; + alphaComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA; + alphaComb.Other = GR_COMBINE_OTHER_CONSTANT; + } + else { + /* Av = Af * At */ + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + + if (ifmt == GL_ALPHA) { + colorComb.Function = GR_COMBINE_FUNCTION_LOCAL; + colorComb.Factor = GR_COMBINE_FACTOR_NONE; + colorComb.Other = GR_COMBINE_OTHER_NONE; + } else { + if (fxMesa->type >= GR_SSTTYPE_Voodoo2) { + colorComb.Function = GR_COMBINE_FUNCTION_BLEND; + colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_RGB; + colorComb.Other = GR_COMBINE_OTHER_CONSTANT; + } else if (ifmt == GL_INTENSITY) { + /* just a hack: RGB == ALPHA */ + colorComb.Function = GR_COMBINE_FUNCTION_BLEND; + colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA; + colorComb.Other = GR_COMBINE_OTHER_CONSTANT; + } else { + /* Only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB) + * These settings assume that the TexEnv color is black and + * incoming fragment color is white. + */ + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + colorComb.Invert = FXTRUE; + _mesa_problem(NULL, "can't GL_BLEND with SST1"); + } + } + + grConstantColorValue( + (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[0] * 255.0f)) ) | + (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[1] * 255.0f)) << 8) | + (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[2] * 255.0f)) << 16) | + (((GLuint)(ctx->Texture.Unit[textureset].EnvColor[3] * 255.0f)) << 24)); + break; + case GL_REPLACE: + if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE)) { + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; + } else { + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_ONE; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + + if (ifmt == GL_ALPHA) { + colorComb.Function = GR_COMBINE_FUNCTION_LOCAL; + colorComb.Factor = GR_COMBINE_FACTOR_NONE; + colorComb.Other = GR_COMBINE_OTHER_NONE; + } else { + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + break; + case GL_ADD: + if (ifmt == GL_ALPHA || + ifmt == GL_LUMINANCE_ALPHA || + ifmt == GL_RGBA) { + /* product of texel and fragment alpha */ + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + else if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { + /* fragment alpha is unchanged */ + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; + } + else { + /* sum of texel and fragment alpha */ + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_ONE; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + + if (ifmt == GL_ALPHA) { + /* rgb unchanged */ + colorComb.Function = GR_COMBINE_FUNCTION_LOCAL; + colorComb.Factor = GR_COMBINE_FACTOR_NONE; + colorComb.Other = GR_COMBINE_OTHER_NONE; + } + else { + /* sum of texel and fragment rgb */ + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + break; + default: + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTextureSingleTMU_NoLock: %x Texture.EnvMode not yet supported\n", + ctx->Texture.Unit[textureset].EnvMode); + } + return; + } + + grAlphaCombine(alphaComb.Function, + alphaComb.Factor, + alphaComb.Local, + alphaComb.Other, + alphaComb.Invert); + grColorCombine(colorComb.Function, + colorComb.Factor, + colorComb.Local, + colorComb.Other, + colorComb.Invert); +} + +#if 00 +static void +fxSetupTextureSingleTMU(GLcontext * ctx, GLuint textureset) +{ + BEGIN_BOARD_LOCK(); + fxSetupTextureSingleTMU_NoLock(ctx, textureset); + END_BOARD_LOCK(); +} +#endif + + +/************************* Double Texture Set ***************************/ + +static void +fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa, + struct gl_texture_object *tObj0, + struct gl_texture_object *tObj1) +{ +#define T0_NOT_IN_TMU 0x01 +#define T1_NOT_IN_TMU 0x02 +#define T0_IN_TMU0 0x04 +#define T1_IN_TMU0 0x08 +#define T0_IN_TMU1 0x10 +#define T1_IN_TMU1 0x20 + + tfxTexInfo *ti0 = fxTMGetTexInfo(tObj0); + tfxTexInfo *ti1 = fxTMGetTexInfo(tObj1); + GLuint tstate = 0; + int tmu0 = 0, tmu1 = 1; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupDoubleTMU_NoLock(...)\n"); + } + + /* We shouldn't need to do this. There is something wrong with + mutlitexturing when the TMUs are swapped. So, we're forcing + them to always be loaded correctly. !!! */ + if (ti0->whichTMU == FX_TMU1) + fxTMMoveOutTM_NoLock(fxMesa, tObj0); + if (ti1->whichTMU == FX_TMU0) + fxTMMoveOutTM_NoLock(fxMesa, tObj1); + + if (ti0->isInTM) { + switch (ti0->whichTMU) { + case FX_TMU0: + tstate |= T0_IN_TMU0; + break; + case FX_TMU1: + tstate |= T0_IN_TMU1; + break; + case FX_TMU_BOTH: + tstate |= T0_IN_TMU0 | T0_IN_TMU1; + break; + case FX_TMU_SPLIT: + tstate |= T0_NOT_IN_TMU; + break; + } + } + else + tstate |= T0_NOT_IN_TMU; + + if (ti1->isInTM) { + switch (ti1->whichTMU) { + case FX_TMU0: + tstate |= T1_IN_TMU0; + break; + case FX_TMU1: + tstate |= T1_IN_TMU1; + break; + case FX_TMU_BOTH: + tstate |= T1_IN_TMU0 | T1_IN_TMU1; + break; + case FX_TMU_SPLIT: + tstate |= T1_NOT_IN_TMU; + break; + } + } + else + tstate |= T1_NOT_IN_TMU; + + ti0->lastTimeUsed = fxMesa->texBindNumber; + ti1->lastTimeUsed = fxMesa->texBindNumber; + + /* Move texture maps into TMUs */ + + if (!(((tstate & T0_IN_TMU0) && (tstate & T1_IN_TMU1)) || + ((tstate & T0_IN_TMU1) && (tstate & T1_IN_TMU0)))) { + if (tObj0 == tObj1) + fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU_BOTH); + else { + /* Find the minimal way to correct the situation */ + if ((tstate & T0_IN_TMU0) || (tstate & T1_IN_TMU1)) { + /* We have one in the standard order, setup the other */ + if (tstate & T0_IN_TMU0) { /* T0 is in TMU0, put T1 in TMU1 */ + fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1); + } + else { + fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0); + } + /* tmu0 and tmu1 are setup */ + } + else if ((tstate & T0_IN_TMU1) || (tstate & T1_IN_TMU0)) { + /* we have one in the reverse order, setup the other */ + if (tstate & T1_IN_TMU0) { /* T1 is in TMU0, put T0 in TMU1 */ + fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU1); + } + else { + fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU0); + } + tmu0 = 1; + tmu1 = 0; + } + else { /* Nothing is loaded */ + fxTMMoveInTM_NoLock(fxMesa, tObj0, FX_TMU0); + fxTMMoveInTM_NoLock(fxMesa, tObj1, FX_TMU1); + /* tmu0 and tmu1 are setup */ + } + } + } + + /* [dBorca] Hack alert: + * we put these in reverse order, so that if we can't + * do _REAL_ pointcast, the TMU0 table gets broadcasted + */ + if (!fxMesa->haveGlobalPaletteTexture) { + /* pointcast */ + if (ti1->info.format == GR_TEXFMT_P_8) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU1\n"); + } + fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, ti1->paltype, &(ti1->palette)); + } + if (ti0->info.format == GR_TEXFMT_P_8) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU0\n"); + } + fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, ti0->paltype, &(ti0->palette)); + } + } + + grTexSource(tmu0, ti0->tm[tmu0]->startAddr, + GR_MIPMAPLEVELMASK_BOTH, &(ti0->info)); + grTexClampMode(tmu0, ti0->sClamp, ti0->tClamp); + grTexFilterMode(tmu0, ti0->minFilt, ti0->maxFilt); + grTexMipMapMode(tmu0, ti0->mmMode, FXFALSE); + + grTexSource(tmu1, ti1->tm[tmu1]->startAddr, + GR_MIPMAPLEVELMASK_BOTH, &(ti1->info)); + grTexClampMode(tmu1, ti1->sClamp, ti1->tClamp); + grTexFilterMode(tmu1, ti1->minFilt, ti1->maxFilt); + grTexMipMapMode(tmu1, ti1->mmMode, FXFALSE); + +#undef T0_NOT_IN_TMU +#undef T1_NOT_IN_TMU +#undef T0_IN_TMU0 +#undef T1_IN_TMU0 +#undef T0_IN_TMU1 +#undef T1_IN_TMU1 +} + +static void +fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + struct tdfx_combine alphaComb, colorComb; + struct tdfx_texcombine tex0, tex1; + GrCombineLocal_t localc, locala; + tfxTexInfo *ti0, *ti1; + struct gl_texture_object *tObj0 = ctx->Texture.Unit[1]._Current; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[0]._Current; + GLuint envmode, ifmt, unitsmode; + int tmu0 = 0, tmu1 = 1; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock(...)\n"); + } + + ti0 = fxTMGetTexInfo(tObj0); + fxTexValidate(ctx, tObj0); + + ti1 = fxTMGetTexInfo(tObj1); + fxTexValidate(ctx, tObj1); + + fxSetupDoubleTMU_NoLock(fxMesa, tObj0, tObj1); + + unitsmode = fxGetTexSetConfiguration(ctx, tObj0, tObj1); + +/* if(fxMesa->lastUnitsMode==unitsmode) */ +/* return; */ + + fxMesa->lastUnitsMode = unitsmode; + + fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1; + FX_grHints_NoLock(GR_HINT_STWHINT, fxMesa->stw_hint_state); + + envmode = unitsmode & FX_UM_E_ENVMODE; + ifmt = unitsmode & FX_UM_E_IFMT; + + if (unitsmode & FX_UM_ALPHA_ITERATED) + locala = GR_COMBINE_LOCAL_ITERATED; + else + locala = GR_COMBINE_LOCAL_CONSTANT; + + if (unitsmode & FX_UM_COLOR_ITERATED) + localc = GR_COMBINE_LOCAL_ITERATED; + else + localc = GR_COMBINE_LOCAL_CONSTANT; + + + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock: envmode is %s/%s\n", + _mesa_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode), + _mesa_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode)); + + + if ((ti0->whichTMU == FX_TMU1) || (ti1->whichTMU == FX_TMU0)) { + tmu0 = 1; + tmu1 = 0; + } + fxMesa->tmuSrc = FX_TMU_BOTH; + + tex0.InvertRGB = FXFALSE; + tex0.InvertAlpha = FXFALSE; + tex1.InvertRGB = FXFALSE; + tex1.InvertAlpha = FXFALSE; + alphaComb.Local = locala; + alphaComb.Invert = FXFALSE; + colorComb.Local = localc; + colorComb.Invert = FXFALSE; + + switch (envmode) { + case (FX_UM_E0_MODULATE | FX_UM_E1_MODULATE): + { + GLboolean isalpha[FX_NUM_TMU]; + + isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA); + isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA); + + if (isalpha[FX_TMU1]) { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + tex1.InvertRGB = FXTRUE; + } else { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + } + + if (isalpha[FX_TMU0]) { + tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorRGB = GR_COMBINE_FACTOR_ONE; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL; + } else { + tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL; + } + + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_LOCAL; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + break; + } + case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND): /* Only for GLQuake */ + if (tmu0 == FX_TMU1) { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + tex1.InvertRGB = FXTRUE; + + tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL; + } + else { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + + tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorRGB = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL; + } + + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; + + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + break; + case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE): /* Quake 2 and 3 */ + if (tmu1 == FX_TMU1) { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + tex1.InvertAlpha = FXTRUE; + + tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorAlpha = GR_COMBINE_FACTOR_LOCAL; + } + else { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + + tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorRGB = GR_COMBINE_FACTOR_LOCAL; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER; + tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE; + } + + if (ti0->baseLevelInternalFormat == GL_RGB) { + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; + } else { + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_ONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; + } + + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + break; + + + case (FX_UM_E0_MODULATE | FX_UM_E1_ADD): /* Quake 3 Sky */ + { + GLboolean isalpha[FX_NUM_TMU]; + + isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA); + isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA); + + if (isalpha[FX_TMU1]) { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + tex1.InvertRGB = FXTRUE; + } else { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + } + + if (isalpha[FX_TMU0]) { + tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER; + tex0.FactorRGB = GR_COMBINE_FACTOR_ONE; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE; + } else { + tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + tex0.FactorRGB = GR_COMBINE_FACTOR_ONE; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE; + } + + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_LOCAL; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + break; + } + + case (FX_UM_E0_REPLACE | FX_UM_E1_ADD): /* Vulpine Sky */ + { + GLboolean isalpha[FX_NUM_TMU]; + + isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA); + isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA); + + if (isalpha[FX_TMU1]) { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + tex1.InvertRGB = FXTRUE; + } else { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + } + + if (isalpha[FX_TMU0]) { + tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER; + tex0.FactorRGB = GR_COMBINE_FACTOR_ONE; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE; + } else { + tex0.FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + tex0.FactorRGB = GR_COMBINE_FACTOR_ONE; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + tex0.FactorAlpha = GR_COMBINE_FACTOR_ONE; + } + + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_ONE; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + break; + } + + case (FX_UM_E0_MODULATE | FX_UM_E1_REPLACE): /* Homeworld2 */ + { + tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + + tex0.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex0.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex0.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex0.FactorAlpha = GR_COMBINE_FACTOR_NONE; + + if (ifmt & (FX_UM_E0_RGB | FX_UM_E0_LUMINANCE)) { + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; + } else { + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_ONE; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + + if (ifmt & FX_UM_E0_ALPHA) { + colorComb.Function = GR_COMBINE_FUNCTION_LOCAL; + colorComb.Factor = GR_COMBINE_FACTOR_NONE; + colorComb.Other = GR_COMBINE_OTHER_NONE; + } else { + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + break; + } + default: + fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock: Unexpected dual texture mode encountered\n"); + return; + } + + grAlphaCombine(alphaComb.Function, + alphaComb.Factor, + alphaComb.Local, + alphaComb.Other, + alphaComb.Invert); + grColorCombine(colorComb.Function, + colorComb.Factor, + colorComb.Local, + colorComb.Other, + colorComb.Invert); + grTexCombine(GR_TMU0, + tex0.FunctionRGB, + tex0.FactorRGB, + tex0.FunctionAlpha, + tex0.FactorAlpha, + tex0.InvertRGB, + tex0.InvertAlpha); + grTexCombine(GR_TMU1, + tex1.FunctionRGB, + tex1.FactorRGB, + tex1.FunctionAlpha, + tex1.FactorAlpha, + tex1.InvertRGB, + tex1.InvertAlpha); +} + +/************************* No Texture ***************************/ + +static void +fxSetupTextureNone_NoLock(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrCombineLocal_t localc, locala; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTextureNone_NoLock(...)\n"); + } + + if ((ctx->Light.ShadeModel == GL_SMOOTH) || 1 || + (ctx->Point.SmoothFlag) || + (ctx->Line.SmoothFlag) || + (ctx->Polygon.SmoothFlag)) locala = GR_COMBINE_LOCAL_ITERATED; + else + locala = GR_COMBINE_LOCAL_CONSTANT; + + if (ctx->Light.ShadeModel == GL_SMOOTH || 1) + localc = GR_COMBINE_LOCAL_ITERATED; + else + localc = GR_COMBINE_LOCAL_CONSTANT; + + grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + locala, + GR_COMBINE_OTHER_NONE, + FXFALSE); + + grColorCombine(GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + localc, + GR_COMBINE_OTHER_NONE, + FXFALSE); + + fxMesa->lastUnitsMode = FX_UM_NONE; +} + +#include "fxsetup.h" + +/************************************************************************/ +/************************** Texture Mode SetUp **************************/ +/************************************************************************/ + +static void +fxSetupTexture_NoLock(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTexture_NoLock(...)\n"); + } + + if (fxMesa->HaveCmbExt) { + /* Texture Combine, Color Combine and Alpha Combine. */ + if ((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) && + (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) && + fxMesa->haveTwoTMUs) { + fxSetupTextureDoubleTMUNapalm_NoLock(ctx); + } + else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { + fxSetupTextureSingleTMUNapalm_NoLock(ctx, 0); + } + else if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { + fxSetupTextureSingleTMUNapalm_NoLock(ctx, 1); + } + else { + fxSetupTextureNoneNapalm_NoLock(ctx); + } + } else { + /* Texture Combine, Color Combine and Alpha Combine. */ + if ((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) && + (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) && + fxMesa->haveTwoTMUs) { + fxSetupTextureDoubleTMU_NoLock(ctx); + } + else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { + fxSetupTextureSingleTMU_NoLock(ctx, 0); + } + else if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { + fxSetupTextureSingleTMU_NoLock(ctx, 1); + } + else { + fxSetupTextureNone_NoLock(ctx); + } + } +} + +void +fxSetupTexture(GLcontext * ctx) +{ + BEGIN_BOARD_LOCK(); + fxSetupTexture_NoLock(ctx); + END_BOARD_LOCK(); +} + +/************************************************************************/ +/**************************** Blend SetUp *******************************/ +/************************************************************************/ + +void +fxDDBlendFuncSeparate(GLcontext * ctx, GLenum sfactor, GLenum dfactor, GLenum asfactor, GLenum adfactor) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + GLboolean isNapalm = (fxMesa->type >= GR_SSTTYPE_Voodoo4); + GLboolean have32bpp = (fxMesa->colDepth == 32); + GLboolean haveAlpha = fxMesa->haveHwAlpha; + GrAlphaBlendFnc_t sfact, dfact, asfact, adfact; + + /* + * 15/16 BPP alpha channel alpha blending modes + * 0x0 AZERO Zero + * 0x4 AONE One + * + * 32 BPP alpha channel alpha blending modes + * 0x0 AZERO Zero + * 0x1 ASRC_ALPHA Source alpha + * 0x3 ADST_ALPHA Destination alpha + * 0x4 AONE One + * 0x5 AOMSRC_ALPHA 1 - Source alpha + * 0x7 AOMDST_ALPHA 1 - Destination alpha + * + * If we don't have HW alpha buffer: + * DST_ALPHA == 1 + * ONE_MINUS_DST_ALPHA == 0 + * Unsupported modes are: + * 1 if used as src blending factor + * 0 if used as dst blending factor + */ + + switch (sfactor) { + case GL_ZERO: + sfact = GR_BLEND_ZERO; + break; + case GL_ONE: + sfact = GR_BLEND_ONE; + break; + case GL_DST_COLOR: + sfact = GR_BLEND_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + sfact = GR_BLEND_ONE_MINUS_DST_COLOR; + break; + case GL_SRC_ALPHA: + sfact = GR_BLEND_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + sfact = GR_BLEND_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + sfact = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_ONE_MINUS_DST_ALPHA: + sfact = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/; + break; + case GL_SRC_ALPHA_SATURATE: + sfact = GR_BLEND_ALPHA_SATURATE; + break; + case GL_SRC_COLOR: + if (isNapalm) { + sfact = GR_BLEND_SAME_COLOR_EXT; + break; + } + case GL_ONE_MINUS_SRC_COLOR: + if (isNapalm) { + sfact = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT; + break; + } + default: + sfact = GR_BLEND_ONE; + break; + } + + switch (asfactor) { + case GL_ZERO: + asfact = GR_BLEND_ZERO; + break; + case GL_ONE: + asfact = GR_BLEND_ONE; + break; + case GL_SRC_COLOR: + case GL_SRC_ALPHA: + asfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_ONE_MINUS_SRC_COLOR: + case GL_ONE_MINUS_SRC_ALPHA: + asfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_DST_COLOR: + case GL_DST_ALPHA: + asfact = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_ONE_MINUS_DST_COLOR: + case GL_ONE_MINUS_DST_ALPHA: + asfact = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/; + break; + case GL_SRC_ALPHA_SATURATE: + asfact = GR_BLEND_ONE; + break; + default: + asfact = GR_BLEND_ONE; + break; + } + + switch (dfactor) { + case GL_ZERO: + dfact = GR_BLEND_ZERO; + break; + case GL_ONE: + dfact = GR_BLEND_ONE; + break; + case GL_SRC_COLOR: + dfact = GR_BLEND_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + dfact = GR_BLEND_ONE_MINUS_SRC_COLOR; + break; + case GL_SRC_ALPHA: + dfact = GR_BLEND_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dfact = GR_BLEND_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + dfact = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_ONE_MINUS_DST_ALPHA: + dfact = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/; + break; + case GL_DST_COLOR: + if (isNapalm) { + dfact = GR_BLEND_SAME_COLOR_EXT; + break; + } + case GL_ONE_MINUS_DST_COLOR: + if (isNapalm) { + dfact = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT; + break; + } + default: + dfact = GR_BLEND_ZERO; + break; + } + + switch (adfactor) { + case GL_ZERO: + adfact = GR_BLEND_ZERO; + break; + case GL_ONE: + adfact = GR_BLEND_ONE; + break; + case GL_SRC_COLOR: + case GL_SRC_ALPHA: + adfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*bad*/; + break; + case GL_ONE_MINUS_SRC_COLOR: + case GL_ONE_MINUS_SRC_ALPHA: + adfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*bad*/; + break; + case GL_DST_COLOR: + case GL_DST_ALPHA: + adfact = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_ONE_MINUS_DST_COLOR: + case GL_ONE_MINUS_DST_ALPHA: + adfact = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/; + break; + default: + adfact = GR_BLEND_ZERO; + break; + } + + if ((sfact != us->blendSrcFuncRGB) || (asfact != us->blendSrcFuncAlpha)) { + us->blendSrcFuncRGB = sfact; + us->blendSrcFuncAlpha = asfact; + fxMesa->new_state |= FX_NEW_BLEND; + } + + if ((dfact != us->blendDstFuncRGB) || (adfact != us->blendDstFuncAlpha)) { + us->blendDstFuncRGB = dfact; + us->blendDstFuncAlpha = adfact; + fxMesa->new_state |= FX_NEW_BLEND; + } +} + +void +fxDDBlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + GrAlphaBlendOp_t q; + + switch (modeRGB) { + case GL_FUNC_ADD: + q = GR_BLEND_OP_ADD; + break; + case GL_FUNC_SUBTRACT: + q = GR_BLEND_OP_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + q = GR_BLEND_OP_REVSUB; + break; + default: + q = us->blendEqRGB; + } + if (q != us->blendEqRGB) { + us->blendEqRGB = q; + fxMesa->new_state |= FX_NEW_BLEND; + } + + switch (modeA) { + case GL_FUNC_ADD: + q = GR_BLEND_OP_ADD; + break; + case GL_FUNC_SUBTRACT: + q = GR_BLEND_OP_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + q = GR_BLEND_OP_REVSUB; + break; + default: + q = us->blendEqAlpha; + } + if (q != us->blendEqAlpha) { + us->blendEqAlpha = q; + fxMesa->new_state |= FX_NEW_BLEND; + } +} + +void +fxSetupBlend(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (fxMesa->HavePixExt) { + if (us->blendEnabled) { + fxMesa->Glide.grAlphaBlendFunctionExt(us->blendSrcFuncRGB, us->blendDstFuncRGB, + us->blendEqRGB, + us->blendSrcFuncAlpha, us->blendDstFuncAlpha, + us->blendEqAlpha); + } else { + fxMesa->Glide.grAlphaBlendFunctionExt(GR_BLEND_ONE, GR_BLEND_ZERO, + GR_BLEND_OP_ADD, + GR_BLEND_ONE, GR_BLEND_ZERO, + GR_BLEND_OP_ADD); + } + } else { + if (us->blendEnabled) { + grAlphaBlendFunction(us->blendSrcFuncRGB, us->blendDstFuncRGB, + us->blendSrcFuncAlpha, us->blendDstFuncAlpha); + } else { + grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, + GR_BLEND_ONE, GR_BLEND_ZERO); + } + } +} + +/************************************************************************/ +/************************** Alpha Test SetUp ****************************/ +/************************************************************************/ + +void +fxDDAlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if ( + (us->alphaTestFunc != func) + || + (us->alphaTestRefValue != ref) + ) { + us->alphaTestFunc = func; + us->alphaTestRefValue = ref; + fxMesa->new_state |= FX_NEW_ALPHA; + } +} + +static void +fxSetupAlphaTest(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (us->alphaTestEnabled) { + GrAlpha_t ref = (GLint) (us->alphaTestRefValue * 255.0); + grAlphaTestFunction(us->alphaTestFunc - GL_NEVER + GR_CMP_NEVER); + grAlphaTestReferenceValue(ref); + } + else + grAlphaTestFunction(GR_CMP_ALWAYS); +} + +/************************************************************************/ +/************************** Depth Test SetUp ****************************/ +/************************************************************************/ + +void +fxDDDepthFunc(GLcontext * ctx, GLenum func) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (us->depthTestFunc != func) { + us->depthTestFunc = func; + fxMesa->new_state |= FX_NEW_DEPTH; + } +} + +void +fxDDDepthMask(GLcontext * ctx, GLboolean flag) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (flag != us->depthMask) { + us->depthMask = flag; + fxMesa->new_state |= FX_NEW_DEPTH; + } +} + +void +fxSetupDepthTest(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (us->depthTestEnabled) { + grDepthBufferFunction(us->depthTestFunc - GL_NEVER + GR_CMP_NEVER); + grDepthMask(us->depthMask); + } + else { + grDepthBufferFunction(GR_CMP_ALWAYS); + grDepthMask(FXFALSE); + } +} + +/************************************************************************/ +/************************** Stencil SetUp *******************************/ +/************************************************************************/ + +static GrStencil_t convertGLStencilOp( GLenum op ) +{ + switch ( op ) { + case GL_KEEP: + return GR_STENCILOP_KEEP; + case GL_ZERO: + return GR_STENCILOP_ZERO; + case GL_REPLACE: + return GR_STENCILOP_REPLACE; + case GL_INCR: + return GR_STENCILOP_INCR_CLAMP; + case GL_DECR: + return GR_STENCILOP_DECR_CLAMP; + case GL_INVERT: + return GR_STENCILOP_INVERT; + case GL_INCR_WRAP_EXT: + return GR_STENCILOP_INCR_WRAP; + case GL_DECR_WRAP_EXT: + return GR_STENCILOP_DECR_WRAP; + default: + _mesa_problem( NULL, "bad stencil op in convertGLStencilOp" ); + } + return GR_STENCILOP_KEEP; /* never get, silence compiler warning */ +} + +void +fxDDStencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (ctx->Stencil.ActiveFace) { + return; + } + + if ( + (us->stencilFunction != func) + || + (us->stencilRefValue != ref) + || + (us->stencilValueMask != mask) + ) { + us->stencilFunction = func; + us->stencilRefValue = ref; + us->stencilValueMask = mask; + fxMesa->new_state |= FX_NEW_STENCIL; + } +} + +void +fxDDStencilMask (GLcontext *ctx, GLuint mask) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (ctx->Stencil.ActiveFace) { + return; + } + + if (us->stencilWriteMask != mask) { + us->stencilWriteMask = mask; + fxMesa->new_state |= FX_NEW_STENCIL; + } +} + +void +fxDDStencilOp (GLcontext *ctx, GLenum sfail, GLenum zfail, GLenum zpass) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (ctx->Stencil.ActiveFace) { + return; + } + + if ( + (us->stencilFailFunc != sfail) + || + (us->stencilZFailFunc != zfail) + || + (us->stencilZPassFunc != zpass) + ) { + us->stencilFailFunc = sfail; + us->stencilZFailFunc = zfail; + us->stencilZPassFunc = zpass; + fxMesa->new_state |= FX_NEW_STENCIL; + } +} + +void +fxSetupStencil (GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (us->stencilEnabled) { + GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP; + GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP; + GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP; + if (!fxMesa->multipass) { + stencilFailFunc = convertGLStencilOp(us->stencilFailFunc); + stencilZFailFunc = convertGLStencilOp(us->stencilZFailFunc); + stencilZPassFunc = convertGLStencilOp(us->stencilZPassFunc); + } + grEnable(GR_STENCIL_MODE_EXT); + fxMesa->Glide.grStencilOpExt(stencilFailFunc, + stencilZFailFunc, + stencilZPassFunc); + fxMesa->Glide.grStencilFuncExt(us->stencilFunction - GL_NEVER + GR_CMP_NEVER, + us->stencilRefValue, + us->stencilValueMask); + fxMesa->Glide.grStencilMaskExt(us->stencilWriteMask); + } else { + grDisable(GR_STENCIL_MODE_EXT); + } +} + +void +fxSetupStencilFace (GLcontext * ctx, GLint face) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (us->stencilEnabled) { + GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP; + GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP; + GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP; + if (!fxMesa->multipass) { + stencilFailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[face]); + stencilZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[face]); + stencilZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[face]); + } + grEnable(GR_STENCIL_MODE_EXT); + fxMesa->Glide.grStencilOpExt(stencilFailFunc, + stencilZFailFunc, + stencilZPassFunc); + fxMesa->Glide.grStencilFuncExt(ctx->Stencil.Function[face] - GL_NEVER + GR_CMP_NEVER, + ctx->Stencil.Ref[face], + ctx->Stencil.ValueMask[face]); + fxMesa->Glide.grStencilMaskExt(ctx->Stencil.WriteMask[face]); + } else { + grDisable(GR_STENCIL_MODE_EXT); + } +} + +/************************************************************************/ +/**************************** Color Mask SetUp **************************/ +/************************************************************************/ + +void +fxDDColorMask(GLcontext * ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + fxMesa->new_state |= FX_NEW_COLOR_MASK; + (void) r; + (void) g; + (void) b; + (void) a; +} + +void +fxSetupColorMask(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (fxMesa->colDepth == 32) { + /* 32bpp mode */ + fxMesa->Glide.grColorMaskExt(ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha); + } + else { + /* 15/16 bpp mode */ + grColorMask(ctx->Color.ColorMask[RCOMP] | + ctx->Color.ColorMask[GCOMP] | + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha); + } +} + + + + +/************************************************************************/ +/**************************** Fog Mode SetUp ****************************/ +/************************************************************************/ + +/* + * This is called during state update in order to update the Glide fog state. + */ +static void +fxSetupFog(GLcontext * ctx) +{ + if (ctx->Fog.Enabled /*&& ctx->FogMode==FOG_FRAGMENT */ ) { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + /* update fog color */ + GLubyte col[4]; + col[0] = (unsigned int) (255 * ctx->Fog.Color[0]); + col[1] = (unsigned int) (255 * ctx->Fog.Color[1]); + col[2] = (unsigned int) (255 * ctx->Fog.Color[2]); + col[3] = (unsigned int) (255 * ctx->Fog.Color[3]); + grFogColorValue(FXCOLOR4(col)); + + if (fxMesa->fogTableMode != ctx->Fog.Mode || + fxMesa->fogDensity != ctx->Fog.Density || + fxMesa->fogStart != ctx->Fog.Start || + fxMesa->fogEnd != ctx->Fog.End) { + /* reload the fog table */ + switch (ctx->Fog.Mode) { + case GL_LINEAR: + guFogGenerateLinear(fxMesa->fogTable, ctx->Fog.Start, + ctx->Fog.End); + if (fxMesa->fogTable[0] > 63) { + /* [dBorca] Hack alert: + * As per Glide3 Programming Guide: + * The difference between consecutive fog values + * must be less than 64. + */ + fxMesa->fogTable[0] = 63; + } + break; + case GL_EXP: + guFogGenerateExp(fxMesa->fogTable, ctx->Fog.Density); + break; + case GL_EXP2: + guFogGenerateExp2(fxMesa->fogTable, ctx->Fog.Density); + break; + default: + ; + } + fxMesa->fogTableMode = ctx->Fog.Mode; + fxMesa->fogDensity = ctx->Fog.Density; + fxMesa->fogStart = ctx->Fog.Start; + fxMesa->fogEnd = ctx->Fog.End; + } + + grFogTable(fxMesa->fogTable); + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2, + GR_PARAM_ENABLE); + grFogMode(GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + } else { + grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2, + GR_PARAM_DISABLE); + grFogMode(GR_FOG_WITH_TABLE_ON_Q); + } + } + else { + grFogMode(GR_FOG_DISABLE); + } +} + +void +fxDDFogfv(GLcontext * ctx, GLenum pname, const GLfloat * params) +{ + FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG; + switch (pname) { + case GL_FOG_COORDINATE_SOURCE_EXT: { + GLenum p = (GLenum)*params; + if (p == GL_FOG_COORDINATE_EXT) { + _swrast_allow_vertex_fog(ctx, GL_TRUE); + _swrast_allow_pixel_fog(ctx, GL_FALSE); + _tnl_allow_vertex_fog( ctx, GL_TRUE); + _tnl_allow_pixel_fog( ctx, GL_FALSE); + } else { + _swrast_allow_vertex_fog(ctx, GL_FALSE); + _swrast_allow_pixel_fog(ctx, GL_TRUE); + _tnl_allow_vertex_fog( ctx, GL_FALSE); + _tnl_allow_pixel_fog( ctx, GL_TRUE); + } + break; + } + default: + ; + } +} + +/************************************************************************/ +/************************** Scissor Test SetUp **************************/ +/************************************************************************/ + +/* This routine is used in managing the lock state, and therefore can't lock */ +void +fxSetScissorValues(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + int xmin, xmax; + int ymin, ymax; + + if (ctx->Scissor.Enabled) { + xmin = ctx->Scissor.X; + xmax = ctx->Scissor.X + ctx->Scissor.Width; + ymin = ctx->Scissor.Y; + ymax = ctx->Scissor.Y + ctx->Scissor.Height; + + if (xmin < 0) + xmin = 0; + if (xmax > fxMesa->width) + xmax = fxMesa->width; + if (ymin < fxMesa->screen_height - fxMesa->height) + ymin = fxMesa->screen_height - fxMesa->height; + if (ymax > fxMesa->screen_height - 0) + ymax = fxMesa->screen_height - 0; + } + else { + xmin = 0; + ymin = 0; + xmax = fxMesa->width; + ymax = fxMesa->height; + } + + fxMesa->clipMinX = xmin; + fxMesa->clipMinY = ymin; + fxMesa->clipMaxX = xmax; + fxMesa->clipMaxY = ymax; + grClipWindow(xmin, ymin, xmax, ymax); +} + +void +fxSetupScissor(GLcontext * ctx) +{ + BEGIN_BOARD_LOCK(); + fxSetScissorValues(ctx); + END_BOARD_LOCK(); +} + +void +fxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + FX_CONTEXT(ctx)->new_state |= FX_NEW_SCISSOR; +} + +/************************************************************************/ +/*************************** Cull mode setup ****************************/ +/************************************************************************/ + + +void +fxDDCullFace(GLcontext * ctx, GLenum mode) +{ + (void) mode; + FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL; +} + +void +fxDDFrontFace(GLcontext * ctx, GLenum mode) +{ + (void) mode; + FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL; +} + + +void +fxSetupCull(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrCullMode_t mode = GR_CULL_DISABLE; + + if (ctx->Polygon.CullFlag && (fxMesa->raster_primitive == GL_TRIANGLES)) { + switch (ctx->Polygon.CullFaceMode) { + case GL_BACK: + if (ctx->Polygon.FrontFace == GL_CCW) + mode = GR_CULL_NEGATIVE; + else + mode = GR_CULL_POSITIVE; + break; + case GL_FRONT: + if (ctx->Polygon.FrontFace == GL_CCW) + mode = GR_CULL_POSITIVE; + else + mode = GR_CULL_NEGATIVE; + break; + case GL_FRONT_AND_BACK: + /* Handled as a fallback on triangles in tdfx_tris.c */ + return; + default: + ASSERT(0); + break; + } + } + + if (fxMesa->cullMode != mode) { + fxMesa->cullMode = mode; + grCullMode(mode); + } +} + + +/************************************************************************/ +/****************************** DD Enable ******************************/ +/************************************************************************/ + +void +fxDDEnable(GLcontext * ctx, GLenum cap, GLboolean state) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s(%s)\n", state ? "fxDDEnable" : "fxDDDisable", + _mesa_lookup_enum_by_nr(cap)); + } + + switch (cap) { + case GL_ALPHA_TEST: + if (state != us->alphaTestEnabled) { + us->alphaTestEnabled = state; + fxMesa->new_state |= FX_NEW_ALPHA; + } + break; + case GL_BLEND: + if (state != us->blendEnabled) { + us->blendEnabled = state; + fxMesa->new_state |= FX_NEW_BLEND; + } + break; + case GL_DEPTH_TEST: + if (state != us->depthTestEnabled) { + us->depthTestEnabled = state; + fxMesa->new_state |= FX_NEW_DEPTH; + } + break; + case GL_STENCIL_TEST: + if (fxMesa->haveHwStencil && state != us->stencilEnabled) { + us->stencilEnabled = state; + fxMesa->new_state |= FX_NEW_STENCIL; + } + break; + case GL_DITHER: + if (state) { + grDitherMode(GR_DITHER_4x4); + } + else { + grDitherMode(GR_DITHER_DISABLE); + } + break; + case GL_SCISSOR_TEST: + fxMesa->new_state |= FX_NEW_SCISSOR; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + fxDDTexUseGlbPalette(ctx, state); + break; + case GL_FOG: + fxMesa->new_state |= FX_NEW_FOG; + break; + case GL_CULL_FACE: + fxMesa->new_state |= FX_NEW_CULL; + break; + case GL_LINE_SMOOTH: + case GL_LINE_STIPPLE: + case GL_POINT_SMOOTH: + case GL_POLYGON_SMOOTH: + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + fxMesa->new_state |= FX_NEW_TEXTURING; + break; + default: + ; /* XXX no-op? */ + } +} + + + + +/************************************************************************/ +/************************** Changes to units state **********************/ +/************************************************************************/ + + +/* All units setup is handled under texture setup. + */ +void +fxDDShadeModel(GLcontext * ctx, GLenum mode) +{ + FX_CONTEXT(ctx)->new_state |= FX_NEW_TEXTURING; +} + + + +/************************************************************************/ +/****************************** Units SetUp *****************************/ +/************************************************************************/ +static void +fx_print_state_flags(const char *msg, GLuint flags) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & FX_NEW_TEXTURING) ? "texture, " : "", + (flags & FX_NEW_BLEND) ? "blend, " : "", + (flags & FX_NEW_ALPHA) ? "alpha, " : "", + (flags & FX_NEW_FOG) ? "fog, " : "", + (flags & FX_NEW_SCISSOR) ? "scissor, " : "", + (flags & FX_NEW_COLOR_MASK) ? "colormask, " : "", + (flags & FX_NEW_CULL) ? "cull, " : "", + (flags & FX_NEW_STENCIL) ? "stencil, " : ""); +} + +void +fxSetupFXUnits(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint newstate = fxMesa->new_state; + + if (TDFX_DEBUG & VERBOSE_DRIVER) + fx_print_state_flags("fxSetupFXUnits", newstate); + + if (newstate) { + if (newstate & FX_NEW_TEXTURING) + fxSetupTexture(ctx); + + if (newstate & FX_NEW_BLEND) + fxSetupBlend(ctx); + + if (newstate & FX_NEW_ALPHA) + fxSetupAlphaTest(ctx); + + if (newstate & FX_NEW_DEPTH) + fxSetupDepthTest(ctx); + + if (newstate & FX_NEW_STENCIL) + fxSetupStencil(ctx); + + if (newstate & FX_NEW_FOG) + fxSetupFog(ctx); + + if (newstate & FX_NEW_SCISSOR) + fxSetupScissor(ctx); + + if (newstate & FX_NEW_COLOR_MASK) + fxSetupColorMask(ctx); + + if (newstate & FX_NEW_CULL) + fxSetupCull(ctx); + + fxMesa->new_state = 0; + } +} + + + +#else + + +/* + * Need this to provide at least one external definition. + */ + +extern int gl_fx_dummy_function_setup(void); +int +gl_fx_dummy_function_setup(void) +{ + return 0; +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.h b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.h new file mode 100644 index 000000000..9d337d4b0 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.h @@ -0,0 +1,850 @@ +/* + * 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 + */ + +/* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */ +/* This code belongs to fxsetup.c, but I didn't want to clutter + * the original code with Napalm specifics, in order to keep things + * clear -- especially for backward compatibility. I should have + * put it into another .c file, but I didn't want to export so many + * things... + * The point is, Napalm uses a different technique for texture env. + * SST1 Single texturing: + * setup standard grTexCombine + * fiddle with grColorCombine/grAlphaCombine + * SST1 Multi texturing: + * fiddle with grTexCombine/grColorCombine/grAlphaCombine + * Napalm Single texturing: + * setup standard grColorCombineExt/grAlphaCombineExt + * fiddle with grTexColorCombine/grTexAlphaCombine + * Napalm Multi texturing: + * setup standard grColorCombineExt/grAlphaCombineExt + * fiddle with grTexColorCombine/grTexAlphaCombine + */ + +/* + * These macros are used below when handling COMBINE_EXT. + */ +#define TEXENV_OPERAND_INVERTED(operand) \ + (((operand) == GL_ONE_MINUS_SRC_ALPHA) \ + || ((operand) == GL_ONE_MINUS_SRC_COLOR)) +#define TEXENV_OPERAND_ALPHA(operand) \ + (((operand) == GL_SRC_ALPHA) || ((operand) == GL_ONE_MINUS_SRC_ALPHA)) +#define TEXENV_SETUP_ARG_A(param, source, operand, iteratedAlpha) \ + switch (source) { \ + case GL_TEXTURE: \ + param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \ + break; \ + case GL_CONSTANT_EXT: \ + param = GR_CMBX_TMU_CALPHA; \ + break; \ + case GL_PRIMARY_COLOR_EXT: \ + param = GR_CMBX_ITALPHA; \ + break; \ + case GL_PREVIOUS_EXT: \ + param = iteratedAlpha; \ + break; \ + default: \ + /* \ + * This is here just to keep from getting \ + * compiler warnings. \ + */ \ + param = GR_CMBX_ZERO; \ + break; \ + } + +#define TEXENV_SETUP_ARG_RGB(param, source, operand, iteratedColor, iteratedAlpha) \ + if (!TEXENV_OPERAND_ALPHA(operand)) { \ + switch (source) { \ + case GL_TEXTURE: \ + param = GR_CMBX_LOCAL_TEXTURE_RGB; \ + break; \ + case GL_CONSTANT_EXT: \ + param = GR_CMBX_TMU_CCOLOR; \ + break; \ + case GL_PRIMARY_COLOR_EXT: \ + param = GR_CMBX_ITRGB; \ + break; \ + case GL_PREVIOUS_EXT: \ + param = iteratedColor; \ + break; \ + default: \ + /* \ + * This is here just to keep from getting \ + * compiler warnings. \ + */ \ + param = GR_CMBX_ZERO; \ + break; \ + } \ + } else { \ + switch (source) { \ + case GL_TEXTURE: \ + param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \ + break; \ + case GL_CONSTANT_EXT: \ + param = GR_CMBX_TMU_CALPHA; \ + break; \ + case GL_PRIMARY_COLOR_EXT: \ + param = GR_CMBX_ITALPHA; \ + break; \ + case GL_PREVIOUS_EXT: \ + param = iteratedAlpha; \ + break; \ + default: \ + /* \ + * This is here just to keep from getting \ + * compiler warnings. \ + */ \ + param = GR_CMBX_ZERO; \ + break; \ + } \ + } + +#define TEXENV_SETUP_MODE_RGB(param, operand) \ + switch (operand) { \ + case GL_SRC_COLOR: \ + case GL_SRC_ALPHA: \ + param = GR_FUNC_MODE_X; \ + break; \ + case GL_ONE_MINUS_SRC_ALPHA: \ + case GL_ONE_MINUS_SRC_COLOR: \ + param = GR_FUNC_MODE_ONE_MINUS_X; \ + break; \ + default: \ + param = GR_FUNC_MODE_ZERO; \ + break; \ + } + +#define TEXENV_SETUP_MODE_A(param, operand) \ + switch (operand) { \ + case GL_SRC_ALPHA: \ + param = GR_FUNC_MODE_X; \ + break; \ + case GL_ONE_MINUS_SRC_ALPHA: \ + param = GR_FUNC_MODE_ONE_MINUS_X; \ + break; \ + default: \ + param = GR_FUNC_MODE_ZERO; \ + break; \ + } + +static void +fxSetupTextureEnvNapalm_NoLock(GLcontext * ctx, GLuint textureset, GLuint tmu, GLboolean iterated) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[textureset]; + struct tdfx_combine_alpha_ext alphaComb; + struct tdfx_combine_color_ext colorComb; + const GLfloat *envColor = texUnit->EnvColor; + GrCombineLocal_t localc, locala; /* fragmentColor/Alpha */ + GLint ifmt; + tfxTexInfo *ti; + struct gl_texture_object *tObj = texUnit->_Current; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTextureEnvNapalm_NoLock(unit %u, TMU %u, iterated %d)\n", + textureset, tmu, iterated); + } + + ti = fxTMGetTexInfo(tObj); + + ifmt = ti->baseLevelInternalFormat; + + if (iterated) { + /* we don't have upstream TMU */ + locala = GR_CMBX_ITALPHA; + localc = GR_CMBX_ITRGB; + } else { + /* we have upstream TMU */ + locala = GR_CMBX_OTHER_TEXTURE_ALPHA; + localc = GR_CMBX_OTHER_TEXTURE_RGB; + } + + alphaComb.InvertD = FXFALSE; + alphaComb.Shift = 0; + alphaComb.Invert = FXFALSE; + colorComb.InvertD = FXFALSE; + colorComb.Shift = 0; + colorComb.Invert = FXFALSE; + + switch (texUnit->EnvMode) { + case GL_DECAL: + alphaComb.SourceA = locala; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_ZERO; + alphaComb.InvertC = FXTRUE; + alphaComb.SourceD = GR_CMBX_ZERO; + + colorComb.SourceA = GR_CMBX_LOCAL_TEXTURE_RGB; + colorComb.ModeA = GR_FUNC_MODE_X; + colorComb.SourceB = localc; + colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X; + colorComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; + colorComb.InvertC = FXFALSE; + colorComb.SourceD = GR_CMBX_B; + break; + case GL_MODULATE: + if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { + alphaComb.SourceA = locala; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_ZERO; + alphaComb.InvertC = FXTRUE; + alphaComb.SourceD = GR_CMBX_ZERO; + } else { + alphaComb.SourceA = locala; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; + alphaComb.InvertC = FXFALSE; + alphaComb.SourceD = GR_CMBX_ZERO; + } + + if (ifmt == GL_ALPHA) { + colorComb.SourceA = localc; + colorComb.ModeA = GR_FUNC_MODE_X; + colorComb.SourceB = GR_CMBX_ZERO; + colorComb.ModeB = GR_FUNC_MODE_X; + colorComb.SourceC = GR_CMBX_ZERO; + colorComb.InvertC = FXTRUE; + colorComb.SourceD = GR_CMBX_ZERO; + } else { + colorComb.SourceA = localc; + colorComb.ModeA = GR_FUNC_MODE_X; + colorComb.SourceB = GR_CMBX_ZERO; + colorComb.ModeB = GR_FUNC_MODE_X; + colorComb.SourceC = GR_CMBX_LOCAL_TEXTURE_RGB; + colorComb.InvertC = FXFALSE; + colorComb.SourceD = GR_CMBX_ZERO; + } + break; + case GL_BLEND: + if (ifmt == GL_INTENSITY) { + alphaComb.SourceA = GR_CMBX_TMU_CALPHA; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = locala; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; + alphaComb.InvertC = FXFALSE; + alphaComb.SourceD = GR_CMBX_ZERO; + } else { + alphaComb.SourceA = locala; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; + alphaComb.InvertC = FXFALSE; + alphaComb.SourceD = GR_CMBX_ZERO; + } + + if (ifmt == GL_ALPHA) { + colorComb.SourceA = localc; + colorComb.ModeA = GR_FUNC_MODE_X; + colorComb.SourceB = GR_CMBX_ZERO; + colorComb.ModeB = GR_FUNC_MODE_X; + colorComb.SourceC = GR_CMBX_ZERO; + colorComb.InvertC = FXTRUE; + colorComb.SourceD = GR_CMBX_ZERO; + } else { + colorComb.SourceA = GR_CMBX_TMU_CCOLOR; + colorComb.ModeA = GR_FUNC_MODE_X; + colorComb.SourceB = localc; + colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X; + colorComb.SourceC = GR_CMBX_LOCAL_TEXTURE_RGB; + colorComb.InvertC = FXFALSE; + colorComb.SourceD = GR_CMBX_B; + } + + fxMesa->Glide.grConstantColorValueExt(tmu, + (((GLuint)(envColor[0] * 255.0f)) ) | + (((GLuint)(envColor[1] * 255.0f)) << 8) | + (((GLuint)(envColor[2] * 255.0f)) << 16) | + (((GLuint)(envColor[3] * 255.0f)) << 24)); + break; + case GL_REPLACE: + if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { + alphaComb.SourceA = locala; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_ZERO; + alphaComb.InvertC = FXTRUE; + alphaComb.SourceD = GR_CMBX_ZERO; + } else { + alphaComb.SourceA = GR_CMBX_LOCAL_TEXTURE_ALPHA; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_ZERO; + alphaComb.InvertC = FXTRUE; + alphaComb.SourceD = GR_CMBX_ZERO; + } + + if (ifmt == GL_ALPHA) { + colorComb.SourceA = localc; + colorComb.ModeA = GR_FUNC_MODE_X; + colorComb.SourceB = GR_CMBX_ZERO; + colorComb.ModeB = GR_FUNC_MODE_X; + colorComb.SourceC = GR_CMBX_ZERO; + colorComb.InvertC = FXTRUE; + colorComb.SourceD = GR_CMBX_ZERO; + } else { + colorComb.SourceA = GR_CMBX_LOCAL_TEXTURE_RGB; + colorComb.ModeA = GR_FUNC_MODE_X; + colorComb.SourceB = GR_CMBX_ZERO; + colorComb.ModeB = GR_FUNC_MODE_X; + colorComb.SourceC = GR_CMBX_ZERO; + colorComb.InvertC = FXTRUE; + colorComb.SourceD = GR_CMBX_ZERO; + } + break; + case GL_ADD: + if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { + alphaComb.SourceA = locala; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_ZERO; + alphaComb.InvertC = FXTRUE; + alphaComb.SourceD = GR_CMBX_ZERO; + } else if (ifmt == GL_INTENSITY) { + alphaComb.SourceA = locala; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = GR_CMBX_LOCAL_TEXTURE_ALPHA; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_ZERO; + alphaComb.InvertC = FXTRUE; + alphaComb.SourceD = GR_CMBX_ZERO; + } else { + alphaComb.SourceA = locala; + alphaComb.ModeA = GR_FUNC_MODE_X; + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_X; + alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; + alphaComb.InvertC = FXFALSE; + alphaComb.SourceD = GR_CMBX_ZERO; + } + + if (ifmt == GL_ALPHA) { + colorComb.SourceA = localc; + colorComb.ModeA = GR_FUNC_MODE_X; + colorComb.SourceB = GR_CMBX_ZERO; + colorComb.ModeB = GR_FUNC_MODE_X; + colorComb.SourceC = GR_CMBX_ZERO; + colorComb.InvertC = FXTRUE; + colorComb.SourceD = GR_CMBX_ZERO; + } else { + colorComb.SourceA = localc; + colorComb.ModeA = GR_FUNC_MODE_X; + colorComb.SourceB = GR_CMBX_LOCAL_TEXTURE_RGB; + colorComb.ModeB = GR_FUNC_MODE_X; + colorComb.SourceC = GR_CMBX_ZERO; + colorComb.InvertC = FXTRUE; + colorComb.SourceD = GR_CMBX_ZERO; + } + break; + /* COMBINE_EXT */ + case GL_COMBINE_EXT: + /* XXX todo - INCOMPLETE!!! */ + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) { +#if 1 + fprintf(stderr, "COMBINE_EXT: %s + %s\n", + _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB), + _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA)); +#else + fprintf(stderr, "Texture Unit %d\n", textureset); + fprintf(stderr, " GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode)); + fprintf(stderr, " GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB)); + fprintf(stderr, " GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA)); + fprintf(stderr, " GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0])); + fprintf(stderr, " GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1])); + fprintf(stderr, " GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2])); + fprintf(stderr, " GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0])); + fprintf(stderr, " GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1])); + fprintf(stderr, " GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2])); + fprintf(stderr, " GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0])); + fprintf(stderr, " GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1])); + fprintf(stderr, " GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2])); + fprintf(stderr, " GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0])); + fprintf(stderr, " GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1])); + fprintf(stderr, " GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2])); + fprintf(stderr, " GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB); + fprintf(stderr, " GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA); + fprintf(stderr, " GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", envColor[0], envColor[1], envColor[2], envColor[3]); +#endif + } + + alphaComb.Shift = texUnit->Combine.ScaleShiftA; + colorComb.Shift = texUnit->Combine.ScaleShiftRGB; + + switch (texUnit->Combine.ModeRGB) { + case GL_MODULATE: + /* Arg0 * Arg1 == (A + 0) * C + 0 */ + TEXENV_SETUP_ARG_RGB(colorComb.SourceA, + texUnit->Combine.SourceRGB[0], + texUnit->Combine.OperandRGB[0], + localc, locala); + TEXENV_SETUP_MODE_RGB(colorComb.ModeA, + texUnit->Combine.OperandRGB[0]); + colorComb.SourceB = GR_CMBX_ZERO; + colorComb.ModeB = GR_FUNC_MODE_ZERO; + TEXENV_SETUP_ARG_RGB(colorComb.SourceC, + texUnit->Combine.SourceRGB[1], + texUnit->Combine.OperandRGB[1], + localc, locala); + colorComb.InvertC = TEXENV_OPERAND_INVERTED( + texUnit->Combine.OperandRGB[1]); + colorComb.SourceD = GR_CMBX_ZERO; + break; + case GL_REPLACE: + /* Arg0 == (A + 0) * 1 + 0 */ + TEXENV_SETUP_ARG_RGB(colorComb.SourceA, + texUnit->Combine.SourceRGB[0], + texUnit->Combine.OperandRGB[0], + localc, locala); + TEXENV_SETUP_MODE_RGB(colorComb.ModeA, + texUnit->Combine.OperandRGB[0]); + colorComb.SourceB = GR_CMBX_ZERO; + colorComb.ModeB = GR_FUNC_MODE_ZERO; + colorComb.SourceC = GR_CMBX_ZERO; + colorComb.InvertC = FXTRUE; + colorComb.SourceD = GR_CMBX_ZERO; + break; + case GL_ADD: + /* Arg0 + Arg1 = (A + B) * 1 + 0 */ + TEXENV_SETUP_ARG_RGB(colorComb.SourceA, + texUnit->Combine.SourceRGB[0], + texUnit->Combine.OperandRGB[0], + localc, locala); + TEXENV_SETUP_MODE_RGB(colorComb.ModeA, + texUnit->Combine.OperandRGB[0]); + TEXENV_SETUP_ARG_RGB(colorComb.SourceB, + texUnit->Combine.SourceRGB[1], + texUnit->Combine.OperandRGB[1], + localc, locala); + TEXENV_SETUP_MODE_RGB(colorComb.ModeB, + texUnit->Combine.OperandRGB[1]); + colorComb.SourceC = GR_CMBX_ZERO; + colorComb.InvertC = FXTRUE; + colorComb.SourceD = GR_CMBX_ZERO; + break; + case GL_INTERPOLATE_EXT: + /* Arg0 * Arg2 + Arg1 * (1 - Arg2) == + * (Arg0 - Arg1) * Arg2 + Arg1 == (A - B) * C + D + */ + TEXENV_SETUP_ARG_RGB(colorComb.SourceA, + texUnit->Combine.SourceRGB[0], + texUnit->Combine.OperandRGB[0], + localc, locala); + TEXENV_SETUP_MODE_RGB(colorComb.ModeA, + texUnit->Combine.OperandRGB[0]); + TEXENV_SETUP_ARG_RGB(colorComb.SourceB, + texUnit->Combine.SourceRGB[1], + texUnit->Combine.OperandRGB[1], + localc, locala); + if (TEXENV_OPERAND_INVERTED(texUnit->Combine.OperandRGB[1])) { + /* Hack alert!!! This case is wrong!!! */ + fprintf(stderr, "COMBINE_EXT_color: WRONG!!!\n"); + colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X; + } else { + colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X; + } + /* + * The Source/Operand for the C value must + * specify some kind of alpha value. + */ + TEXENV_SETUP_ARG_A(colorComb.SourceC, + texUnit->Combine.SourceRGB[2], + texUnit->Combine.OperandRGB[2], + locala); + colorComb.InvertC = FXFALSE; + colorComb.SourceD = GR_CMBX_B; + break; + default: + fprintf(stderr, "COMBINE_EXT_color: %s\n", + _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB)); + } + + switch (texUnit->Combine.ModeA) { + case GL_MODULATE: + /* Arg0 * Arg1 == (A + 0) * C + 0 */ + TEXENV_SETUP_ARG_A(alphaComb.SourceA, + texUnit->Combine.SourceA[0], + texUnit->Combine.OperandA[0], + locala); + TEXENV_SETUP_MODE_A(alphaComb.ModeA, + texUnit->Combine.OperandA[0]); + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_ZERO; + TEXENV_SETUP_ARG_A(alphaComb.SourceC, + texUnit->Combine.SourceA[1], + texUnit->Combine.OperandA[1], + locala); + alphaComb.InvertC = TEXENV_OPERAND_INVERTED( + texUnit->Combine.OperandA[1]); + alphaComb.SourceD = GR_CMBX_ZERO; + break; + case GL_REPLACE: + /* Arg0 == (A + 0) * 1 + 0 */ + TEXENV_SETUP_ARG_A(alphaComb.SourceA, + texUnit->Combine.SourceA[0], + texUnit->Combine.OperandA[0], + locala); + TEXENV_SETUP_MODE_A(alphaComb.ModeA, + texUnit->Combine.OperandA[0]); + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_ZERO; + alphaComb.SourceC = GR_CMBX_ZERO; + alphaComb.InvertC = FXTRUE; + alphaComb.SourceD = GR_CMBX_ZERO; + break; + case GL_ADD: + /* Arg0 + Arg1 = (A + B) * 1 + 0 */ + TEXENV_SETUP_ARG_A(alphaComb.SourceA, + texUnit->Combine.SourceA[0], + texUnit->Combine.OperandA[0], + locala); + TEXENV_SETUP_MODE_A(alphaComb.ModeA, + texUnit->Combine.OperandA[0]); + TEXENV_SETUP_ARG_A(alphaComb.SourceB, + texUnit->Combine.SourceA[1], + texUnit->Combine.OperandA[1], + locala); + TEXENV_SETUP_MODE_A(alphaComb.ModeB, + texUnit->Combine.OperandA[1]); + alphaComb.SourceC = GR_CMBX_ZERO; + alphaComb.InvertC = FXTRUE; + alphaComb.SourceD = GR_CMBX_ZERO; + break; + default: + fprintf(stderr, "COMBINE_EXT_alpha: %s\n", + _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA)); + } + + fxMesa->Glide.grConstantColorValueExt(tmu, + (((GLuint)(envColor[0] * 255.0f)) ) | + (((GLuint)(envColor[1] * 255.0f)) << 8) | + (((GLuint)(envColor[2] * 255.0f)) << 16) | + (((GLuint)(envColor[3] * 255.0f)) << 24)); + break; + + default: + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTextureEnvNapalm_NoLock: %x Texture.EnvMode not yet supported\n", + texUnit->EnvMode); + } + return; + } + + /* On Napalm we simply put the color combine unit into passthrough mode + * and do everything we need with the texture combine units. */ + fxMesa->Glide.grColorCombineExt(GR_CMBX_TEXTURE_RGB, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + FXTRUE, + GR_CMBX_ZERO, + FXFALSE, + 0, + FXFALSE); + fxMesa->Glide.grAlphaCombineExt(GR_CMBX_TEXTURE_ALPHA, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + FXTRUE, + GR_CMBX_ZERO, + FXFALSE, + 0, + FXFALSE); + + fxMesa->Glide.grTexAlphaCombineExt(tmu, + alphaComb.SourceA, + alphaComb.ModeA, + alphaComb.SourceB, + alphaComb.ModeB, + alphaComb.SourceC, + alphaComb.InvertC, + alphaComb.SourceD, + alphaComb.InvertD, + alphaComb.Shift, + alphaComb.Invert); + fxMesa->Glide.grTexColorCombineExt(tmu, + colorComb.SourceA, + colorComb.ModeA, + colorComb.SourceB, + colorComb.ModeB, + colorComb.SourceC, + colorComb.InvertC, + colorComb.SourceD, + colorComb.InvertD, + colorComb.Shift, + colorComb.Invert); +} + + +/************************* Single Texture Set ***************************/ + +static void +fxSelectSingleTMUSrcNapalm_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend) +{ + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSelectSingleTMUSrcNapalm_NoLock(%d, %d)\n", tmu, LODblend); + } + + if (LODblend) { + /* XXX todo - GR_CMBX_LOD_FRAC? */ + fxMesa->tmuSrc = FX_TMU_SPLIT; + } + else { + if (tmu != FX_TMU1) { + /* disable tex1 */ + if (fxMesa->haveTwoTMUs) { + fxMesa->Glide.grTexAlphaCombineExt(FX_TMU1, + GR_CMBX_ZERO, + GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, + GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, + FXTRUE, + GR_CMBX_ZERO, + FXFALSE, + 0, + FXFALSE); + fxMesa->Glide.grTexColorCombineExt(FX_TMU1, + GR_CMBX_ZERO, + GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, + GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, + FXTRUE, + GR_CMBX_ZERO, + FXFALSE, + 0, + FXFALSE); + } + + fxMesa->tmuSrc = FX_TMU0; + } + else { +#if 1 + grTexCombine(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_ONE, + FXFALSE, + FXFALSE); +#else + /* [dBorca] why, oh why? doesn't work! stupid Glide? */ + fxMesa->Glide.grTexAlphaCombineExt(FX_TMU0, + GR_CMBX_OTHER_TEXTURE_ALPHA, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + FXTRUE, + GR_CMBX_ZERO, + FXFALSE, + 0, + FXFALSE); + fxMesa->Glide.grTexColorCombineExt(FX_TMU0, + GR_CMBX_OTHER_TEXTURE_RGB, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + FXTRUE, + GR_CMBX_ZERO, + FXFALSE, + 0, + FXFALSE); +#endif + + fxMesa->tmuSrc = FX_TMU1; + } + } +} + +static void +fxSetupTextureSingleTMUNapalm_NoLock(GLcontext * ctx, GLuint textureset) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint unitsmode; + tfxTexInfo *ti; + struct gl_texture_object *tObj = ctx->Texture.Unit[textureset]._Current; + int tmu; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTextureSingleTMUNapalm_NoLock(%d)\n", textureset); + } + + ti = fxTMGetTexInfo(tObj); + + fxTexValidate(ctx, tObj); + + fxSetupSingleTMU_NoLock(fxMesa, tObj); + + if (ti->whichTMU == FX_TMU_BOTH) + tmu = FX_TMU0; + else + tmu = ti->whichTMU; + if (fxMesa->tmuSrc != tmu) + fxSelectSingleTMUSrcNapalm_NoLock(fxMesa, tmu, ti->LODblend); + + if (textureset == 0 || !fxMesa->haveTwoTMUs) + unitsmode = fxGetTexSetConfiguration(ctx, tObj, NULL); + else + unitsmode = fxGetTexSetConfiguration(ctx, NULL, tObj); + +/* if(fxMesa->lastUnitsMode==unitsmode) */ +/* return; */ + + fxMesa->lastUnitsMode = unitsmode; + + fxMesa->stw_hint_state = 0; + FX_grHints_NoLock(GR_HINT_STWHINT, 0); + + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fprintf(stderr, "fxSetupTextureSingleTMUNapalm_NoLock: envmode is %s\n", + _mesa_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode)); + + /* [dBorca] Hack alert: + * what if we're in split mode? (LODBlend) + * also should we update BOTH TMUs in FX_TMU_BOTH mode? + */ + fxSetupTextureEnvNapalm_NoLock(ctx, textureset, tmu, GL_TRUE); +} + + +/************************* Double Texture Set ***************************/ + +static void +fxSetupTextureDoubleTMUNapalm_NoLock(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti0, *ti1; + struct gl_texture_object *tObj0 = ctx->Texture.Unit[1]._Current; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[0]._Current; + GLuint unitsmode; + int tmu0 = 0, tmu1 = 1; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTextureDoubleTMUNapalm_NoLock(...)\n"); + } + + ti0 = fxTMGetTexInfo(tObj0); + fxTexValidate(ctx, tObj0); + + ti1 = fxTMGetTexInfo(tObj1); + fxTexValidate(ctx, tObj1); + + fxSetupDoubleTMU_NoLock(fxMesa, tObj0, tObj1); + + unitsmode = fxGetTexSetConfiguration(ctx, tObj0, tObj1); + +/* if(fxMesa->lastUnitsMode==unitsmode) */ +/* return; */ + + fxMesa->lastUnitsMode = unitsmode; + + fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1; + FX_grHints_NoLock(GR_HINT_STWHINT, fxMesa->stw_hint_state); + + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) + fprintf(stderr, "fxSetupTextureDoubleTMUNapalm_NoLock: envmode is %s/%s\n", + _mesa_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode), + _mesa_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode)); + + + if ((ti0->whichTMU == FX_TMU1) || (ti1->whichTMU == FX_TMU0)) { + tmu0 = 1; + tmu1 = 0; + } + fxMesa->tmuSrc = FX_TMU_BOTH; + + /* OpenGL vs Glide texture pipeline */ + fxSetupTextureEnvNapalm_NoLock(ctx, 0, 1, GL_TRUE); + fxSetupTextureEnvNapalm_NoLock(ctx, 1, 0, GL_FALSE); +} + +/************************* No Texture ***************************/ + +static void +fxSetupTextureNoneNapalm_NoLock(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxSetupTextureNoneNapalm_NoLock(...)\n"); + } + + /* the combiner formula is: (A + B) * C + D + ** + ** a = tc_otherselect + ** a_mode = tc_invert_other + ** b = tc_localselect + ** b_mode = tc_invert_local + ** c = (tc_mselect, tc_mselect_7) + ** d = (tc_add_clocal, tc_add_alocal) + ** shift = tc_outshift + ** invert = tc_invert_output + */ + + fxMesa->Glide.grColorCombineExt(GR_CMBX_ITRGB, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, + FXTRUE, + GR_CMBX_ZERO, + FXFALSE, + 0, + FXFALSE); + fxMesa->Glide.grAlphaCombineExt(GR_CMBX_ITALPHA, + GR_FUNC_MODE_X, + GR_CMBX_ZERO, + GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, + FXTRUE, + GR_CMBX_ZERO, + FXFALSE, + 0, + FXFALSE); + + fxMesa->lastUnitsMode = FX_UM_NONE; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtexman.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtexman.c new file mode 100644 index 000000000..940c8fd0b --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtexman.c @@ -0,0 +1,874 @@ +/* + * 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 + */ + +/* fxtexman.c - 3Dfx VooDoo texture memory functions */ + + +#ifdef HAVE_CONFIG_H +#include "conf.h" +#endif + +#if defined(FX) + +#include "hash.h" +#include "fxdrv.h" + +int texSwaps = 0; +static FxU32 texBoundMask; + +#define FX_2MB_SPLIT 0x200000 + +static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa, + int tmu); + + +#ifdef TEXSANITY +static void +fubar() +{ +} + + /* Sanity Check */ +static void +sanity(fxMesaContext fxMesa) +{ + MemRange *tmp, *prev, *pos; + + prev = 0; + tmp = fxMesa->tmFree[0]; + while (tmp) { + if (!tmp->startAddr && !tmp->endAddr) { + fprintf(stderr, "Textures fubar\n"); + fubar(); + } + if (tmp->startAddr >= tmp->endAddr) { + fprintf(stderr, "Node fubar\n"); + fubar(); + } + if (prev && (prev->startAddr >= tmp->startAddr || + prev->endAddr > tmp->startAddr)) { + fprintf(stderr, "Sorting fubar\n"); + fubar(); + } + prev = tmp; + tmp = tmp->next; + } + prev = 0; + tmp = fxMesa->tmFree[1]; + while (tmp) { + if (!tmp->startAddr && !tmp->endAddr) { + fprintf(stderr, "Textures fubar\n"); + fubar(); + } + if (tmp->startAddr >= tmp->endAddr) { + fprintf(stderr, "Node fubar\n"); + fubar(); + } + if (prev && (prev->startAddr >= tmp->startAddr || + prev->endAddr > tmp->startAddr)) { + fprintf(stderr, "Sorting fubar\n"); + fubar(); + } + prev = tmp; + tmp = tmp->next; + } +} +#endif + +static MemRange * +fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end) +{ + MemRange *result = 0; + + if (fxMesa->tmPool) { + result = fxMesa->tmPool; + fxMesa->tmPool = fxMesa->tmPool->next; + } + else { + if (!(result = MALLOC(sizeof(MemRange)))) { + fprintf(stderr, "fxTMNewRangeNode: ERROR: out of memory!\n"); + fxCloseHardware(); + exit(-1); + } + } + result->startAddr = start; + result->endAddr = end; + return result; +} + +#if 1 +#define fxTMDeleteRangeNode(fxMesa, range) \ + do { \ + range->next = fxMesa->tmPool; \ + fxMesa->tmPool = range; \ + } while (0); +#else +static void +fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange * range) +{ + range->next = fxMesa->tmPool; + fxMesa->tmPool = range; +} +#endif + +static void +fxTMUInit(fxMesaContext fxMesa, int tmu) +{ + MemRange *tmn, *last; + FxU32 start, end, blockstart, blockend, chunk; + + start = grTexMinAddress(tmu); + end = grTexMaxAddress(tmu); + + chunk = (fxMesa->type >= GR_SSTTYPE_Banshee) ? (end - start) : FX_2MB_SPLIT; + + if (fxMesa->verbose) { + fprintf(stderr, "Voodoo TMU%d configuration:\n", tmu); + } + + fxMesa->freeTexMem[tmu] = end - start; + fxMesa->tmFree[tmu] = NULL; + + last = 0; + blockstart = start; + while (blockstart < end) { + if (blockstart + chunk > end) + blockend = end; + else + blockend = blockstart + chunk; + + if (fxMesa->verbose) + fprintf(stderr, "Voodoo %08u-%08u\n", + (unsigned int) blockstart, (unsigned int) blockend); + + tmn = fxTMNewRangeNode(fxMesa, blockstart, blockend); + tmn->next = NULL; + + + if (last) + last->next = tmn; + else + fxMesa->tmFree[tmu] = tmn; + last = tmn; + + blockstart += chunk; + } +} + +static int +fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) +{ + MemRange *prev, *tmp; + int result; + struct gl_texture_object *obj; + + if (fxMesa->HaveTexUma) { + tmu = FX_TMU0; + } + + while (1) { + prev = 0; + tmp = fxMesa->tmFree[tmu]; + while (tmp) { + if (tmp->endAddr - tmp->startAddr >= size) { /* Fits here */ + result = tmp->startAddr; + tmp->startAddr += size; + if (tmp->startAddr == tmp->endAddr) { /* Empty */ + if (prev) { + prev->next = tmp->next; + } + else { + fxMesa->tmFree[tmu] = tmp->next; + } + fxTMDeleteRangeNode(fxMesa, tmp); + } + fxMesa->freeTexMem[tmu] -= size; + return result; + } + prev = tmp; + tmp = tmp->next; + } + /* No free space. Discard oldest */ + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTMFindStartAddr: No free space. Discard oldest\n"); + } + obj = fxTMFindOldestObject(fxMesa, tmu); + if (!obj) { + fprintf(stderr, "fxTMFindStartAddr: ERROR: No space for texture\n"); + return -1; + } + fxTMMoveOutTM(fxMesa, obj); + texSwaps++; + } +} + +int fxTMCheckStartAddr (fxMesaContext fxMesa, GLint tmu, tfxTexInfo *ti) +{ + MemRange *tmp; + int size; + + if (fxMesa->HaveTexUma) { + return FXTRUE; + } + + size = grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + + tmp = fxMesa->tmFree[tmu]; + while (tmp) { + if (tmp->endAddr - tmp->startAddr >= size) { /* Fits here */ + return FXTRUE; + } + tmp = tmp->next; + } + + return FXFALSE; +} + +static void +fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range) +{ + MemRange *tmp, *prev; + + if (fxMesa->HaveTexUma) { + tmu = FX_TMU0; + } + + if (range->startAddr == range->endAddr) { + fxTMDeleteRangeNode(fxMesa, range); + return; + } + fxMesa->freeTexMem[tmu] += range->endAddr - range->startAddr; + prev = 0; + tmp = fxMesa->tmFree[tmu]; + while (tmp) { + if (range->startAddr > tmp->startAddr) { + prev = tmp; + tmp = tmp->next; + } + else + break; + } + /* When we create the regions, we make a split at the 2MB boundary. + Now we have to make sure we don't join those 2MB boundary regions + back together again. */ + range->next = tmp; + if (tmp) { + if (range->endAddr == tmp->startAddr + && tmp->startAddr & texBoundMask) { + /* Combine */ + tmp->startAddr = range->startAddr; + fxTMDeleteRangeNode(fxMesa, range); + range = tmp; + } + } + if (prev) { + if (prev->endAddr == range->startAddr + && range->startAddr & texBoundMask) { + /* Combine */ + prev->endAddr = range->endAddr; + prev->next = range->next; + fxTMDeleteRangeNode(fxMesa, range); + } + else + prev->next = range; + } + else { + fxMesa->tmFree[tmu] = range; + } +} + +static struct gl_texture_object * +fxTMFindOldestObject(fxMesaContext fxMesa, int tmu) +{ + GLuint age, old, lasttime, bindnumber; + GLfloat lowestPriority; + struct gl_texture_object *obj, *lowestPriorityObj; + struct _mesa_HashTable *textures = fxMesa->glCtx->Shared->TexObjects; + GLuint id; + + if (!_mesa_HashFirstEntry(textures)) + return 0; + + obj = NULL; + old = 0; + + lowestPriorityObj = NULL; + lowestPriority = 1.0F; + + bindnumber = fxMesa->texBindNumber; + + for (id = _mesa_HashFirstEntry(textures); + id; + id = _mesa_HashNextEntry(textures, id)) { + struct gl_texture_object *tmp + = (struct gl_texture_object *) _mesa_HashLookup(textures, id); + tfxTexInfo *info = fxTMGetTexInfo(tmp); + + if (info && info->isInTM && + ((info->whichTMU == tmu) || + (info->whichTMU == FX_TMU_BOTH) || + (info->whichTMU == FX_TMU_SPLIT) || + fxMesa->HaveTexUma + ) + ) { + lasttime = info->lastTimeUsed; + + if (lasttime > bindnumber) + age = bindnumber + (UINT_MAX - lasttime + 1); /* TO DO: check wrap around */ + else + age = bindnumber - lasttime; + + if (age >= old) { + old = age; + obj = tmp; + } + + /* examine priority */ + if (tmp->Priority < lowestPriority) { + lowestPriority = tmp->Priority; + lowestPriorityObj = tmp; + } + } + } + + if (lowestPriorityObj != NULL) { + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTMFindOldestObject: %d pri=%f\n", lowestPriorityObj->Name, lowestPriority); + } + return lowestPriorityObj; + } + else { + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + if (obj != NULL) { + fprintf(stderr, "fxTMFindOldestObject: %d age=%d\n", obj->Name, old); + } + } + return obj; + } +} + +static MemRange * +fxTMAddObj(fxMesaContext fxMesa, + struct gl_texture_object *tObj, GLint tmu, int texmemsize) +{ + FxI32 startAddr; + MemRange *range; + + startAddr = fxTMFindStartAddr(fxMesa, tmu, texmemsize); + if (startAddr < 0) + return 0; + range = fxTMNewRangeNode(fxMesa, startAddr, startAddr + texmemsize); + return range; +} + +/* External Functions */ + +void +fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint where) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + int i, l; + int texmemsize; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxTMMoveInTM_NoLock(%d)\n", tObj->Name); + } + + fxMesa->stats.reqTexUpload++; + + if (!ti->validated) { + fprintf(stderr, "fxTMMoveInTM_NoLock: INTERNAL ERROR: not validated\n"); + fxCloseHardware(); + exit(-1); + } + + if (ti->isInTM) { + if (ti->whichTMU == where) + return; + if (where == FX_TMU_SPLIT || ti->whichTMU == FX_TMU_SPLIT) + fxTMMoveOutTM_NoLock(fxMesa, tObj); + else { + if (ti->whichTMU == FX_TMU_BOTH) + return; + where = FX_TMU_BOTH; + } + } + + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) { + fprintf(stderr, "fxTMMoveInTM_NoLock: downloading %p (%d) in texture memory in %d\n", + (void *)tObj, tObj->Name, where); + } + + ti->whichTMU = (FxU32) where; + + switch (where) { + case FX_TMU0: + case FX_TMU1: + texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + ti->tm[where] = fxTMAddObj(fxMesa, tObj, where, texmemsize); + fxMesa->stats.memTexUpload += texmemsize; + + for (i = FX_largeLodValue(ti->info), l = ti->minLevel; + i <= FX_smallLodValue(ti->info); i++, l++) { + struct gl_texture_image *texImage = tObj->Image[0][l]; + grTexDownloadMipMapLevel(where, + ti->tm[where]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + texImage->Data); + } + break; + case FX_TMU_SPLIT: + texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD, &(ti->info)); + ti->tm[FX_TMU0] = fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize); + fxMesa->stats.memTexUpload += texmemsize; + + texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN, &(ti->info)); + ti->tm[FX_TMU1] = fxTMAddObj(fxMesa, tObj, FX_TMU1, texmemsize); + fxMesa->stats.memTexUpload += texmemsize; + + for (i = FX_largeLodValue(ti->info), l = ti->minLevel; + i <= FX_smallLodValue(ti->info); i++, l++) { + struct gl_texture_image *texImage = tObj->Image[0][l]; + + grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[FX_TMU0]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, + texImage->Data); + + grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[FX_TMU1]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, + texImage->Data); + } + break; + case FX_TMU_BOTH: + texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + ti->tm[FX_TMU0] = fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize); + fxMesa->stats.memTexUpload += texmemsize; + + /*texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info));*/ + ti->tm[FX_TMU1] = fxTMAddObj(fxMesa, tObj, FX_TMU1, texmemsize); + fxMesa->stats.memTexUpload += texmemsize; + + for (i = FX_largeLodValue(ti->info), l = ti->minLevel; + i <= FX_smallLodValue(ti->info); i++, l++) { + struct gl_texture_image *texImage = tObj->Image[0][l]; + grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[FX_TMU0]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + texImage->Data); + + grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[FX_TMU1]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + texImage->Data); + } + break; + default: + fprintf(stderr, "fxTMMoveInTM_NoLock: INTERNAL ERROR: wrong tmu (%d)\n", where); + fxCloseHardware(); + exit(-1); + } + + fxMesa->stats.texUpload++; + + ti->isInTM = GL_TRUE; +} + + +void +fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint where) +{ + BEGIN_BOARD_LOCK(); + fxTMMoveInTM_NoLock(fxMesa, tObj, where); + END_BOARD_LOCK(); +} + + +void +fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint level) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + GrLOD_t lodlevel; + GLint tmu; + struct gl_texture_image *texImage = tObj->Image[0][level]; + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTMReloadMipMapLevel(%p (%d), %d)\n", (void *)tObj, tObj->Name, level); + } + + assert(mml); + assert(mml->width > 0); + assert(mml->height > 0); + assert(mml->glideFormat > 0); + assert(ti->isInTM); + + if (!ti->validated) { + fprintf(stderr, "fxTMReloadMipMapLevel: INTERNAL ERROR: not validated\n"); + fxCloseHardware(); + exit(-1); + } + + tmu = (int) ti->whichTMU; + fxMesa->stats.reqTexUpload++; + fxMesa->stats.texUpload++; + + lodlevel = ti->info.largeLodLog2 - (level - ti->minLevel); + + switch (tmu) { + case FX_TMU0: + case FX_TMU1: + grTexDownloadMipMapLevel(tmu, + ti->tm[tmu]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, texImage->Data); + break; + case FX_TMU_SPLIT: + grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[GR_TMU0]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, texImage->Data); + + grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[GR_TMU1]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, texImage->Data); + break; + case FX_TMU_BOTH: + grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[GR_TMU0]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, texImage->Data); + + grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[GR_TMU1]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, texImage->Data); + break; + + default: + fprintf(stderr, "fxTMReloadMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu); + fxCloseHardware(); + exit(-1); + } +} + +void +fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, + struct gl_texture_object *tObj, + GLint level, GLint yoffset, GLint height) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + GrLOD_t lodlevel; + unsigned short *data; + GLint tmu; + struct gl_texture_image *texImage = tObj->Image[0][level]; + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + assert(mml); + + if (!ti->validated) { + fprintf(stderr, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: not validated\n"); + fxCloseHardware(); + exit(-1); + } + + tmu = (int) ti->whichTMU; + fxTMMoveInTM(fxMesa, tObj, tmu); + + fxTexGetInfo(mml->width, mml->height, + &lodlevel, NULL, NULL, NULL, NULL, NULL); + + if ((ti->info.format == GR_TEXFMT_INTENSITY_8) || + (ti->info.format == GR_TEXFMT_P_8) || + (ti->info.format == GR_TEXFMT_ALPHA_8)) + data = (GLushort *) texImage->Data + ((yoffset * mml->width) >> 1); + else + data = (GLushort *) texImage->Data + yoffset * mml->width; + + switch (tmu) { + case FX_TMU0: + case FX_TMU1: + grTexDownloadMipMapLevelPartial(tmu, + ti->tm[tmu]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel) + + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); + break; + case FX_TMU_SPLIT: + grTexDownloadMipMapLevelPartial(GR_TMU0, + ti->tm[FX_TMU0]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel) + + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, data, + yoffset, yoffset + height - 1); + + grTexDownloadMipMapLevelPartial(GR_TMU1, + ti->tm[FX_TMU1]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel) + + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, data, + yoffset, yoffset + height - 1); + break; + case FX_TMU_BOTH: + grTexDownloadMipMapLevelPartial(GR_TMU0, + ti->tm[FX_TMU0]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel) + + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); + + grTexDownloadMipMapLevelPartial(GR_TMU1, + ti->tm[FX_TMU1]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel) + + level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); + break; + default: + fprintf(stderr, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu); + fxCloseHardware(); + exit(-1); + } +} + +void +fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxTMMoveOutTM(%p (%d))\n", (void *)tObj, tObj->Name); + } + + if (!ti->isInTM) + return; + + switch (ti->whichTMU) { + case FX_TMU0: + case FX_TMU1: + fxTMRemoveRange(fxMesa, (int) ti->whichTMU, ti->tm[ti->whichTMU]); + break; + case FX_TMU_SPLIT: + case FX_TMU_BOTH: + fxTMRemoveRange(fxMesa, FX_TMU0, ti->tm[FX_TMU0]); + fxTMRemoveRange(fxMesa, FX_TMU1, ti->tm[FX_TMU1]); + break; + default: + fprintf(stderr, "fxTMMoveOutTM: INTERNAL ERROR: bad TMU (%ld)\n", ti->whichTMU); + fxCloseHardware(); + exit(-1); + } + + ti->isInTM = GL_FALSE; + ti->whichTMU = FX_TMU_NONE; +} + +void +fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + int i; + + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTMFreeTexture(%p (%d))\n", (void *)tObj, tObj->Name); + } + + fxTMMoveOutTM(fxMesa, tObj); + + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { + struct gl_texture_image *texImage = tObj->Image[0][i]; + if (texImage) { + if (texImage->DriverData) { + FREE(texImage->DriverData); + texImage->DriverData = NULL; + } + } + } + switch (ti->whichTMU) { + case FX_TMU0: + case FX_TMU1: + fxTMDeleteRangeNode(fxMesa, ti->tm[ti->whichTMU]); + break; + case FX_TMU_SPLIT: + case FX_TMU_BOTH: + fxTMDeleteRangeNode(fxMesa, ti->tm[FX_TMU0]); + fxTMDeleteRangeNode(fxMesa, ti->tm[FX_TMU1]); + break; + } +} + +void +fxTMInit(fxMesaContext fxMesa) +{ + fxMesa->texBindNumber = 0; + fxMesa->tmPool = 0; + + if (fxMesa->HaveTexUma) { + grEnable(GR_TEXTURE_UMA_EXT); + } + + fxTMUInit(fxMesa, FX_TMU0); + + if (!fxMesa->HaveTexUma && fxMesa->haveTwoTMUs) + fxTMUInit(fxMesa, FX_TMU1); + + texBoundMask = (fxMesa->type >= GR_SSTTYPE_Banshee) ? -1 : (FX_2MB_SPLIT - 1); +} + +void +fxTMClose(fxMesaContext fxMesa) +{ + MemRange *tmp, *next; + + tmp = fxMesa->tmPool; + while (tmp) { + next = tmp->next; + FREE(tmp); + tmp = next; + } + tmp = fxMesa->tmFree[FX_TMU0]; + while (tmp) { + next = tmp->next; + FREE(tmp); + tmp = next; + } + if (fxMesa->haveTwoTMUs) { + tmp = fxMesa->tmFree[FX_TMU1]; + while (tmp) { + next = tmp->next; + FREE(tmp); + tmp = next; + } + } +} + +void +fxTMRestoreTextures_NoLock(fxMesaContext ctx) +{ + struct _mesa_HashTable *textures = ctx->glCtx->Shared->TexObjects; + GLuint id; + + for (id = _mesa_HashFirstEntry(textures); + id; + id = _mesa_HashNextEntry(textures, id)) { + struct gl_texture_object *tObj + = (struct gl_texture_object *) _mesa_HashLookup(textures, id); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + if (ti && ti->isInTM) { + int i; + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + if (ctx->glCtx->Texture.Unit[i]._Current == tObj) { + /* Force the texture onto the board, as it could be in use */ + int where = ti->whichTMU; + fxTMMoveOutTM_NoLock(ctx, tObj); + fxTMMoveInTM_NoLock(ctx, tObj, where); + break; + } + } + if (i == MAX_TEXTURE_UNITS) /* Mark the texture as off the board */ + fxTMMoveOutTM_NoLock(ctx, tObj); + } + } +} + +#else + + +/* + * Need this to provide at least one external definition. + */ + +extern int gl_fx_dummy_function_texman(void); +int +gl_fx_dummy_function_texman(void) +{ + return 0; +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtris.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtris.c new file mode 100644 index 000000000..180637565 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtris.c @@ -0,0 +1,1834 @@ +/* + * 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: + * Keith Whitwell <keith@tungstengraphics.com> + * Daniel Borca <dborca@users.sourceforge.net> + */ + +#include "glheader.h" + +#ifdef FX + +#include "imports.h" +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" +#include "nvfragprog.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "fxdrv.h" + + +static GLboolean fxMultipass_ColorSum (GLcontext *ctx, GLuint pass); + + +/* + * Subpixel offsets to adjust Mesa's (true) window coordinates to + * Glide coordinates. We need these to ensure precise rasterization. + * Otherwise, we'll fail a bunch of conformance tests. + */ +#define TRI_X_OFFSET ( 0.0F) +#define TRI_Y_OFFSET ( 0.0F) +#define LINE_X_OFFSET ( 0.0F) +#define LINE_Y_OFFSET ( 0.125F) +#define PNT_X_OFFSET ( 0.375F) +#define PNT_Y_OFFSET ( 0.375F) + +static void fxRasterPrimitive( GLcontext *ctx, GLenum prim ); +static void fxRenderPrimitive( GLcontext *ctx, GLenum prim ); + +static GLenum reduced_prim[GL_POLYGON+1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_tri( fxMesa, a, b, c ); \ + else \ + grDrawTriangle( a, b, c ); \ +} while (0) \ + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + fxMesa->draw_tri( fxMesa, a, b, d ); \ + fxMesa->draw_tri( fxMesa, b, c, d ); \ + } else { \ + GrVertex *_v_[4]; \ + _v_[0] = d; \ + _v_[1] = a; \ + _v_[2] = b; \ + _v_[3] = c; \ + grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\ + /*grDrawTriangle( a, b, d );*/ \ + /*grDrawTriangle( b, c, d );*/ \ + } \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_line( fxMesa, v0, v1 ); \ + else { \ + v0->x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + grDrawLine( v0, v1 ); \ + v0->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + } \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + fxMesa->draw_point( fxMesa, v0 ); \ + else { \ + v0->x += PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->y += PNT_Y_OFFSET - TRI_Y_OFFSET; \ + grDrawPoint( v0 ); \ + v0->x -= PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->y -= PNT_Y_OFFSET - TRI_Y_OFFSET; \ + } \ +} while (0) + + +/*********************************************************************** + * Fallback to swrast for basic primitives * + ***********************************************************************/ + +/* Build an SWvertex from a hardware vertex. + * + * This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +fx_translate_vertex( GLcontext *ctx, const GrVertex *src, SWvertex *dst) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint ts0 = fxMesa->tmu_source[0]; + GLuint ts1 = fxMesa->tmu_source[1]; + GLfloat w = 1.0F / src->oow; + + dst->win[0] = src->x; + dst->win[1] = src->y; + dst->win[2] = src->ooz; + dst->win[3] = src->oow; + +#if FX_PACKEDCOLOR + dst->color[0] = src->pargb[2]; + dst->color[1] = src->pargb[1]; + dst->color[2] = src->pargb[0]; + dst->color[3] = src->pargb[3]; + + dst->specular[0] = src->pspec[2]; + dst->specular[1] = src->pspec[1]; + dst->specular[2] = src->pspec[0]; +#else /* !FX_PACKEDCOLOR */ + dst->color[0] = src->r; + dst->color[1] = src->g; + dst->color[2] = src->b; + dst->color[3] = src->a; + + dst->specular[0] = src->r1; + dst->specular[1] = src->g1; + dst->specular[2] = src->g1; +#endif /* !FX_PACKEDCOLOR */ + + dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->tmuvtx[0].sow * w; + dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->tmuvtx[0].tow * w; + + if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU0) + dst->texcoord[ts0][3] = src->tmuvtx[0].oow * w; + else + dst->texcoord[ts0][3] = 1.0F; + + if (fxMesa->SetupIndex & SETUP_TMU1) { + dst->texcoord[ts1][0] = fxMesa->inv_s1scale * src->tmuvtx[1].sow * w; + dst->texcoord[ts1][1] = fxMesa->inv_t1scale * src->tmuvtx[1].tow * w; + + if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU1) + dst->texcoord[ts1][3] = src->tmuvtx[1].oow * w; + else + dst->texcoord[ts1][3] = 1.0F; + } + + dst->pointSize = src->psize; +} + + +static void +fx_fallback_tri( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1, + GrVertex *v2 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[3]; + + fx_translate_vertex( ctx, v0, &v[0] ); + fx_translate_vertex( ctx, v1, &v[1] ); + fx_translate_vertex( ctx, v2, &v[2] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} + + +static void +fx_fallback_line( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[2]; + fx_translate_vertex( ctx, v0, &v[0] ); + fx_translate_vertex( ctx, v1, &v[1] ); + _swrast_Line( ctx, &v[0], &v[1] ); +} + + +static void +fx_fallback_point( fxMesaContext fxMesa, + GrVertex *v0 ) +{ + GLcontext *ctx = fxMesa->glCtx; + SWvertex v[1]; + fx_translate_vertex( ctx, v0, &v[0] ); + _swrast_Point( ctx, &v[0] ); +} + +/*********************************************************************** + * Functions to draw basic primitives * + ***********************************************************************/ + +static void fx_print_vertex( GLcontext *ctx, const GrVertex *v ) +{ + fprintf(stderr, "fx_print_vertex:\n"); + + fprintf(stderr, "\tvertex at %p\n", (void *) v); + + fprintf(stderr, "\tx %f y %f z %f oow %f\n", v->x, v->y, v->ooz, v->oow); +#if FX_PACKEDCOLOR + fprintf(stderr, "\tr %d g %d b %d a %d\n", v->pargb[2], v->pargb[1], v->pargb[0], v->pargb[3]); +#else /* !FX_PACKEDCOLOR */ + fprintf(stderr, "\tr %f g %f b %f a %f\n", v->r, v->g, v->b, v->a); +#endif /* !FX_PACKEDCOLOR */ + + fprintf(stderr, "\n"); +} + +#define DO_FALLBACK 0 + +/* Need to do clip loop at each triangle when mixing swrast and hw + * rendering. These functions are only used when mixed-mode rendering + * is occurring. + */ +static void fx_draw_triangle( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1, + GrVertex *v2 ) +{ + BEGIN_CLIP_LOOP(); + TRI( v0, v1, v2 ); + END_CLIP_LOOP(); +} + +static void fx_draw_line( fxMesaContext fxMesa, + GrVertex *v0, + GrVertex *v1 ) +{ + /* No support for wide lines (avoid wide/aa line fallback). + */ + BEGIN_CLIP_LOOP(); + LINE(v0, v1); + END_CLIP_LOOP(); +} + +static void fx_draw_point( fxMesaContext fxMesa, + GrVertex *v0 ) +{ + /* No support for wide points. + */ + BEGIN_CLIP_LOOP(); + POINT( v0 ); + END_CLIP_LOOP(); +} + +#ifndef M_2PI +#define M_2PI 6.28318530717958647692528676655901 +#endif +#define __GL_COSF cos +#define __GL_SINF sin +static void fx_draw_point_sprite ( fxMesaContext fxMesa, + GrVertex *v0, GLfloat psize ) +{ + const GLcontext *ctx = fxMesa->glCtx; + + GLfloat radius; + GrVertex _v_[4]; + GLuint ts0 = fxMesa->tmu_source[0]; + GLuint ts1 = fxMesa->tmu_source[1]; + GLfloat w = v0->oow; + GLfloat u0scale = fxMesa->s0scale * w; + GLfloat v0scale = fxMesa->t0scale * w; + GLfloat u1scale = fxMesa->s1scale * w; + GLfloat v1scale = fxMesa->t1scale * w; + + radius = psize / 2.0F; + _v_[0] = *v0; + _v_[1] = *v0; + _v_[2] = *v0; + _v_[3] = *v0; + /* CLIP_LOOP ?!? */ + /* point coverage? */ + /* we don't care about culling here (see fxSetupCull) */ + + if (ctx->Point.SpriteOrigin == GL_UPPER_LEFT) { + _v_[0].x -= radius; + _v_[0].y += radius; + _v_[1].x += radius; + _v_[1].y += radius; + _v_[2].x += radius; + _v_[2].y -= radius; + _v_[3].x -= radius; + _v_[3].y -= radius; + } else { + _v_[0].x -= radius; + _v_[0].y -= radius; + _v_[1].x += radius; + _v_[1].y -= radius; + _v_[2].x += radius; + _v_[2].y += radius; + _v_[3].x -= radius; + _v_[3].y += radius; + } + + if (ctx->Point.CoordReplace[ts0]) { + _v_[0].tmuvtx[0].sow = 0; + _v_[0].tmuvtx[0].tow = 0; + _v_[1].tmuvtx[0].sow = u0scale; + _v_[1].tmuvtx[0].tow = 0; + _v_[2].tmuvtx[0].sow = u0scale; + _v_[2].tmuvtx[0].tow = v0scale; + _v_[3].tmuvtx[0].sow = 0; + _v_[3].tmuvtx[0].tow = v0scale; + } + if (ctx->Point.CoordReplace[ts1]) { + _v_[0].tmuvtx[1].sow = 0; + _v_[0].tmuvtx[1].tow = 0; + _v_[1].tmuvtx[1].sow = u1scale; + _v_[1].tmuvtx[1].tow = 0; + _v_[2].tmuvtx[1].sow = u1scale; + _v_[2].tmuvtx[1].tow = v1scale; + _v_[3].tmuvtx[1].sow = 0; + _v_[3].tmuvtx[1].tow = v1scale; + } + + grDrawVertexArrayContiguous(GR_TRIANGLE_FAN, 4, _v_, sizeof(GrVertex)); +} + +static void fx_draw_point_wide ( fxMesaContext fxMesa, + GrVertex *v0 ) +{ + GLint i, n; + GLfloat ang, radius, oon; + GrVertex vtxB, vtxC; + GrVertex *_v_[3]; + + const GLcontext *ctx = fxMesa->glCtx; + const GLfloat psize = (ctx->_TriangleCaps & DD_POINT_ATTEN) + ? CLAMP(v0->psize, ctx->Point.MinSize, ctx->Point.MaxSize) + : ctx->Point._Size; /* clamped */ + + if (ctx->Point.PointSprite) { + fx_draw_point_sprite(fxMesa, v0, psize); + return; + } + + _v_[0] = v0; + _v_[1] = &vtxB; + _v_[2] = &vtxC; + + radius = psize / 2.0F; + n = IROUND(psize * 2); /* radius x 4 */ + if (n < 4) n = 4; + oon = 1.0F / (GLfloat)n; + + /* CLIP_LOOP ?!? */ + /* point coverage? */ + /* we don't care about culling here (see fxSetupCull) */ + + vtxB = *v0; + vtxC = *v0; + + vtxB.x += radius; + ang = M_2PI * oon; + vtxC.x += radius * __GL_COSF(ang); + vtxC.y += radius * __GL_SINF(ang); + grDrawVertexArray(GR_TRIANGLE_FAN, 3, _v_); + for (i = 2; i <= n; i++) { + ang = M_2PI * i * oon; + vtxC.x = v0->x + radius * __GL_COSF(ang); + vtxC.y = v0->y + radius * __GL_SINF(ang); + grDrawVertexArray(GR_TRIANGLE_FAN_CONTINUE, 1, &_v_[2]); + } +} + +static void fx_render_pw_verts( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + (void) flags; + + fxRenderPrimitive( ctx, GL_POINTS ); + + for ( ; start < count ; start++) + fx_draw_point_wide(fxMesa, fxVB + start); +} + +static void fx_render_pw_elts ( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + (void) flags; + + fxRenderPrimitive( ctx, GL_POINTS ); + + for ( ; start < count ; start++) + fx_draw_point_wide(fxMesa, fxVB + elt[start]); +} + +static void fx_draw_point_wide_aa ( fxMesaContext fxMesa, + GrVertex *v0 ) +{ + GLint i, n; + GLfloat ang, radius, oon; + GrVertex vtxB, vtxC; + + const GLcontext *ctx = fxMesa->glCtx; + const GLfloat psize = (ctx->_TriangleCaps & DD_POINT_ATTEN) + ? CLAMP(v0->psize, ctx->Point.MinSize, ctx->Point.MaxSize) + : ctx->Point._Size; /* clamped */ + + if (ctx->Point.PointSprite) { + fx_draw_point_sprite(fxMesa, v0, psize); + return; + } + + radius = psize / 2.0F; + n = IROUND(psize * 2); /* radius x 4 */ + if (n < 4) n = 4; + oon = 1.0F / (GLfloat)n; + + /* CLIP_LOOP ?!? */ + /* point coverage? */ + /* we don't care about culling here (see fxSetupCull) */ + + vtxB = *v0; + vtxC = *v0; + + vtxB.x += radius; + for (i = 1; i <= n; i++) { + ang = M_2PI * i * oon; + vtxC.x = v0->x + radius * __GL_COSF(ang); + vtxC.y = v0->y + radius * __GL_SINF(ang); + grAADrawTriangle( v0, &vtxB, &vtxC, FXFALSE, FXTRUE, FXFALSE); + /*grDrawTriangle( v0, &vtxB, &vtxC);*/ + vtxB.x = vtxC.x; + vtxB.y = vtxC.y; + } +} +#undef __GLCOSF +#undef __GLSINF +#undef M_2PI + +#undef DO_FALLBACK + + +#define FX_UNFILLED_BIT 0x1 +#define FX_OFFSET_BIT 0x2 +#define FX_TWOSIDE_BIT 0x4 +#define FX_FLAT_BIT 0x8 +#define FX_TWOSTENCIL_BIT 0x10 +#define FX_FALLBACK_BIT 0x20 +#define FX_MAX_TRIFUNC 0x40 + +static struct { + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_quad_func quad; +} rast_tab[FX_MAX_TRIFUNC]; + +#define DO_FALLBACK (IND & FX_FALLBACK_BIT) +#define DO_OFFSET (IND & FX_OFFSET_BIT) +#define DO_UNFILLED (IND & FX_UNFILLED_BIT) +#define DO_TWOSIDE (IND & FX_TWOSIDE_BIT) +#define DO_FLAT (IND & FX_FLAT_BIT) +#define DO_TWOSTENCIL (IND & FX_TWOSTENCIL_BIT) +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_HW_FLATSHADE 0 +#define HAVE_BACK_COLORS 0 +#define VERTEX GrVertex +#define TAB rast_tab + +#define DEPTH_SCALE 1.0 +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->x +#define VERT_Y(_v) _v->y +#define VERT_Z(_v) _v->ooz +#define AREA_IS_CCW( a ) IS_NEGATIVE( a ) +#define GET_VERTEX(e) (fxMesa->verts + e) + + +#if FX_PACKEDCOLOR +#define VERT_SET_RGBA( dst, f ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[2], f[0]);\ + UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[1], f[1]);\ + UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[0], f[2]);\ + UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[3], f[3]);\ +} while (0) + +#define VERT_COPY_RGBA( v0, v1 ) \ + *(GLuint *)&v0->pargb = *(GLuint *)&v1->pargb + +#define VERT_SAVE_RGBA( idx ) \ + *(GLuint *)&color[idx] = *(GLuint *)&v[idx]->pargb + +#define VERT_RESTORE_RGBA( idx ) \ + *(GLuint *)&v[idx]->pargb = *(GLuint *)&color[idx] + + +#define VERT_SET_SPEC( dst, f ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[2], f[0]);\ + UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[1], f[1]);\ + UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[0], f[2]);\ +} while (0) + +#define VERT_COPY_SPEC( v0, v1 ) \ + *(GLuint *)&v0->pspec = *(GLuint *)&v1->pspec + +#define VERT_SAVE_SPEC( idx ) \ + *(GLuint *)&spec[idx] = *(GLuint *)&v[idx]->pspec + +#define VERT_RESTORE_SPEC( idx ) \ + *(GLuint *)&v[idx]->pspec = *(GLuint *)&spec[idx] + + +#define LOCAL_VARS(n) \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GLubyte color[n][4], spec[n][4]; \ + (void) color; (void) spec; +#else /* !FX_PACKEDCOLOR */ +#define VERT_SET_RGBA( dst, f ) \ +do { \ + CNORM(dst->r, f[0]); \ + CNORM(dst->g, f[1]); \ + CNORM(dst->b, f[2]); \ + CNORM(dst->a, f[3]); \ +} while (0) + +#define VERT_COPY_RGBA( v0, v1 ) \ +do { \ + COPY_FLOAT(v0->r, v1->r); \ + COPY_FLOAT(v0->g, v1->g); \ + COPY_FLOAT(v0->b, v1->b); \ + COPY_FLOAT(v0->a, v1->a); \ +} while (0) + +#define VERT_SAVE_RGBA( idx ) \ +do { \ + COPY_FLOAT(color[idx][0], v[idx]->r); \ + COPY_FLOAT(color[idx][1], v[idx]->g); \ + COPY_FLOAT(color[idx][2], v[idx]->b); \ + COPY_FLOAT(color[idx][3], v[idx]->a); \ +} while (0) + +#define VERT_RESTORE_RGBA( idx ) \ +do { \ + COPY_FLOAT(v[idx]->r, color[idx][0]); \ + COPY_FLOAT(v[idx]->g, color[idx][1]); \ + COPY_FLOAT(v[idx]->b, color[idx][2]); \ + COPY_FLOAT(v[idx]->a, color[idx][3]); \ +} while (0) + + +#define VERT_SET_SPEC( dst, f ) \ +do { \ + CNORM(dst->r1, f[0]); \ + CNORM(dst->g1, f[1]); \ + CNORM(dst->b1, f[2]); \ +} while (0) + +#define VERT_COPY_SPEC( v0, v1 ) \ +do { \ + COPY_FLOAT(v0->r1, v1->r1); \ + COPY_FLOAT(v0->g1, v1->g1); \ + COPY_FLOAT(v0->b1, v1->b1); \ +} while (0) + +#define VERT_SAVE_SPEC( idx ) \ +do { \ + COPY_FLOAT(spec[idx][0], v[idx]->r1); \ + COPY_FLOAT(spec[idx][1], v[idx]->g1); \ + COPY_FLOAT(spec[idx][2], v[idx]->b1); \ +} while (0) + +#define VERT_RESTORE_SPEC( idx ) \ +do { \ + COPY_FLOAT(v[idx]->r1, spec[idx][0]); \ + COPY_FLOAT(v[idx]->g1, spec[idx][1]); \ + COPY_FLOAT(v[idx]->b1, spec[idx][2]); \ +} while (0) + + +#define LOCAL_VARS(n) \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GLfloat color[n][4], spec[n][4]; \ + (void) color; (void) spec; +#endif /* !FX_PACKEDCOLOR */ + + +/*********************************************************************** + * Twoside stencil * + ***********************************************************************/ +#define SETUP_STENCIL(f) if (f) fxSetupStencilFace(ctx, f) +#define UNSET_STENCIL(f) if (f) fxSetupStencil(ctx) + + +/*********************************************************************** + * Functions to draw basic unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) if (fxMesa->raster_primitive != reduced_prim[x]) \ + fxRasterPrimitive( ctx, reduced_prim[x] ) +#define RENDER_PRIMITIVE fxMesa->render_primitive +#define IND FX_FALLBACK_BIT +#define TAG(x) x +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + +/*********************************************************************** + * Functions to draw GL primitives * + ***********************************************************************/ + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + + +/* Fx doesn't support provoking-vertex flat-shading? + */ +#define IND (FX_FLAT_BIT) +#define TAG(x) x##_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT|FX_FLAT_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback_flat +#include "tnl_dd/t_dd_tritmp.h" + + +/* 2-sided stencil begin */ +#define IND (FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_unfilled_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_unfilled_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_unfilled_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_unfilled_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_unfilled_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_unfilled_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_unfilled_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback_twostencil +#include "tnl_dd/t_dd_tritmp.h" + + +/* Fx doesn't support provoking-vertex flat-shading? + */ +#define IND (FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_unfilled_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_unfilled_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_unfilled_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_unfilled_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_unfilled_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_offset_unfilled_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_unfilled_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \ + FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback_flat_twostencil +#include "tnl_dd/t_dd_tritmp.h" +/* 2-sided stencil end */ + + +static void init_rast_tab( void ) +{ + init(); + init_offset(); + init_twoside(); + init_twoside_offset(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); + init_fallback(); + init_offset_fallback(); + init_twoside_fallback(); + init_twoside_offset_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); + + init_flat(); + init_offset_flat(); + init_twoside_flat(); + init_twoside_offset_flat(); + init_unfilled_flat(); + init_offset_unfilled_flat(); + init_twoside_unfilled_flat(); + init_twoside_offset_unfilled_flat(); + init_fallback_flat(); + init_offset_fallback_flat(); + init_twoside_fallback_flat(); + init_twoside_offset_fallback_flat(); + init_unfilled_fallback_flat(); + init_offset_unfilled_fallback_flat(); + init_twoside_unfilled_fallback_flat(); + init_twoside_offset_unfilled_fallback_flat(); + + /* 2-sided stencil begin */ + init_twostencil(); + init_offset_twostencil(); + init_twoside_twostencil(); + init_twoside_offset_twostencil(); + init_unfilled_twostencil(); + init_offset_unfilled_twostencil(); + init_twoside_unfilled_twostencil(); + init_twoside_offset_unfilled_twostencil(); + init_fallback_twostencil(); + init_offset_fallback_twostencil(); + init_twoside_fallback_twostencil(); + init_twoside_offset_fallback_twostencil(); + init_unfilled_fallback_twostencil(); + init_offset_unfilled_fallback_twostencil(); + init_twoside_unfilled_fallback_twostencil(); + init_twoside_offset_unfilled_fallback_twostencil(); + + init_flat_twostencil(); + init_offset_flat_twostencil(); + init_twoside_flat_twostencil(); + init_twoside_offset_flat_twostencil(); + init_unfilled_flat_twostencil(); + init_offset_unfilled_flat_twostencil(); + init_twoside_unfilled_flat_twostencil(); + init_twoside_offset_unfilled_flat_twostencil(); + init_fallback_flat_twostencil(); + init_offset_fallback_flat_twostencil(); + init_twoside_fallback_flat_twostencil(); + init_twoside_offset_fallback_flat_twostencil(); + init_unfilled_fallback_flat_twostencil(); + init_offset_unfilled_fallback_flat_twostencil(); + init_twoside_unfilled_fallback_flat_twostencil(); + init_twoside_offset_unfilled_fallback_flat_twostencil(); + /* 2-sided stencil end */ +} + + +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ + + +/* Accelerate vertex buffer rendering when renderindex == 0 and + * there is no clipping. + */ +#define INIT(x) fxRenderPrimitive( ctx, x ) + +static void fx_render_vb_points( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + GLint i; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_points\n"); + } + + INIT(GL_POINTS); + + /* Adjust point coords */ + for (i = start; i < count; i++) { + fxVB[i].x += PNT_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y += PNT_Y_OFFSET - TRI_Y_OFFSET; + } + + grDrawVertexArrayContiguous( GR_POINTS, count-start, + fxVB + start, sizeof(GrVertex)); + /* restore point coords */ + for (i = start; i < count; i++) { + fxVB[i].x -= PNT_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y -= PNT_Y_OFFSET - TRI_Y_OFFSET; + } +} + +static void fx_render_vb_line_strip( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + GLint i; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_line_strip\n"); + } + + INIT(GL_LINE_STRIP); + + /* adjust line coords */ + for (i = start; i < count; i++) { + fxVB[i].x += LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y += LINE_Y_OFFSET - TRI_Y_OFFSET; + } + + grDrawVertexArrayContiguous( GR_LINE_STRIP, count-start, + fxVB + start, sizeof(GrVertex)); + + /* restore line coords */ + for (i = start; i < count; i++) { + fxVB[i].x -= LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y -= LINE_Y_OFFSET - TRI_Y_OFFSET; + } +} + +static void fx_render_vb_line_loop( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + GLint i; + GLint j = start; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_line_loop\n"); + } + + INIT(GL_LINE_LOOP); + + if (!(flags & PRIM_BEGIN)) { + j++; + } + + /* adjust line coords */ + for (i = start; i < count; i++) { + fxVB[i].x += LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y += LINE_Y_OFFSET - TRI_Y_OFFSET; + } + + grDrawVertexArrayContiguous( GR_LINE_STRIP, count-j, + fxVB + j, sizeof(GrVertex)); + + if (flags & PRIM_END) + grDrawLine( fxVB + (count - 1), + fxVB + start ); + + /* restore line coords */ + for (i = start; i < count; i++) { + fxVB[i].x -= LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y -= LINE_Y_OFFSET - TRI_Y_OFFSET; + } +} + +static void fx_render_vb_lines( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + GLint i; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_lines\n"); + } + + INIT(GL_LINES); + + /* adjust line coords */ + for (i = start; i < count; i++) { + fxVB[i].x += LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y += LINE_Y_OFFSET - TRI_Y_OFFSET; + } + + grDrawVertexArrayContiguous( GR_LINES, count-start, + fxVB + start, sizeof(GrVertex)); + + /* restore line coords */ + for (i = start; i < count; i++) { + fxVB[i].x -= LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y -= LINE_Y_OFFSET - TRI_Y_OFFSET; + } +} + +static void fx_render_vb_triangles( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + GLuint j; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_triangles\n"); + } + + INIT(GL_TRIANGLES); + + for (j=start+2; j<count; j+=3) { + grDrawTriangle(fxVB + (j-2), fxVB + (j-1), fxVB + j); + } +} + + +static void fx_render_vb_tri_strip( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_tri_strip\n"); + } + + INIT(GL_TRIANGLE_STRIP); + + /* no GR_TRIANGLE_STRIP_CONTINUE?!? */ + + grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP, count-start, + fxVB + start, sizeof(GrVertex)); +} + + +static void fx_render_vb_tri_fan( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_tri_fan\n"); + } + + INIT(GL_TRIANGLE_FAN); + + grDrawVertexArrayContiguous( GR_TRIANGLE_FAN, count-start, + fxVB + start, sizeof(GrVertex) ); +} + +static void fx_render_vb_quads( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + GLuint i; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_quads\n"); + } + + INIT(GL_QUADS); + + for (i = start + 3 ; i < count ; i += 4 ) { +#define VERT(x) (fxVB + (x)) + GrVertex *_v_[4]; + _v_[0] = VERT(i); + _v_[1] = VERT(i-3); + _v_[2] = VERT(i-2); + _v_[3] = VERT(i-1); + grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_); + /*grDrawTriangle( VERT(i-3), VERT(i-2), VERT(i) );*/ + /*grDrawTriangle( VERT(i-2), VERT(i-1), VERT(i) );*/ +#undef VERT + } +} + +static void fx_render_vb_quad_strip( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_quad_strip\n"); + } + + INIT(GL_QUAD_STRIP); + + count -= (count-start)&1; + + grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP, + count-start, fxVB + start, sizeof(GrVertex)); +} + +static void fx_render_vb_poly( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrVertex *fxVB = fxMesa->verts; + (void) flags; + + if (TDFX_DEBUG & VERBOSE_VARRAY) { + fprintf(stderr, "fx_render_vb_poly\n"); + } + + INIT(GL_POLYGON); + + grDrawVertexArrayContiguous( GR_POLYGON, count-start, + fxVB + start, sizeof(GrVertex)); +} + +static void fx_render_vb_noop( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + (void) (ctx && start && count && flags); +} + +static void (*fx_render_tab_verts[GL_POLYGON+2])(GLcontext *, + GLuint, + GLuint, + GLuint) = +{ + fx_render_vb_points, + fx_render_vb_lines, + fx_render_vb_line_loop, + fx_render_vb_line_strip, + fx_render_vb_triangles, + fx_render_vb_tri_strip, + fx_render_vb_tri_fan, + fx_render_vb_quads, + fx_render_vb_quad_strip, + fx_render_vb_poly, + fx_render_vb_noop, +}; +#undef INIT + + +/**********************************************************************/ +/* Render whole (indexed) begin/end objects */ +/**********************************************************************/ + + +#define VERT(x) (vertptr + x) + +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + grDrawPoint( VERT(ELT(start)) ); + +#define RENDER_LINE( v0, v1 ) \ + grDrawLine( VERT(v0), VERT(v1) ) + +#define RENDER_TRI( v0, v1, v2 ) \ + grDrawTriangle( VERT(v0), VERT(v1), VERT(v2) ) + +#define RENDER_QUAD( v0, v1, v2, v3 ) \ + do { \ + GrVertex *_v_[4]; \ + _v_[0] = VERT(v3);\ + _v_[1] = VERT(v0);\ + _v_[2] = VERT(v1);\ + _v_[3] = VERT(v2);\ + grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\ + /*grDrawTriangle( VERT(v0), VERT(v1), VERT(v3) );*/\ + /*grDrawTriangle( VERT(v1), VERT(v2), VERT(v3) );*/\ + } while (0) + +#define INIT(x) fxRenderPrimitive( ctx, x ) + +#undef LOCAL_VARS +#define LOCAL_VARS \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GrVertex *vertptr = fxMesa->verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; + +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS + +/* Elts, no clipping. + */ +#undef ELT +#undef TAG +#define TAG(x) fx_##x##_elts +#define ELT(x) elt[x] +#include "tnl_dd/t_dd_rendertmp.h" + +/* Verts, no clipping. + */ +#undef ELT +#undef TAG +#define TAG(x) fx_##x##_verts +#define ELT(x) x +/*#include "tnl_dd/t_dd_rendertmp.h"*/ /* we have fx_render_vb_* now */ + + + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + + + +static void fxRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint prim = fxMesa->render_primitive; + + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, + PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; + } + + /* Restore the render primitive + */ + if (prim != GL_POLYGON) + tnl->Driver.Render.PrimitiveNotify( ctx, prim ); +} + + +static void fxFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + int i; + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GrVertex *vertptr = fxMesa->verts; + if (n == 3) { + grDrawTriangle( VERT(elts[0]), VERT(elts[1]), VERT(elts[2]) ); + } else if (n <= 32) { + GrVertex *newvptr[32]; + for (i = 0 ; i < n ; i++) { + newvptr[i] = VERT(elts[i]); + } + grDrawVertexArray(GR_TRIANGLE_FAN, n, newvptr); + } else { + const GrVertex *start = VERT(elts[0]); + for (i = 2 ; i < n ; i++) { + grDrawTriangle( start, VERT(elts[i-1]), VERT(elts[i]) ); + } + } +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + +#define POINT_FALLBACK (DD_POINT_SMOOTH) +#define LINE_FALLBACK (DD_LINE_STIPPLE) +#define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_STIPPLE) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK) +#define ANY_RASTER_FLAGS (DD_FLATSHADE | DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET \ + | DD_TRI_UNFILLED | DD_TRI_TWOSTENCIL) + + + +void fxDDChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_TWOSTENCIL) index |= FX_TWOSTENCIL_BIT; + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= FX_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= FX_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= FX_UNFILLED_BIT; + if (flags & DD_FLATSHADE) index |= FX_FLAT_BIT; + } + + fxMesa->draw_point = fx_draw_point; + fxMesa->draw_line = fx_draw_line; + fxMesa->draw_tri = fx_draw_triangle; + + /* Hook in fallbacks for specific primitives. */ + if (flags & (POINT_FALLBACK| + LINE_FALLBACK| + TRI_FALLBACK)) + { + if (fxMesa->verbose) { + fprintf(stderr, "Voodoo ! fallback (%x), raster (%x)\n", + flags & ANY_FALLBACK_FLAGS, flags & ANY_RASTER_FLAGS); + } + + if (flags & POINT_FALLBACK) + fxMesa->draw_point = fx_fallback_point; + + if (flags & LINE_FALLBACK) + fxMesa->draw_line = fx_fallback_line; + + if (flags & TRI_FALLBACK) + fxMesa->draw_tri = fx_fallback_tri; + + index |= FX_FALLBACK_BIT; + } + } + + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = fx_render_tab_verts; + tnl->Driver.Render.PrimTabElts = fx_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = fxFastRenderClippedPoly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = fxRenderClippedPoly; + } + + fxMesa->render_index = index; + + /* [dBorca] Hack alert: more a trick than a real plug-in!!! */ + if (flags & (DD_POINT_SIZE | DD_POINT_ATTEN)) { + /* We need to set the point primitive to go through "rast_tab", + * to make sure "POINT" calls "fxMesa->draw_point" instead of + * "grDrawPoint". We can achieve this by using FX_FALLBACK_BIT + * (not really a total rasterization fallback, so we don't alter + * "fxMesa->render_index"). If we get here with DD_POINT_SMOOTH, + * we're done, cos we've already set _tnl_render_tab_{verts|elts} + * above. Otherwise, the T&L engine can optimize point rendering + * by using fx_render_tab_{verts|elts} hence the extra work. + */ + if (flags & DD_POINT_SMOOTH) { + fxMesa->draw_point = fx_draw_point_wide_aa; + } else { + fxMesa->draw_point = fx_draw_point_wide; + fx_render_tab_verts[0] = fx_render_pw_verts; + fx_render_tab_elts[0] = fx_render_pw_elts; + } + tnl->Driver.Render.Points = rast_tab[index|FX_FALLBACK_BIT].points; + } else { + fx_render_tab_verts[0] = fx_render_vb_points; + fx_render_tab_elts[0] = fx_render_points_elts; + } +} + + +/**********************************************************************/ +/* Runtime render state and callbacks */ +/**********************************************************************/ + +static void fxRunPipeline( GLcontext *ctx ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint new_gl_state = fxMesa->new_gl_state; + + if (TDFX_DEBUG & VERBOSE_PIPELINE) { + fprintf(stderr, "fxRunPipeline()\n"); + } + +#if 0 + /* Recalculate fog table on projection matrix changes. This used to + * be triggered by the NearFar callback. + */ + if (new_gl_state & _NEW_PROJECTION) + fxMesa->new_state |= FX_NEW_FOG; +#endif + + if (new_gl_state & _FX_NEW_IS_IN_HARDWARE) + fxCheckIsInHardware(ctx); + + if (fxMesa->new_state) + fxSetupFXUnits(ctx); + + if (!fxMesa->fallback) { + if (new_gl_state & _FX_NEW_RENDERSTATE) + fxDDChooseRenderState(ctx); + + if (new_gl_state & _FX_NEW_SETUP_FUNCTION) + fxChooseVertexState(ctx); + } + + if (new_gl_state & _NEW_TEXTURE) { + struct gl_texture_unit *t0 = &ctx->Texture.Unit[fxMesa->tmu_source[0]]; + struct gl_texture_unit *t1 = &ctx->Texture.Unit[fxMesa->tmu_source[1]]; + + if (t0->_Current && FX_TEXTURE_DATA(t0)) { + fxMesa->s0scale = FX_TEXTURE_DATA(t0)->sScale; + fxMesa->t0scale = FX_TEXTURE_DATA(t0)->tScale; + fxMesa->inv_s0scale = 1.0F / fxMesa->s0scale; + fxMesa->inv_t0scale = 1.0F / fxMesa->t0scale; + } + + if (t1->_Current && FX_TEXTURE_DATA(t1)) { + fxMesa->s1scale = FX_TEXTURE_DATA(t1)->sScale; + fxMesa->t1scale = FX_TEXTURE_DATA(t1)->tScale; + fxMesa->inv_s1scale = 1.0F / fxMesa->s1scale; + fxMesa->inv_t1scale = 1.0F / fxMesa->t1scale; + } + } + + fxMesa->new_gl_state = 0; + + _tnl_run_pipeline( ctx ); +} + + + +/* Always called between RenderStart and RenderFinish --> We already + * hold the lock. + */ +static void fxRasterPrimitive( GLcontext *ctx, GLenum prim ) +{ + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + + fxMesa->raster_primitive = prim; + + fxSetupCull(ctx); +} + + + +/* Determine the rasterized primitive when not drawing unfilled + * polygons. + */ +static void fxRenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint rprim = reduced_prim[prim]; + + fxMesa->render_primitive = prim; + + if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + if (fxMesa->raster_primitive != rprim) { + fxRasterPrimitive( ctx, rprim ); + } +} + +static void fxRenderFinish( GLcontext *ctx ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (fxMesa->render_index & FX_FALLBACK_BIT) + _swrast_flush( ctx ); +} + + + +/**********************************************************************/ +/* Manage total rasterization fallbacks */ +/**********************************************************************/ + +static char *fallbackStrings[] = { + "3D/Rect/Cube Texture map", + "glDrawBuffer(GL_FRONT_AND_BACK)", + "Separate specular color", + "glEnable/Disable(GL_STENCIL_TEST)", + "glRenderMode(selection or feedback)", + "glLogicOp()", + "Texture env mode", + "Texture border", + "glColorMask", + "blend mode", + "multitex" +}; + + +static char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + + +void fxCheckIsInHardware( GLcontext *ctx ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = fxMesa->fallback; + GLuint newfallback = fxMesa->fallback = fx_check_IsInHardware( ctx ); + + if (newfallback) { + if (oldfallback == 0) { + if (fxMesa->verbose) { + fprintf(stderr, "Voodoo ! enter SW 0x%08x %s\n", newfallback, getFallbackString(newfallback)); + } + _swsetup_Wakeup( ctx ); + } + } + else { + if (oldfallback) { + _swrast_flush( ctx ); + tnl->Driver.Render.Start = fxCheckTexSizes; + tnl->Driver.Render.Finish = fxRenderFinish; + tnl->Driver.Render.PrimitiveNotify = fxRenderPrimitive; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = fxBuildVertices; + fxChooseVertexState(ctx); + fxDDChooseRenderState(ctx); + if (fxMesa->verbose) { + fprintf(stderr, "Voodoo ! leave SW 0x%08x %s\n", oldfallback, getFallbackString(oldfallback)); + } + } + tnl->Driver.Render.Multipass = NULL; + if (HAVE_SPEC && NEED_SECONDARY_COLOR(ctx)) { + tnl->Driver.Render.Multipass = fxMultipass_ColorSum; + /* obey stencil, but do not change it */ + fxMesa->multipass = GL_TRUE; + if (fxMesa->unitsState.stencilEnabled) { + fxMesa->new_state |= FX_NEW_STENCIL; + } + } + } +} + +void fxDDInitTriFuncs( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = fxRunPipeline; + tnl->Driver.Render.Start = fxCheckTexSizes; + tnl->Driver.Render.Finish = fxRenderFinish; + tnl->Driver.Render.PrimitiveNotify = fxRenderPrimitive; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = fxBuildVertices; + tnl->Driver.Render.Multipass = NULL; + + (void) fx_print_vertex; +} + + +/* [dBorca] Hack alert: + * doesn't work with blending. + */ +static GLboolean +fxMultipass_ColorSum (GLcontext *ctx, GLuint pass) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + static int t0 = 0; + static int t1 = 0; + + switch (pass) { + case 1: /* first pass: the TEXTURED triangles are drawn */ + /* set stencil's real values */ + fxMesa->multipass = GL_FALSE; + if (us->stencilEnabled) { + fxSetupStencil(ctx); + } + /* save per-pass data */ + fxMesa->restoreUnitsState = *us; + /* turn off texturing */ + t0 = ctx->Texture.Unit[0]._ReallyEnabled; + t1 = ctx->Texture.Unit[1]._ReallyEnabled; + ctx->Texture.Unit[0]._ReallyEnabled = 0; + ctx->Texture.Unit[1]._ReallyEnabled = 0; + /* SUM the colors */ + fxDDBlendEquationSeparate(ctx, GL_FUNC_ADD, GL_FUNC_ADD); + fxDDBlendFuncSeparate(ctx, GL_ONE, GL_ONE, GL_ZERO, GL_ONE); + fxDDEnable(ctx, GL_BLEND, GL_TRUE); + /* make sure we draw only where we want to */ + if (us->depthTestEnabled) { + switch (us->depthTestFunc) { + default: + fxDDDepthFunc(ctx, GL_EQUAL); + case GL_NEVER: + case GL_ALWAYS: + ; + } + fxDDDepthMask(ctx, GL_FALSE); + } + /* switch to secondary colors */ +#if FX_PACKEDCOLOR + grVertexLayout(GR_PARAM_PARGB, GR_VERTEX_PSPEC_OFFSET << 2, GR_PARAM_ENABLE); +#else /* !FX_PACKEDCOLOR */ + grVertexLayout(GR_PARAM_RGB, GR_VERTEX_SPEC_OFFSET << 2, GR_PARAM_ENABLE); +#endif /* !FX_PACKEDCOLOR */ + /* don't advertise new state */ + fxMesa->new_state = 0; + break; + case 2: /* 2nd pass (last): the secondary color is summed over texture */ + /* restore original state */ + *us = fxMesa->restoreUnitsState; + /* restore texturing */ + ctx->Texture.Unit[0]._ReallyEnabled = t0; + ctx->Texture.Unit[1]._ReallyEnabled = t1; + /* revert to primary colors */ +#if FX_PACKEDCOLOR + grVertexLayout(GR_PARAM_PARGB, GR_VERTEX_PARGB_OFFSET << 2, GR_PARAM_ENABLE); +#else /* !FX_PACKEDCOLOR */ + grVertexLayout(GR_PARAM_RGB, GR_VERTEX_RGB_OFFSET << 2, GR_PARAM_ENABLE); +#endif /* !FX_PACKEDCOLOR */ + break; + default: + assert(0); /* NOTREACHED */ + } + + /* update HW state */ + fxSetupBlend(ctx); + fxSetupDepthTest(ctx); + fxSetupTexture(ctx); + + return (pass == 1); +} + + +#else + + +/* + * Need this to provide at least one external definition. + */ + +extern int gl_fx_dummy_function_tris(void); +int +gl_fx_dummy_function_tris(void) +{ + return 0; +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvb.c b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvb.c new file mode 100644 index 000000000..34ada61f4 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvb.c @@ -0,0 +1,838 @@ +/* + * Mesa 3-D graphics library + * Version: 5.1 + * + * Copyright (C) 1999-2003 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 + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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: + * Keith Whitwell <keith@tungstengraphics.com> + * Daniel Borca <dborca@users.sourceforge.net> + */ + +#ifdef HAVE_CONFIG_H +#include "conf.h" +#endif + +#ifdef FX + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "macros.h" +#include "colormac.h" + +#include "math/m_translate.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" + +#include "fxdrv.h" + + +static void copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GrVertex *dst = fxMesa->verts + edst; + GrVertex *src = fxMesa->verts + esrc; + +#if FX_PACKEDCOLOR + *(GLuint *)&dst->pargb = *(GLuint *)&src->pargb; +#else /* !FX_PACKEDCOLOR */ + COPY_FLOAT(dst->r, src->r); + COPY_FLOAT(dst->g, src->g); + COPY_FLOAT(dst->b, src->b); + COPY_FLOAT(dst->a, src->a); +#endif /* !FX_PACKEDCOLOR */ +} + +static void copy_pv2( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GrVertex *dst = fxMesa->verts + edst; + GrVertex *src = fxMesa->verts + esrc; + +#if FX_PACKEDCOLOR + *(GLuint *)&dst->pargb = *(GLuint *)&src->pargb; + *(GLuint *)&dst->pspec = *(GLuint *)&src->pspec; +#else /* !FX_PACKEDCOLOR */ + COPY_FLOAT(dst->r, src->r); + COPY_FLOAT(dst->g, src->g); + COPY_FLOAT(dst->b, src->b); + COPY_FLOAT(dst->a, src->a); + COPY_FLOAT(dst->r1, src->r1); + COPY_FLOAT(dst->g1, src->g1); + COPY_FLOAT(dst->b1, src->b1); +#endif /* !FX_PACKEDCOLOR */ +} + +static struct { + void (*emit) (GLcontext *ctx, GLuint start, GLuint end, void *dest); + tnl_copy_pv_func copy_pv; + tnl_interp_func interp; + GLboolean (*check_tex_sizes) (GLcontext *ctx); + GLuint vertex_format; +} setup_tab[MAX_SETUP]; + + +#define GET_COLOR(ptr, idx) ((ptr)->data[idx]) + + +static void interp_extras( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + /* If stride is zero, ColorPtr[1] is constant across the VB, so + * there is no point interpolating between two values as they will + * be identical. This case is handled in t_dd_tritmp.h + */ + if (VB->ColorPtr[1]->stride) { + assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat)); + INTERP_4F( t, + GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], out), + GET_COLOR(VB->ColorPtr[1], in) ); + } + + if (VB->SecondaryColorPtr[1]) { + INTERP_3F( t, + GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], out), + GET_COLOR(VB->SecondaryColorPtr[1], in) ); + } + } + + if (VB->EdgeFlag) { + VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; + } + + setup_tab[FX_CONTEXT(ctx)->SetupIndex].interp(ctx, t, dst, out, in, + force_boundary); +} + +static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], src) ); + + if (VB->SecondaryColorPtr[1]) { + COPY_3FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], src) ); + } + } + + setup_tab[FX_CONTEXT(ctx)->SetupIndex].copy_pv(ctx, dst, src); +} + + +#define IND (SETUP_XYZW|SETUP_RGBA) +#define TAG(x) x##_wg +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_wgt0 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_wgt0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX) +#define TAG(x) x##_wgpt0 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\ + SETUP_PTEX) +#define TAG(x) x##_wgpt0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_PSIZ) +#define TAG(x) x##_wga +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PSIZ) +#define TAG(x) x##_wgt0a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|SETUP_PSIZ) +#define TAG(x) x##_wgt0t1a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX|SETUP_PSIZ) +#define TAG(x) x##_wgpt0a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\ + SETUP_PTEX|SETUP_PSIZ) +#define TAG(x) x##_wgpt0t1a +#include "fxvbtmp.h" + + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC) +#define TAG(x) x##_2wg +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0) +#define TAG(x) x##_2wgt0 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_2wgt0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PTEX) +#define TAG(x) x##_2wgpt0 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|\ + SETUP_PTEX) +#define TAG(x) x##_2wgpt0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_PSIZ) +#define TAG(x) x##_2wga +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PSIZ) +#define TAG(x) x##_2wgt0a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|SETUP_PSIZ) +#define TAG(x) x##_2wgt0t1a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PTEX|SETUP_PSIZ) +#define TAG(x) x##_2wgpt0a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|\ + SETUP_PTEX|SETUP_PSIZ) +#define TAG(x) x##_2wgpt0t1a +#include "fxvbtmp.h" + +/* fog { */ +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_FOGC) +#define TAG(x) x##_wgf +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_FOGC) +#define TAG(x) x##_wgt0f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|SETUP_FOGC) +#define TAG(x) x##_wgt0t1f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX|SETUP_FOGC) +#define TAG(x) x##_wgpt0f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\ + SETUP_PTEX|SETUP_FOGC) +#define TAG(x) x##_wgpt0t1f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wgaf +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wgt0af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wgt0t1af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wgpt0af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\ + SETUP_PTEX|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wgpt0t1af +#include "fxvbtmp.h" + + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_FOGC) +#define TAG(x) x##_2wgf +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_FOGC) +#define TAG(x) x##_2wgt0f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|SETUP_FOGC) +#define TAG(x) x##_2wgt0t1f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PTEX|SETUP_FOGC) +#define TAG(x) x##_2wgpt0f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|\ + SETUP_PTEX|SETUP_FOGC) +#define TAG(x) x##_2wgpt0t1f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wgaf +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wgt0af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wgt0t1af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PTEX|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wgpt0af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|\ + SETUP_PTEX|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wgpt0t1af +#include "fxvbtmp.h" +/* fog } */ + + +/* Snapping for voodoo-1 + */ +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA) +#define TAG(x) x##_wsg +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_wsgt0 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1) +#define TAG(x) x##_wsgt0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_PTEX) +#define TAG(x) x##_wsgpt0 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PTEX) +#define TAG(x) x##_wsgpt0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_PSIZ) +#define TAG(x) x##_wsga +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|SETUP_PSIZ) +#define TAG(x) x##_wsgt0a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PSIZ) +#define TAG(x) x##_wsgt0t1a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_PTEX|SETUP_PSIZ) +#define TAG(x) x##_wsgpt0a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PTEX|SETUP_PSIZ) +#define TAG(x) x##_wsgpt0t1a +#include "fxvbtmp.h" + + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC) +#define TAG(x) x##_2wsg +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0) +#define TAG(x) x##_2wsgt0 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_TMU1) +#define TAG(x) x##_2wsgt0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_PTEX) +#define TAG(x) x##_2wsgpt0 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PTEX) +#define TAG(x) x##_2wsgpt0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_PSIZ) +#define TAG(x) x##_2wsga +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PSIZ) +#define TAG(x) x##_2wsgt0a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PSIZ) +#define TAG(x) x##_2wsgt0t1a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_PTEX|SETUP_PSIZ) +#define TAG(x) x##_2wsgpt0a +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PTEX|SETUP_PSIZ) +#define TAG(x) x##_2wsgpt0t1a +#include "fxvbtmp.h" + +/* fog { */ +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_FOGC) +#define TAG(x) x##_wsgf +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|SETUP_FOGC) +#define TAG(x) x##_wsgt0f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1|SETUP_FOGC) +#define TAG(x) x##_wsgt0t1f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_PTEX|SETUP_FOGC) +#define TAG(x) x##_wsgpt0f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PTEX|SETUP_FOGC) +#define TAG(x) x##_wsgpt0t1f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wsgaf +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wsgt0af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wsgt0t1af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_PTEX|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wsgpt0af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PTEX|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_wsgpt0t1af +#include "fxvbtmp.h" + + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_FOGC) +#define TAG(x) x##_2wsgf +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_FOGC) +#define TAG(x) x##_2wsgt0f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_TMU1|SETUP_FOGC) +#define TAG(x) x##_2wsgt0t1f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_PTEX|SETUP_FOGC) +#define TAG(x) x##_2wsgpt0f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PTEX|SETUP_FOGC) +#define TAG(x) x##_2wsgpt0t1f +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wsgaf +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wsgt0af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wsgt0t1af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_PTEX|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wsgpt0af +#include "fxvbtmp.h" + +#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\ + SETUP_TMU1|SETUP_PTEX|SETUP_PSIZ|SETUP_FOGC) +#define TAG(x) x##_2wsgpt0t1af +#include "fxvbtmp.h" +/* fog } */ + + +/* Vertex repair (multipass rendering) + */ +#define IND (SETUP_RGBA) +#define TAG(x) x##_g +#include "fxvbtmp.h" + +#define IND (SETUP_TMU0) +#define TAG(x) x##_t0 +#include "fxvbtmp.h" + +#define IND (SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_t0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_gt0 +#include "fxvbtmp.h" + +#define IND (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_gt0t1 +#include "fxvbtmp.h" + + +#define IND (SETUP_RGBA|SETUP_SPEC) +#define TAG(x) x##_2g +#include "fxvbtmp.h" + +#define IND (SETUP_TMU0|SETUP_SPEC) +#define TAG(x) x##_2t0 +#include "fxvbtmp.h" + +#define IND (SETUP_TMU0|SETUP_SPEC|SETUP_TMU1) +#define TAG(x) x##_2t0t1 +#include "fxvbtmp.h" + +#define IND (SETUP_RGBA|SETUP_SPEC|SETUP_TMU0) +#define TAG(x) x##_2gt0 +#include "fxvbtmp.h" + +#define IND (SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_2gt0t1 +#include "fxvbtmp.h" + + + +static void init_setup_tab( void ) +{ + init_wg(); + init_wgt0(); + init_wgt0t1(); + init_wgpt0(); + init_wgpt0t1(); + init_wga(); + init_wgt0a(); + init_wgt0t1a(); + init_wgpt0a(); + init_wgpt0t1a(); + init_2wg(); + init_2wgt0(); + init_2wgt0t1(); + init_2wgpt0(); + init_2wgpt0t1(); + init_2wga(); + init_2wgt0a(); + init_2wgt0t1a(); + init_2wgpt0a(); + init_2wgpt0t1a(); + init_wgf(); + init_wgt0f(); + init_wgt0t1f(); + init_wgpt0f(); + init_wgpt0t1f(); + init_wgaf(); + init_wgt0af(); + init_wgt0t1af(); + init_wgpt0af(); + init_wgpt0t1af(); + init_2wgf(); + init_2wgt0f(); + init_2wgt0t1f(); + init_2wgpt0f(); + init_2wgpt0t1f(); + init_2wgaf(); + init_2wgt0af(); + init_2wgt0t1af(); + init_2wgpt0af(); + init_2wgpt0t1af(); + + init_wsg(); + init_wsgt0(); + init_wsgt0t1(); + init_wsgpt0(); + init_wsgpt0t1(); + init_wsga(); + init_wsgt0a(); + init_wsgt0t1a(); + init_wsgpt0a(); + init_wsgpt0t1a(); + init_2wsg(); + init_2wsgt0(); + init_2wsgt0t1(); + init_2wsgpt0(); + init_2wsgpt0t1(); + init_2wsga(); + init_2wsgt0a(); + init_2wsgt0t1a(); + init_2wsgpt0a(); + init_2wsgpt0t1a(); + init_wsgf(); + init_wsgt0f(); + init_wsgt0t1f(); + init_wsgpt0f(); + init_wsgpt0t1f(); + init_wsgaf(); + init_wsgt0af(); + init_wsgt0t1af(); + init_wsgpt0af(); + init_wsgpt0t1af(); + init_2wsgf(); + init_2wsgt0f(); + init_2wsgt0t1f(); + init_2wsgpt0f(); + init_2wsgpt0t1f(); + init_2wsgaf(); + init_2wsgt0af(); + init_2wsgt0t1af(); + init_2wsgpt0af(); + init_2wsgpt0t1af(); + + init_g(); + init_t0(); + init_t0t1(); + init_gt0(); + init_gt0t1(); + init_2g(); + init_2t0(); + init_2t0t1(); + init_2gt0(); + init_2gt0t1(); +} + + +void fxPrintSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s(%x): %s%s%s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & SETUP_XYZW) ? " xyzw," : "", + (flags & SETUP_SNAP) ? " snap," : "", + (flags & SETUP_RGBA) ? " rgba," : "", + (flags & SETUP_TMU0) ? " tex-0," : "", + (flags & SETUP_TMU1) ? " tex-1," : "", + (flags & SETUP_PSIZ) ? " psiz," : "", + (flags & SETUP_SPEC) ? " spec," : "", + (flags & SETUP_FOGC) ? " fog," : ""); +} + + + +void fxCheckTexSizes( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + + if (!setup_tab[fxMesa->SetupIndex].check_tex_sizes(ctx)) { + GLuint ind = fxMesa->SetupIndex |= (SETUP_PTEX|SETUP_RGBA); + + /* Tdfx handles projective textures nicely; just have to change + * up to the new vertex format. + */ + if (setup_tab[ind].vertex_format != fxMesa->stw_hint_state) { + + fxMesa->stw_hint_state = setup_tab[ind].vertex_format; + FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state); + + /* This is required as we have just changed the vertex + * format, so the interp routines must also change. + * In the unfilled and twosided cases we are using the + * Extras ones anyway, so leave them in place. + */ + if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + tnl->Driver.Render.Interp = setup_tab[fxMesa->SetupIndex].interp; + } + } + } +} + + +void fxBuildVertices( GLcontext *ctx, GLuint start, GLuint end, + GLuint newinputs ) +{ + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GrVertex *v = (fxMesa->verts + start); + + if (!newinputs) + return; + + if (newinputs & VERT_BIT_POS) { + setup_tab[fxMesa->SetupIndex].emit( ctx, start, end, v ); + } else { + GLuint ind = 0; + + if (newinputs & VERT_BIT_COLOR0) + ind |= SETUP_RGBA; + + if (newinputs & VERT_BIT_COLOR1) + ind |= SETUP_SPEC; + + if (newinputs & VERT_BIT_FOG) + ind |= SETUP_FOGC; + + if (newinputs & VERT_BIT_TEX0) + ind |= SETUP_TMU0; + + if (newinputs & VERT_BIT_TEX1) + ind |= SETUP_TMU0|SETUP_TMU1; + + if (fxMesa->SetupIndex & SETUP_PTEX) + ind = ~0; + + ind &= fxMesa->SetupIndex; + + if (ind) { + setup_tab[ind].emit( ctx, start, end, v ); + } + } +} + + +void fxChooseVertexState( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + GLuint ind = SETUP_XYZW|SETUP_RGBA; + + if (fxMesa->snapVertices) + ind |= SETUP_SNAP; + + fxMesa->tmu_source[0] = 0; + fxMesa->tmu_source[1] = 1; + + if (ctx->Texture._EnabledUnits & 0x2) { + if (ctx->Texture._EnabledUnits & 0x1) { + ind |= SETUP_TMU1; + } + ind |= SETUP_TMU0; + fxMesa->tmu_source[0] = 1; + fxMesa->tmu_source[1] = 0; + } + else if (ctx->Texture._EnabledUnits & 0x1) { + ind |= SETUP_TMU0; + } + + if (ctx->_TriangleCaps & DD_POINT_ATTEN) { + ind |= SETUP_PSIZ; + } + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { + ind |= SETUP_SPEC; + } + + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + ind |= SETUP_FOGC; + } + + fxMesa->SetupIndex = ind; + + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = interp_extras; + tnl->Driver.Render.CopyPV = copy_pv_extras; + } else { + tnl->Driver.Render.Interp = setup_tab[ind].interp; + tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv; + } + + if (setup_tab[ind].vertex_format != fxMesa->stw_hint_state) { + fxMesa->stw_hint_state = setup_tab[ind].vertex_format; + FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state); + } +} + + + +void fxAllocVB( GLcontext *ctx ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + static int firsttime = 1; + if (firsttime) { + init_setup_tab(); + firsttime = 0; + } + + fxMesa->verts = (GrVertex *)ALIGN_MALLOC(size * sizeof(GrVertex), 32); + fxMesa->SetupIndex = SETUP_XYZW|SETUP_RGBA; +} + + +void fxFreeVB( GLcontext *ctx ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + if (fxMesa->verts) { + ALIGN_FREE(fxMesa->verts); + fxMesa->verts = 0; + } +} +#else + + +/* + * Need this to provide at least one external definition. + */ + +extern int gl_fx_dummy_function_vb(void); +int +gl_fx_dummy_function_vb(void) +{ + return 0; +} + +#endif /* FX */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvbtmp.h b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvbtmp.h new file mode 100644 index 000000000..f7970c78e --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvbtmp.h @@ -0,0 +1,369 @@ +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * Copyright (C) 1999-2002 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: + * Keith Whitwell <keith@tungstengraphics.com> + * Daniel Borca <dborca@users.sourceforge.net> + */ + + +#define VIEWPORT_X(dst,x) dst = s[0] * x + s[12] +#define VIEWPORT_Y(dst,y) dst = s[5] * y + s[13] +#define VIEWPORT_Z(dst,z) dst = s[10] * z + s[14] + +static void TAG(emit)( GLcontext *ctx, + GLuint start, GLuint end, + void *dest ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint tmu0_source = fxMesa->tmu_source[0]; + GLuint tmu1_source = fxMesa->tmu_source[1]; + GLfloat (*tc0)[4], (*tc1)[4]; + GLfloat (*col)[4], (*spec)[4]; + GLuint tc0_stride, tc1_stride, col_stride, spec_stride; + GLuint tc0_size, tc1_size, col_size; + GLfloat (*proj)[4] = VB->NdcPtr->data; + GLuint proj_stride = VB->NdcPtr->stride; + GLfloat (*psize)[4]; + GLuint psize_stride; + GLfloat (*fog)[4]; + GLuint fog_stride; + GrVertex *v = (GrVertex *)dest; + GLfloat u0scale,v0scale,u1scale,v1scale; + const GLubyte *mask = VB->ClipMask; + const GLfloat *const s = ctx->Viewport._WindowMap.m; + int i; + + if (IND & SETUP_PSIZ) { + psize = VB->PointSizePtr->data; + psize_stride = VB->PointSizePtr->stride; + } + + if (IND & SETUP_TMU0) { + tc0 = VB->TexCoordPtr[tmu0_source]->data; + tc0_stride = VB->TexCoordPtr[tmu0_source]->stride; + u0scale = fxMesa->s0scale; + v0scale = fxMesa->t0scale; + if (IND & SETUP_PTEX) + tc0_size = VB->TexCoordPtr[tmu0_source]->size; + } + + if (IND & SETUP_TMU1) { + tc1 = VB->TexCoordPtr[tmu1_source]->data; + tc1_stride = VB->TexCoordPtr[tmu1_source]->stride; + u1scale = fxMesa->s1scale; /* wrong if tmu1_source == 0, possible? */ + v1scale = fxMesa->t1scale; + if (IND & SETUP_PTEX) + tc1_size = VB->TexCoordPtr[tmu1_source]->size; + } + + if (IND & SETUP_RGBA) { + col = VB->ColorPtr[0]->data; + col_stride = VB->ColorPtr[0]->stride; + col_size = VB->ColorPtr[0]->size; + } + + if (IND & SETUP_SPEC) { + spec = VB->SecondaryColorPtr[0]->data; + spec_stride = VB->SecondaryColorPtr[0]->stride; + } + + if (IND & SETUP_FOGC) { + fog = VB->FogCoordPtr->data; + fog_stride = VB->FogCoordPtr->stride; + } + + if (start) { + proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride); + if (IND & SETUP_PSIZ) + psize = (GLfloat (*)[4])((GLubyte *)psize + start * psize_stride); + if (IND & SETUP_TMU0) + tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride); + if (IND & SETUP_TMU1) + tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride); + if (IND & SETUP_RGBA) + STRIDE_4F(col, start * col_stride); + if (IND & SETUP_SPEC) + STRIDE_4F(spec, start * spec_stride); + if (IND & SETUP_FOGC) + fog = (GLfloat (*)[4])((GLubyte *)fog + start * fog_stride); + } + + for (i=start; i < end; i++, v++) { + if (IND & SETUP_PSIZ) { + v->psize = psize[0][0]; + psize = (GLfloat (*)[4])((GLubyte *)psize + psize_stride); + } + + if (IND & SETUP_XYZW) { + if (mask[i] == 0) { + /* unclipped */ + VIEWPORT_X(v->x, proj[0][0]); + VIEWPORT_Y(v->y, proj[0][1]); + VIEWPORT_Z(v->ooz, proj[0][2]); + v->oow = proj[0][3]; + + if (IND & SETUP_SNAP) { +#if defined(USE_IEEE) + const float snapper = (3L << 18); + v->x += snapper; + v->x -= snapper; + v->y += snapper; + v->y -= snapper; +#else + v->x = ((int) (v->x * 16.0f)) * (1.0f / 16.0f); + v->y = ((int) (v->y * 16.0f)) * (1.0f / 16.0f); +#endif + } + } else { + /* clipped */ + v->oow = 1.0; + } + + proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride); + } + if (IND & SETUP_RGBA) { +#if FX_PACKEDCOLOR + UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[2], col[0][0]); + UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[1], col[0][1]); + UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[0], col[0][2]); + if (col_size == 4) { + UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[3], col[0][3]); + } else { + v->pargb[3] = 255; + } +#else /* !FX_PACKEDCOLOR */ + CNORM(v->r, col[0][0]); + CNORM(v->g, col[0][1]); + CNORM(v->b, col[0][2]); + if (col_size == 4) { + CNORM(v->a, col[0][3]); + } else { + v->a = 255.0f; + } +#endif /* !FX_PACKEDCOLOR */ + STRIDE_4F(col, col_stride); + } + if (IND & SETUP_SPEC) { +#if FX_PACKEDCOLOR + UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[2], spec[0][0]); + UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[1], spec[0][1]); + UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[0], spec[0][2]); +#else /* !FX_PACKEDCOLOR */ + CNORM(v->r1, spec[0][0]); + CNORM(v->g1, spec[0][1]); + CNORM(v->b1, spec[0][2]); +#endif /* !FX_PACKEDCOLOR */ + STRIDE_4F(spec, spec_stride); + } + if (IND & SETUP_FOGC) { + v->fog = CLAMP(fog[0][0], 0.0f, 1.0f); + fog = (GLfloat (*)[4])((GLubyte *)fog + fog_stride); + } + if (IND & SETUP_TMU0) { + GLfloat w = v->oow; + v->tmuvtx[0].sow = tc0[0][0] * u0scale * w; + v->tmuvtx[0].tow = tc0[0][1] * v0scale * w; + if (IND & SETUP_PTEX) { + v->tmuvtx[0].oow = w; + if (tc0_size == 4) + v->tmuvtx[0].oow *= tc0[0][3]; + } + tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride); + } + if (IND & SETUP_TMU1) { + GLfloat w = v->oow; + v->tmuvtx[1].sow = tc1[0][0] * u1scale * w; + v->tmuvtx[1].tow = tc1[0][1] * v1scale * w; + if (IND & SETUP_PTEX) { + v->tmuvtx[1].oow = w; + if (tc1_size == 4) + v->tmuvtx[1].oow *= tc1[0][3]; + } + tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride); + } + } +} + +#if (IND & SETUP_XYZW) && (IND & SETUP_RGBA) + +static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) +{ +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + if (IND & SETUP_PTEX) + return GL_TRUE; + + if (IND & SETUP_TMU0) { + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (IND & SETUP_TMU1) { + if (VB->TexCoordPtr[0] == 0) + VB->TexCoordPtr[0] = VB->TexCoordPtr[1]; + + if (VB->TexCoordPtr[1]->size == 4) + return GL_FALSE; + } + + if (VB->TexCoordPtr[0] && VB->TexCoordPtr[0]->size == 4) + return GL_FALSE; + } + + return GL_TRUE; +} + +static void TAG(interp)( GLcontext *ctx, + GLfloat t, + GLuint edst, GLuint eout, GLuint ein, + GLboolean force_boundary ) +{ + fxMesaContext fxMesa = FX_CONTEXT( ctx ); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + const GLfloat *dstclip = VB->ClipPtr->data[edst]; + const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]); + const GLfloat *const s = ctx->Viewport._WindowMap.m; + GrVertex *fxverts = fxMesa->verts; + GrVertex *dst = (GrVertex *) (fxverts + edst); + const GrVertex *out = (const GrVertex *) (fxverts + eout); + const GrVertex *in = (const GrVertex *) (fxverts + ein); + const GLfloat wout = oow / out->oow; + const GLfloat win = oow / in->oow; + + VIEWPORT_X(dst->x, dstclip[0] * oow); + VIEWPORT_Y(dst->y, dstclip[1] * oow); + VIEWPORT_Z(dst->ooz, dstclip[2] * oow); + dst->oow = oow; + + if (IND & SETUP_SNAP) { +#if defined(USE_IEEE) + const float snapper = (3L << 18); + dst->x += snapper; + dst->x -= snapper; + dst->y += snapper; + dst->y -= snapper; +#else + dst->x = ((int) (dst->x * 16.0f)) * (1.0f / 16.0f); + dst->y = ((int) (dst->y * 16.0f)) * (1.0f / 16.0f); +#endif + } + + +#if FX_PACKEDCOLOR + INTERP_UB( t, dst->pargb[0], out->pargb[0], in->pargb[0] ); + INTERP_UB( t, dst->pargb[1], out->pargb[1], in->pargb[1] ); + INTERP_UB( t, dst->pargb[2], out->pargb[2], in->pargb[2] ); + INTERP_UB( t, dst->pargb[3], out->pargb[3], in->pargb[3] ); +#else /* !FX_PACKEDCOLOR */ + INTERP_F( t, dst->r, out->r, in->r ); + INTERP_F( t, dst->g, out->g, in->g ); + INTERP_F( t, dst->b, out->b, in->b ); + INTERP_F( t, dst->a, out->a, in->a ); +#endif /* !FX_PACKEDCOLOR */ + + if (IND & SETUP_SPEC) { +#if FX_PACKEDCOLOR + INTERP_UB( t, dst->pspec[0], out->pspec[0], in->pspec[0] ); + INTERP_UB( t, dst->pspec[1], out->pspec[1], in->pspec[1] ); + INTERP_UB( t, dst->pspec[2], out->pspec[2], in->pspec[2] ); +#else /* !FX_PACKEDCOLOR */ + INTERP_F( t, dst->r1, out->r1, in->r1 ); + INTERP_F( t, dst->g1, out->g1, in->g1 ); + INTERP_F( t, dst->b1, out->b1, in->b1 ); +#endif /* !FX_PACKEDCOLOR */ + } + + if (IND & SETUP_FOGC) { + INTERP_F( t, dst->fog, out->fog, in->fog ); + } + + if (IND & SETUP_TMU0) { + INTERP_F( t, + dst->tmuvtx[0].sow, + out->tmuvtx[0].sow * wout, + in->tmuvtx[0].sow * win ); + INTERP_F( t, + dst->tmuvtx[0].tow, + out->tmuvtx[0].tow * wout, + in->tmuvtx[0].tow * win ); + if (IND & SETUP_PTEX) { + INTERP_F( t, + dst->tmuvtx[0].oow, + out->tmuvtx[0].oow * wout, + in->tmuvtx[0].oow * win ); + } + } + + if (IND & SETUP_TMU1) { + INTERP_F( t, + dst->tmuvtx[1].sow, + out->tmuvtx[1].sow * wout, + in->tmuvtx[1].sow * win ); + INTERP_F( t, + dst->tmuvtx[1].tow, + out->tmuvtx[1].tow * wout, + in->tmuvtx[1].tow * win ); + if (IND & SETUP_PTEX) { + INTERP_F( t, + dst->tmuvtx[1].oow, + out->tmuvtx[1].oow * wout, + in->tmuvtx[1].oow * win ); + } + } +} +#endif + + +static void TAG(init)( void ) +{ + setup_tab[IND].emit = TAG(emit); + + if (IND & SETUP_SPEC) { + setup_tab[IND].copy_pv = copy_pv2; + } else { + setup_tab[IND].copy_pv = copy_pv; + } + +#if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA)) + setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes); + setup_tab[IND].interp = TAG(interp); + + setup_tab[IND].vertex_format = 0; + if (IND & SETUP_PTEX) { + setup_tab[IND].vertex_format |= GR_STWHINT_W_DIFF_TMU0; + } + +#if (IND & SETUP_TMU1) + setup_tab[IND].vertex_format |= GR_STWHINT_ST_DIFF_TMU1; + if (IND & SETUP_PTEX) { + setup_tab[IND].vertex_format |= GR_STWHINT_W_DIFF_TMU1; + } +#endif + +#endif +} + + +#undef IND +#undef TAG |