aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/Mesa/src/mesa/drivers/glide
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/glide')
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxapi.c951
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdd.c2197
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddspan.c663
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxddtex.c1849
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxdrv.h771
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.c2309
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxg.h382
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.c269
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxglidew.h228
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.c2217
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxsetup.h850
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtexman.c874
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxtris.c1834
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvb.c838
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/glide/fxvbtmp.h369
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