diff options
Diffstat (limited to 'src/mesa/drivers/glide')
-rw-r--r-- | src/mesa/drivers/glide/fx.rc | 39 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxapi.c | 306 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxdd.c | 705 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxddspan.c | 1039 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxddtex.c | 708 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxdrv.h | 146 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxg.c | 164 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxg.h | 35 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxglidew.c | 22 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxglidew.h | 14 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxopengl.def | 2 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxsetup.c | 987 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxsetup.h | 1131 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxtexman.c | 85 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxtris.c | 45 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxvb.c | 8 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxvbtmp.h | 38 | ||||
-rw-r--r-- | src/mesa/drivers/glide/fxwgl.c | 64 |
18 files changed, 3912 insertions, 1626 deletions
diff --git a/src/mesa/drivers/glide/fx.rc b/src/mesa/drivers/glide/fx.rc new file mode 100644 index 00000000000..5d00629b826 --- /dev/null +++ b/src/mesa/drivers/glide/fx.rc @@ -0,0 +1,39 @@ +#include <windows.h> + +#define PRODNAME "Mesa 5.1" +#define CONTACTSTR "http://www.mesa3d.org" +#define HWSTR "3dfx Voodoo^2, Voodoo Banshee, Velocity 100/200, Voodoo3, Voodoo4, Voodoo5" +#define COPYRIGHTSTR "Copyright \251 Brian E. Paul" + +#define VERSIONSTR "5.1.0.1" +#define MANVERSION 5 +#define MANREVISION 1 +#define BUILD_NUMBER 1 + +VS_VERSION_INFO VERSIONINFO + FILEVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER + PRODUCTVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER + FILEFLAGSMASK 0x0030003FL + + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DRV + FILESUBTYPE VFT2_DRV_INSTALLABLE +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "FileDescription", PRODNAME + VALUE "FileVersion", VERSIONSTR + VALUE "LegalCopyright", COPYRIGHTSTR + VALUE "ProductName", PRODNAME + VALUE "Graphics Subsystem", HWSTR + VALUE "Contact", CONTACTSTR + END + END + BLOCK "VarFileInfo" + BEGIN + /* the following line should be extended for localized versions */ + VALUE "Translation", 0x409, 1252 + END +END diff --git a/src/mesa/drivers/glide/fxapi.c b/src/mesa/drivers/glide/fxapi.c index 89b4a38a620..57d5034557f 100644 --- a/src/mesa/drivers/glide/fxapi.c +++ b/src/mesa/drivers/glide/fxapi.c @@ -1,5 +1,3 @@ -/* $Id: fxapi.c,v 1.38 2003/10/02 17:36:44 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -216,7 +214,7 @@ fxMesaCreateBestContext(GLuint win, GLint width, GLint height, return NULL; } - return fxMesaCreateContext(win, res, GR_REFRESH_60Hz/*ZZZ: GR_REFRESH_75Hz*/, attribList); + return fxMesaCreateContext(win, res, GR_REFRESH_60Hz, attribList); } @@ -233,7 +231,7 @@ fxMesaCreateContext(GLuint win, int i; const char *str; - int numChips, sliaa, fsaa; + int sliaa, numSLI, samplesPerChip, tmuRam, fbRam; struct SstCard_St *voodoo; struct tdfx_glide *Glide; @@ -245,16 +243,11 @@ fxMesaCreateContext(GLuint win, GrPixelFormat_t pixFmt; GLboolean useBGR; - GLboolean verbose = GL_FALSE; if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "%s(...)\n", __FUNCTION__); } - if (getenv("MESA_FX_INFO")) { - verbose = GL_TRUE; - } - /* Okay, first process the user flags */ aux = GL_FALSE; doubleBuffer = GL_FALSE; @@ -313,7 +306,6 @@ fxMesaCreateContext(GLuint win, and disables the splash screen due to y-origin swapping. Note: We only want the former. */ voodoo = &glbHWConfig.SSTs[glbCurrentBoard]; - numChips = voodoo->numChips; fxMesa = (fxMesaContext)CALLOC_STRUCT(tfxMesaContext); if (!fxMesa) { @@ -321,49 +313,166 @@ fxMesaCreateContext(GLuint win, goto errorhandler; } + if (getenv("MESA_FX_INFO")) { + fxMesa->verbose = GL_TRUE; + } + fxMesa->type = voodoo->type; + fxMesa->HavePalExt = voodoo->HavePalExt; fxMesa->HavePixExt = voodoo->HavePixExt; fxMesa->HaveTexFmt = voodoo->HaveTexFmt; fxMesa->HaveCmbExt = voodoo->HaveCmbExt; fxMesa->HaveMirExt = voodoo->HaveMirExt; + fxMesa->HaveTexUma = voodoo->HaveTexUma; fxMesa->HaveTexus2 = voodoo->HaveTexus2; fxMesa->Glide = glbHWConfig.Glide; Glide = &fxMesa->Glide; - sprintf(fxMesa->rendererString, "Mesa %s v0.51 %s %dMB FB, %dMB TM, %d TMU, %s", - grGetString(GR_RENDERER), - grGetString(GR_HARDWARE), - voodoo->fbRam, - (voodoo->tmuConfig[GR_TMU0].tmuRam + ((voodoo->nTexelfx > 1) ? voodoo->tmuConfig[GR_TMU1].tmuRam : 0)), - voodoo->nTexelfx, - (numChips > 1) ? "SLI" : "NOSLI"); - switch (fxMesa->colDepth = colDepth) { - case 15: - redBits = 5; - greenBits = 5; - blueBits = 5; - alphaBits = 1; - pixFmt = GR_PIXFMT_ARGB_1555; - break; - case 16: - redBits = 5; - greenBits = 6; - blueBits = 5; - alphaBits = depthSize ? 0 : 8; - pixFmt = GR_PIXFMT_RGB_565; + /* + * Pixel tables are used during pixel read-back + * Either initialize them for RGB or BGR order; + * However, 32bit capable cards have the right order. + * As a consequence, 32bit read-back is not swizzled! + * Also determine if we need vertex snapping. + */ + /* number of SLI units and AA Samples per chip */ + sliaa = 0; + switch (voodoo->type) { + case GR_SSTTYPE_VOODOO: + case GR_SSTTYPE_Banshee: + useBGR = GL_TRUE; + fxMesa->snapVertices = GL_TRUE; break; - case 32: - redBits = 8; - greenBits = 8; - blueBits = 8; - alphaBits = 8; - pixFmt = GR_PIXFMT_ARGB_8888; + case GR_SSTTYPE_Voodoo2: + useBGR = GL_TRUE; + fxMesa->snapVertices = GL_FALSE; break; + case GR_SSTTYPE_Voodoo4: + case GR_SSTTYPE_Voodoo5: + if ((str = Glide->grGetRegistryOrEnvironmentStringExt("SSTH3_SLI_AA_CONFIGURATION")) != NULL) { + sliaa = atoi(str); + } + case GR_SSTTYPE_Voodoo3: default: - str = "pixelFormat"; - goto errorhandler; + useBGR = GL_FALSE; + fxMesa->snapVertices = GL_FALSE; + break; + } + /* ZZZ TO DO: 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 = 1; + 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 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; } + /* ZZZ TODO: check if there is enough fbRam */ + /* 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 @@ -391,7 +500,6 @@ fxMesaCreateContext(GLuint win, fxMesa->haveZBuffer = depthSize > 0; fxMesa->haveDoubleBuffer = doubleBuffer; fxMesa->haveGlobalPaletteTexture = GL_FALSE; - fxMesa->verbose = verbose; fxMesa->board = glbCurrentBoard; fxMesa->haveTwoTMUs = (voodoo->nTexelfx > 1); @@ -419,60 +527,6 @@ fxMesaCreateContext(GLuint win, fxMesa->swapInterval = 0; } - if ((str = Glide->grGetRegistryOrEnvironmentStringExt("SSTH3_SLI_AA_CONFIGURATION"))) { - sliaa = atoi(str); - } else { - sliaa = 0; - } - switch (colDepth) { - case 15: - if ((numChips == 4) && (sliaa == 8)) { - pixFmt = GR_PIXFMT_AA_8_ARGB_1555; - fsaa = 8; - } else if (((numChips == 4) && (sliaa == 7)) || ((numChips == 2) && (sliaa == 4))) { - pixFmt = GR_PIXFMT_AA_4_ARGB_1555; - fsaa = 4; - } else if (((numChips == 4) && (sliaa == 6)) || ((numChips == 2) && (sliaa == 3)) || ((numChips == 1) && (sliaa == 1))) { - pixFmt = GR_PIXFMT_AA_2_ARGB_1555; - fsaa = 2; - } else { - fsaa = 0; - } - break; - case 16: - if ((numChips == 4) && (sliaa == 8)) { - pixFmt = GR_PIXFMT_AA_8_RGB_565; - fsaa = 8; - } else if (((numChips == 4) && (sliaa == 7)) || ((numChips == 2) && (sliaa == 4))) { - pixFmt = GR_PIXFMT_AA_4_RGB_565; - fsaa = 4; - } else if (((numChips == 4) && (sliaa == 6)) || ((numChips == 2) && (sliaa == 3)) || ((numChips == 1) && (sliaa == 1))) { - pixFmt = GR_PIXFMT_AA_2_RGB_565; - fsaa = 2; - } else { - fsaa = 0; - } - break; - case 32: - if ((numChips == 4) && (sliaa == 8)) { - pixFmt = GR_PIXFMT_AA_8_ARGB_8888; - fsaa = 8; - } else if (((numChips == 4) && (sliaa == 7)) || ((numChips == 2) && (sliaa == 4))) { - pixFmt = GR_PIXFMT_AA_4_ARGB_8888; - fsaa = 4; - } else if (((numChips == 4) && (sliaa == 6)) || ((numChips == 2) && (sliaa == 3)) || ((numChips == 1) && (sliaa == 1))) { - pixFmt = GR_PIXFMT_AA_2_ARGB_8888; - fsaa = 2; - } else { - fsaa = 0; - } - break; - default: /* NOTREACHED */ - str = "pixelFormat"; - goto errorhandler; - } - fxMesa->fsaa = fsaa; - BEGIN_BOARD_LOCK(); if (fxMesa->HavePixExt) { fxMesa->glideContext = Glide->grSstWinOpenExt((FxU32)win, res, ref, @@ -492,46 +546,44 @@ fxMesaCreateContext(GLuint win, goto errorhandler; } - /* - * Pixel tables are used during pixel read-back - * Either initialize them for RGB or BGR order; - * However, 32bit capable cards have the right order. - * As a consequence, 32bit read-back is not swizzled! - * Also determine if we need vertex snapping. - */ - switch (voodoo->type) { - case GR_SSTTYPE_VOODOO: - case GR_SSTTYPE_Banshee: - useBGR = GL_TRUE; - fxMesa->snapVertices = GL_TRUE; - break; - case GR_SSTTYPE_Voodoo2: - useBGR = GL_TRUE; - fxMesa->snapVertices = GL_FALSE; - break; - case GR_SSTTYPE_Voodoo3: - case GR_SSTTYPE_Voodoo4: - case GR_SSTTYPE_Voodoo5: - default: - useBGR = GL_FALSE; - fxMesa->snapVertices = GL_FALSE; - break; - } + /* Not that it matters, but tmuRam and fbRam change after grSstWinOpen. */ + tmuRam = voodoo->tmuConfig[GR_TMU0].tmuRam; + fbRam = voodoo->fbRam; + BEGIN_BOARD_LOCK(); + { + FxI32 result; + grGet(GR_MEMORY_TMU, 4, &result); + tmuRam = result / (1024 * 1024); + grGet(GR_MEMORY_FB, 4, &result); + fbRam = result / (1024 * 1024); + } + END_BOARD_LOCK(); + + sprintf(fxMesa->rendererString, "Mesa %s v0.51 %s %dMB FB, %dMB TM, %d TMU, %s", + grGetString(GR_RENDERER), + grGetString(GR_HARDWARE), + fbRam, + tmuRam * voodoo->nTexelfx, + voodoo->nTexelfx, + (voodoo->numChips > 1) ? "SLI" : "NOSLI"); - fxInitPixelTables(fxMesa, useBGR); + fxMesa->bgrOrder = useBGR; - fxMesa->width = FX_grSstScreenWidth(); - fxMesa->height = FX_grSstScreenHeight(); + /* 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; - fxMesa->screen_width = fxMesa->width; - fxMesa->screen_height = fxMesa->height; - - if (verbose) { + if (fxMesa->verbose) { char buf[80]; strcpy(buf, grGetString(GR_VERSION)); @@ -544,7 +596,7 @@ fxMesaCreateContext(GLuint win, fprintf(stderr, "Voodoo pixel order = %s, vertex snapping = %d\n", useBGR ? "BGR" : "RGB", fxMesa->snapVertices); - fprintf(stderr, "Voodoo screen: %dx%d.%d\n", + fprintf(stderr, "Voodoo screen: %dx%d:%d\n", fxMesa->screen_width, fxMesa->screen_height, colDepth); } diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index 386fa5b120c..557c0038647 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -1,9 +1,3 @@ -/* Hack alert: - * fxDDReadPixels888 does not convert 8A8R8G8B into 5R5G5B - */ - -/* $Id: fxdd.c,v 1.100.2.1 2003/11/21 13:40:21 keithw Exp $ */ - /* * Mesa 3-D graphics library * Version: 5.1 @@ -55,6 +49,7 @@ #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" @@ -63,13 +58,6 @@ -/* These lookup table are used to extract RGB values in [0,255] from - * 16-bit pixel values. - */ -GLubyte FX_PixelToR[0x10000]; -GLubyte FX_PixelToG[0x10000]; -GLubyte FX_PixelToB[0x10000]; - /* 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, @@ -98,35 +86,17 @@ GLuint FX_rgb_scale_6[64] = { /* - * Initialize the FX_PixelTo{RGB} arrays. - * Input: bgrOrder - if TRUE, pixels are in BGR order, else RGB order. + * Disable color by masking out R, G, B, A */ -void -fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder) +static void fxDisableColor (fxMesaContext fxMesa) { - GLuint pixel; - - fxMesa->bgrOrder = bgrOrder; - for (pixel = 0; pixel <= 0xffff; pixel++) { - GLuint r, g, b; - if (bgrOrder) { - r = (pixel & 0x001F) << 3; - g = (pixel & 0x07E0) >> 3; - b = (pixel & 0xF800) >> 8; - } - else { - r = (pixel & 0xF800) >> 8; - g = (pixel & 0x07E0) >> 3; - b = (pixel & 0x001F) << 3; - } - /* fill in low-order bits with proper rounding */ - r = (GLuint)(((double)r * 255. / 0xF8) + 0.5); - g = (GLuint)(((double)g * 255. / 0xFC) + 0.5); - b = (GLuint)(((double)b * 255. / 0xF8) + 0.5); - FX_PixelToR[pixel] = r; - FX_PixelToG[pixel] = g; - FX_PixelToB[pixel] = b; - } + if (fxMesa->colDepth != 16) { + /* 32bpp mode or 15bpp mode */ + fxMesa->Glide.grColorMaskExt(FXFALSE, FXFALSE, FXFALSE, FXFALSE); + } else { + /* 16 bpp mode */ + grColorMask(FXFALSE, FXFALSE); + } } @@ -185,30 +155,42 @@ static void fxDDClear( GLcontext *ctx, const FxU32 clearD = (FxU32) (((1 << ctx->Visual.depthBits) - 1) * ctx->Depth.Clear); const FxU8 clearS = (FxU8) (ctx->Stencil.Clear & 0xff); + /* [dBorca] Hack alert: + * if we set Mesa for 32bit depth, we'll get + * clearD == 0 + * due to 32bit integer overflow! + */ + if ( TDFX_DEBUG & MESA_VERBOSE ) { fprintf( stderr, "%s( %d, %d, %d, %d )\n", __FUNCTION__, (int) x, (int) y, (int) width, (int) height ); } -/*jejeje*/ /* Need this check to respond to glScissor and clipping updates */ + /* should also take care of FX_NEW_COLOR_MASK, FX_NEW_STENCIL, depth? */ if (fxMesa->new_state & FX_NEW_SCISSOR) { - extern void fxSetupScissor(GLcontext * ctx); fxSetupScissor(ctx); + fxMesa->new_state &= ~FX_NEW_SCISSOR; } /* we can't clear accum buffers */ mask &= ~(DD_ACCUM_BIT); + /* + * As per GL spec, stencil masking should be obeyed when clearing + */ if (mask & DD_STENCIL_BIT) { if (!fxMesa->haveHwStencil || fxMesa->unitsState.stencilWriteMask != 0xff) { /* Napalm seems to have trouble with stencil write masks != 0xff */ /* do stencil clear in software */ - mask &= ~(DD_STENCIL_BIT); softwareMask |= DD_STENCIL_BIT; + mask &= ~(DD_STENCIL_BIT); } } + /* + * As per GL spec, color masking should be obeyed when clearing + */ if (ctx->Visual.greenBits != 8 && ctx->Visual.greenBits != 5) { /* can only do color masking if running in 24/32bpp on Napalm */ if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] || @@ -252,7 +234,7 @@ static void fxDDClear( GLcontext *ctx, switch (mask & ~DD_STENCIL_BIT) { case DD_BACK_LEFT_BIT | DD_DEPTH_BIT: /* back buffer & depth */ - fxColorMask(fxMesa, GL_TRUE); /* work around Voodoo3 bug */ + /* FX_grColorMaskv_NoLock(ctx, true4); */ /* work around Voodoo3 bug */ grDepthMask(FXTRUE); grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) { @@ -264,7 +246,7 @@ static void fxDDClear( GLcontext *ctx, grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - if (!ctx->Depth.Mask || !ctx->Depth.Test) { + if (!fxMesa->unitsState.depthTestEnabled) { grDepthMask(FXFALSE); } break; @@ -276,7 +258,7 @@ static void fxDDClear( GLcontext *ctx, /* clear depth */ grDepthMask(FXTRUE); grRenderBuffer(GR_BUFFER_BACKBUFFER); - fxColorMask(fxMesa, GL_FALSE); + fxDisableColor(fxMesa); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, @@ -286,7 +268,7 @@ static void fxDDClear( GLcontext *ctx, fxMesa->clearA, clearD); /* clear front */ - fxColorMask(fxMesa, GL_TRUE); + fxSetupColorMask(ctx); grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, @@ -296,7 +278,7 @@ static void fxDDClear( GLcontext *ctx, grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - if (!ctx->Depth.Mask || !ctx->Depth.Test) { + if (!fxMesa->unitsState.depthTestEnabled) { grDepthMask(FXFALSE); } break; @@ -312,7 +294,7 @@ static void fxDDClear( GLcontext *ctx, grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - if (ctx->Depth.Mask && ctx->Depth.Test) { + if (fxMesa->unitsState.depthTestEnabled) { grDepthMask(FXTRUE); } break; @@ -328,7 +310,7 @@ static void fxDDClear( GLcontext *ctx, grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - if (ctx->Depth.Mask && ctx->Depth.Test) { + if (fxMesa->unitsState.depthTestEnabled) { grDepthMask(FXTRUE); } break; @@ -353,7 +335,7 @@ static void fxDDClear( GLcontext *ctx, grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - if (ctx->Depth.Mask && ctx->Depth.Test) { + if (fxMesa->unitsState.depthTestEnabled) { grDepthMask(FXTRUE); } break; @@ -380,14 +362,14 @@ static void fxDDClear( GLcontext *ctx, grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - if (!ctx->Depth.Mask || !ctx->Depth.Mask) { + if (!fxMesa->unitsState.depthTestEnabled) { grDepthMask(FXFALSE); } break; case DD_DEPTH_BIT: /* just the depth buffer */ grRenderBuffer(GR_BUFFER_BACKBUFFER); - fxColorMask(fxMesa, GL_FALSE); + fxDisableColor(fxMesa); grDepthMask(FXTRUE); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, @@ -397,11 +379,13 @@ static void fxDDClear( GLcontext *ctx, grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - fxColorMask(fxMesa, GL_TRUE); - if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT) + fxSetupColorMask(ctx); + if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT) { grRenderBuffer(GR_BUFFER_FRONTBUFFER); - if (!ctx->Depth.Test || !ctx->Depth.Mask) + } + if (!fxMesa->unitsState.depthTestEnabled) { grDepthMask(FXFALSE); + } break; default: /* clear no color buffers or depth buffer but might clear stencil */ @@ -409,16 +393,17 @@ static void fxDDClear( GLcontext *ctx, /* XXX need this RenderBuffer call to work around Glide bug */ grRenderBuffer(GR_BUFFER_BACKBUFFER); grDepthMask(FXFALSE); - fxColorMask(fxMesa, GL_FALSE); + fxDisableColor(fxMesa); fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); - if (ctx->Depth.Mask && ctx->Depth.Test) { + if (fxMesa->unitsState.depthTestEnabled) { grDepthMask(FXTRUE); } - fxColorMask(fxMesa, GL_TRUE); - if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT) + fxSetupColorMask(ctx); + if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT) { grRenderBuffer(GR_BUFFER_FRONTBUFFER); + } } } } @@ -456,7 +441,7 @@ fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode) grRenderBuffer(fxMesa->currentFB); } else if (mode == GL_NONE) { - fxColorMask(fxMesa, GL_FALSE); + fxDisableColor(fxMesa); } else { /* we'll need a software fallback */ @@ -468,44 +453,48 @@ fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode) } - - - static void -fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte * bitmap) +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 (ctx->Color.AlphaEnabled || - ctx->Color.BlendEnabled || - ctx->Depth.Test || - ctx->Fog.Enabled || - ctx->Color.ColorLogicOpEnabled || - ctx->Stencil.Enabled || - ctx->Scissor.Enabled || - (ctx->DrawBuffer->UseSoftwareAlphaBuffers && - ctx->Color.ColorMask[ACOMP]) || - (ctx->Color._DrawDestMask != FRONT_LEFT_BIT && - ctx->Color._DrawDestMask != BACK_LEFT_BIT)) { + 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, test follows */ + ALPHABUF_BIT | /* nope! see 565 span kludge */ + MULTI_DRAW_BIT | + OCCLUSION_BIT | /* nope! at least not yet */ + TEXTURE_BIT | + FRAGPROG_BIT)) + || + ((swrast->_RasterMask & MASKING_BIT) /*&& (ctx->Visual.greenBits != 8)*/ && (ctx->Visual.greenBits != 5)) + ) { _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap); return; } + /* make sure the pixelpipe is configured correctly */ + fxSetupFXUnits(ctx); 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. - * - * KW: This code is never reached, see the test above. */ /* we'll construct a new pixelstore struct */ @@ -544,26 +533,25 @@ fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py, /* compute pixel value */ { - GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0f); - GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0f); - GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0f); - /*GLint a = (GLint)(ctx->Current.RasterColor[3]*255.0f); */ - if (fxMesa->bgrOrder) - color = (FxU16) - (((FxU16) 0xf8 & b) << (11 - 3)) | - (((FxU16) 0xfc & g) << (5 - 3 + 1)) | (((FxU16) 0xf8 & r) >> 3); - else - color = (FxU16) - (((FxU16) 0xf8 & r) << (11 - 3)) | - (((FxU16) 0xfc & g) << (5 - 3 + 1)) | (((FxU16) 0xf8 & b) >> 3); + 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, - GR_LFBWRITEMODE_565, - GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { - fprintf(stderr, "%s: ERROR: locking the linear frame buffer\n", __FUNCTION__); + mode, + GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) { + _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap); return; } @@ -632,14 +620,174 @@ fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py, 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 */ + /*ALPHABUF_BIT |*//* alpha 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); + + 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_UPPER_LEFT, FXTRUE, &info)) { + _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap); + return; + } + + { + const GLint winX = 0; + const GLint winY = fxMesa->height - 1; + /* 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_address(finalUnpack, + bitmap, width, height, + GL_COLOR_INDEX, GL_BITMAP, + 0, 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 -fxDDReadPixels(GLcontext * ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *packing, GLvoid * dstImage) +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) { + if (ctx->_ImageTransferState/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) { _swrast_ReadPixels(ctx, x, y, width, height, format, type, packing, dstImage); return; @@ -673,20 +821,18 @@ fxDDReadPixels(GLcontext * ctx, GLint x, GLint y, GLubyte *d = dst; for (col = 0; col < halfWidth; col++) { const GLuint pixel = ((const GLuint *) src)[col]; - const GLint pixel0 = pixel & 0xffff; - const GLint pixel1 = pixel >> 16; - *d++ = FX_PixelToR[pixel0]; - *d++ = FX_PixelToG[pixel0]; - *d++ = FX_PixelToB[pixel0]; - *d++ = FX_PixelToR[pixel1]; - *d++ = FX_PixelToG[pixel1]; - *d++ = FX_PixelToB[pixel1]; + *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_PixelToR[pixel]; - *d++ = FX_PixelToG[pixel]; - *d++ = FX_PixelToB[pixel]; + *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; @@ -701,22 +847,20 @@ fxDDReadPixels(GLcontext * ctx, GLint x, GLint y, GLubyte *d = dst; for (col = 0; col < halfWidth; col++) { const GLuint pixel = ((const GLuint *) src)[col]; - const GLint pixel0 = pixel & 0xffff; - const GLint pixel1 = pixel >> 16; - *d++ = FX_PixelToR[pixel0]; - *d++ = FX_PixelToG[pixel0]; - *d++ = FX_PixelToB[pixel0]; + *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_PixelToR[pixel1]; - *d++ = FX_PixelToG[pixel1]; - *d++ = FX_PixelToB[pixel1]; + *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_PixelToR[pixel]; - *d++ = FX_PixelToG[pixel]; - *d++ = FX_PixelToB[pixel]; + *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; @@ -747,14 +891,15 @@ fxDDReadPixels(GLcontext * ctx, GLint x, GLint y, } } -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) +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) { + if (ctx->_ImageTransferState/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) { _swrast_ReadPixels(ctx, x, y, width, height, format, type, packing, dstImage); return; @@ -788,18 +933,18 @@ static void fxDDReadPixels555 (GLcontext * ctx, GLubyte *d = dst; for (col = 0; col < halfWidth; col++) { const GLuint pixel = ((const GLuint *) src)[col]; - *d++ = FX_rgb_scale_5[ pixel & 0x1f]; - *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; *d++ = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; - *d++ = FX_rgb_scale_5[(pixel >> 16) & 0x1f]; - *d++ = FX_rgb_scale_5[(pixel >> 21) & 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 & 0x1f]; - *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; *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; @@ -814,20 +959,20 @@ static void fxDDReadPixels555 (GLcontext * ctx, GLubyte *d = dst; for (col = 0; col < halfWidth; col++) { const GLuint pixel = ((const GLuint *) src)[col]; - *d++ = FX_rgb_scale_5[ pixel & 0x1f]; - *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; *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 >> 16) & 0x1f]; - *d++ = FX_rgb_scale_5[(pixel >> 21) & 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]; *d++ = (pixel & 0x80000000) ? 255 : 0; } if (extraPixel) { const GLushort pixel = src[width - 1]; - *d++ = FX_rgb_scale_5[ pixel & 0x1f]; - *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; *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; @@ -858,14 +1003,15 @@ static void fxDDReadPixels555 (GLcontext * ctx, } } -static void fxDDReadPixels888 (GLcontext * ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *packing, - GLvoid *dstImage) +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) { + if (ctx->_ImageTransferState/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) { _swrast_ReadPixels(ctx, x, y, width, height, format, type, packing, dstImage); return; @@ -906,17 +1052,35 @@ static void fxDDReadPixels888 (GLcontext * ctx, } } else if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { - /* directly memcpy 8A8R8G8B pixels into client's buffer */ - const GLint widthInBytes = width * 4; - GLint row; + /* 8A8R8G8B pixels into client's buffer */ + GLint row, col; for (row = 0; row < height; row++) { - MEMCPY(dst, src, widthInBytes); + 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 5R5G5B */ + /* 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); @@ -933,6 +1097,105 @@ static void fxDDReadPixels888 (GLcontext * ctx, } +/* [dBorca] Hack alert: + * not finished!!! + * revise fallback tests and fix scissor; implement new formats + * also write its siblings: 565 and 1555 + */ +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); + GrLfbInfo_t info; + + if (ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F || + (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT| + IMAGE_MAP_COLOR_BIT)) || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Scissor.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || + ctx->Color.ColorLogicOpEnabled || + ctx->Texture._EnabledUnits || + ctx->Depth.OcclusionTest || + fxMesa->fallback) + { + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + return; + } + + /* lock early to make sure cliprects are right */ + BEGIN_BOARD_LOCK(); + + /* make sure the pixelpipe is configured correctly */ + fxSetupFXUnits(ctx); + + /* look for clipmasks, giveup if region obscured */ +#if 0 + if (ctx->Color.DrawBuffer == GL_FRONT) { + if (!inClipRects_Region(fxMesa, scrX, scrY, width, height)) { + END_BOARD_LOCK(fxMesa); + _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels); + return; + } + } +#endif + + info.size = sizeof(info); + if (!grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_8888, + GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) { + _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels); + return; + } + + { + const GLint winX = 0; + const GLint winY = fxMesa->height - 1; + + const GLint dstStride = info.strideInBytes / 4; /* stride in GLuints */ + GLuint *dst = (GLuint *) info.lfbPtr + (winY - y) * dstStride + (winX + x); + const GLubyte *src = (GLubyte *)_mesa_image_address(unpack, pixels, + width, height, format, + type, 0, 0, 0); + const GLint srcStride = _mesa_image_row_stride(unpack, width, format, type); + + 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++) { + MEMCPY(dst, src, widthInBytes); + dst -= dstStride; + src += srcStride; + } + } + else { + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + END_BOARD_LOCK(); + _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels); + return; + } + + } + + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + END_BOARD_LOCK(); +} + + static void fxDDFinish(GLcontext * ctx) { @@ -955,6 +1218,25 @@ fxDDGetString(GLcontext * ctx, GLenum name) switch (name) { case GL_RENDERER: return (GLubyte *)fxMesa->rendererString; +#if 0 /* 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); +#if 0 /* put any additional extension names here */ + strcat((char *)ctx->Extensions.String, " 3DFX_set_global_palette"); +#endif + _mesa_free(ext); + } else { + ctx->Extensions.String = ext; + } + } + } + return ctx->Extensions.String; +#endif default: return NULL; } @@ -1007,6 +1289,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) fxMesa->unitsState.blendDstFuncRGB = GR_BLEND_ZERO; fxMesa->unitsState.blendSrcFuncAlpha = GR_BLEND_ONE; fxMesa->unitsState.blendDstFuncAlpha = GR_BLEND_ZERO; + fxMesa->unitsState.blendEq = GR_BLEND_OP_ADD; fxMesa->unitsState.depthTestEnabled = GL_FALSE; fxMesa->unitsState.depthMask = GL_TRUE; @@ -1015,16 +1298,17 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) fxMesa->unitsState.stencilWriteMask = 0xff; - fxColorMask(fxMesa, GL_TRUE); - if (fxMesa->haveDoubleBuffer) { - fxMesa->currentFB = GR_BUFFER_BACKBUFFER; - grRenderBuffer(GR_BUFFER_BACKBUFFER); - } - else { - fxMesa->currentFB = GR_BUFFER_FRONTBUFFER; - grRenderBuffer(GR_BUFFER_FRONTBUFFER); + if (fxMesa->colDepth != 16) { + /* 32bpp mode or 15bpp mode */ + fxMesa->Glide.grColorMaskExt(FXTRUE, FXTRUE, FXTRUE, fxMesa->haveHwAlpha); + } else { + /* 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)); @@ -1040,7 +1324,9 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) if (fxMesa->haveZBuffer) grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER); - grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); + if (!fxMesa->bgrOrder) { + grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); + } fxMesa->textureAlign = FX_grGetInteger(GR_TEXTURE_ALIGN); /* [koolsmoky] */ @@ -1090,6 +1376,13 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) fxDDInitExtensions(ctx); +#if 0 + /* [dBorca] Hack alert: + * do we want dither? It just looks bad... + */ + grEnable(GR_ALLOW_MIPMAP_DITHER); + grTexNccTable(GR_NCCTABLE_NCC0); /* set this once... no multipass */ +#endif grGlideGetState((GrState *) fxMesa->state); return 1; @@ -1121,11 +1414,11 @@ fxDDInitExtensions(GLcontext * ctx) { fxMesaContext fxMesa = FX_CONTEXT(ctx); - /*_mesa_add_extension(ctx, GL_TRUE, "3DFX_set_global_palette", 0);*/ _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"); if (fxMesa->haveTwoTMUs) { _mesa_enable_extension(ctx, "GL_EXT_texture_env_add"); @@ -1136,18 +1429,44 @@ fxDDInitExtensions(GLcontext * ctx) _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" ); } -#if 0 /* not ready yet */ - /* banshee/avenger should enable this for NCC */ - _mesa_enable_extension( ctx, "GL_ARB_texture_compression" ); -#endif - if (0/*IS_NAPALM*/) { - /* tex_compress: not ready yet */ - _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" );*/ - - /* env_combine: not ready yet */ - /*_mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" );*/ + /* [dBorca] Hack alert: + * True texture compression can be done only on Napalm. + * We will advertise, however, generic texture compression + * on all Voodoo cards; the Mesa logic allows us to eventually + * fallback to uncompressed. This will fix those dumb applications + * which refuse to run w/o texture compression! We actually _can_ + * do texture compression for pre-Napalm cores, through NCC. But + * NCC poses many issues: + * 1) NCC w/o DITHER_ERR has poor quality and NCC w/ DITHER_ERR is + * damn slow! + * 2) NCC compression cannot be used with multitexturing, because + * the decompression tables are not per TMU anymore (bear in mind + * that earlier Voodoos could handle 2 NCC tables for each TMU -- + * just look for POINTCAST_PALETTE). As a last resort, we could + * fake NCC multitexturing through multipass rendering, but... + * ohwell, it's not worth the effort... + * This stand true for multitexturing palletized textures. + * 3) since NCC is not an OpenGL standard (as opposed to FXT1), we + * would need to plug deeper into the core... First, we would need to + * bind NCC to GL_COMPRESSED_RGB[A]. Then, we would need to trick + * Mesa into reporting our texture as compressed. Last, we would need + * to stash the NCC decompression table into the mipmap data and adjust + * CompressedSize accordingly! + */ + _mesa_enable_extension(ctx, "GL_ARB_texture_compression"); + + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + _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"); + } + + if (fxMesa->HaveCmbExt) { + _mesa_enable_extension(ctx, "GL_EXT_texture_env_combine"); + } + + if (fxMesa->HavePixExt) { + _mesa_enable_extension(ctx, "GL_EXT_blend_subtract"); } if (fxMesa->HaveMirExt) { @@ -1181,8 +1500,17 @@ fx_check_IsInHardware(GLcontext * ctx) return FX_FALLBACK_DRAW_BUFFER; } - if (ctx->Color.BlendEnabled && (ctx->Color.BlendEquation != GL_FUNC_ADD_EXT)) { - return FX_FALLBACK_BLEND; + if (ctx->Color.BlendEnabled) { + if (ctx->Color.BlendEquation != GL_FUNC_ADD_EXT) { + if (fxMesa->HavePixExt) { + if ((ctx->Color.BlendEquation != GL_FUNC_SUBTRACT_EXT) && + (ctx->Color.BlendEquation != GL_FUNC_REVERSE_SUBTRACT_EXT)) { + return FX_FALLBACK_BLEND; + } + } else { + return FX_FALLBACK_BLEND; + } + } } if (ctx->Color.ColorLogicOpEnabled && (ctx->Color.LogicOp != GL_COPY)) { @@ -1212,6 +1540,7 @@ fx_check_IsInHardware(GLcontext * ctx) return FX_FALLBACK_TEXTURE_1D_3D; if (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) { + if (fxMesa->type < GR_SSTTYPE_Voodoo2) if (ctx->Texture.Unit[0].EnvMode == GL_BLEND && (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT || ctx->Texture.Unit[0].EnvColor[0] != 0 || @@ -1225,6 +1554,7 @@ fx_check_IsInHardware(GLcontext * ctx) } if (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT) { + 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]->Border > 0) @@ -1264,6 +1594,7 @@ fx_check_IsInHardware(GLcontext * ctx) return FX_FALLBACK_TEXTURE_MULTI; } + if (fxMesa->type < GR_SSTTYPE_Voodoo2) if ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) && (ctx->Texture.Unit[0].EnvMode == GL_BLEND)) { return FX_FALLBACK_TEXTURE_ENV; @@ -1314,18 +1645,21 @@ fxSetupDDPointers(GLcontext * ctx) ctx->Driver.DrawBuffer = fxDDSetDrawBuffer; ctx->Driver.GetBufferSize = fxDDBufferSize; ctx->Driver.Accum = _swrast_Accum; - ctx->Driver.Bitmap = fxDDDrawBitmap; ctx->Driver.CopyPixels = _swrast_CopyPixels; ctx->Driver.DrawPixels = _swrast_DrawPixels; switch (fxMesa->colDepth) { case 15: ctx->Driver.ReadPixels = fxDDReadPixels555; + ctx->Driver.Bitmap = fxDDDrawBitmap2; break; case 16: - ctx->Driver.ReadPixels = fxDDReadPixels; + ctx->Driver.ReadPixels = fxDDReadPixels565; + ctx->Driver.Bitmap = fxDDDrawBitmap2; break; case 32: - ctx->Driver.ReadPixels = fxDDReadPixels888; + ctx->Driver.DrawPixels = fxDDDrawPixels8888; + ctx->Driver.ReadPixels = fxDDReadPixels8888; + ctx->Driver.Bitmap = fxDDDrawBitmap4; break; } ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; @@ -1339,11 +1673,13 @@ fxSetupDDPointers(GLcontext * ctx) ctx->Driver.TexSubImage2D = fxDDTexSubImage2D; ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; - ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage2D = fxDDCompressedTexImage2D; ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; - ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage2D = fxDDCompressedTexSubImage2D; ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + ctx->Driver.IsCompressedFormat = fxDDIsCompressedFormat; + ctx->Driver.CompressedTextureSize = fxDDCompressedTextureSize; ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; @@ -1358,9 +1694,12 @@ fxSetupDDPointers(GLcontext * ctx) 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.BlendFunc = fxDDBlendFunc; + ctx->Driver.BlendFuncSeparate = fxDDBlendFuncSeparate; + ctx->Driver.BlendEquation = fxDDBlendEquation; ctx->Driver.DepthFunc = fxDDDepthFunc; ctx->Driver.DepthMask = fxDDDepthMask; ctx->Driver.ColorMask = fxDDColorMask; diff --git a/src/mesa/drivers/glide/fxddspan.c b/src/mesa/drivers/glide/fxddspan.c index 460126e86b1..158e34e08e1 100644 --- a/src/mesa/drivers/glide/fxddspan.c +++ b/src/mesa/drivers/glide/fxddspan.c @@ -1,12 +1,3 @@ -/* Hack alert: - * The performance hit is disastruous for SPAN functions. - * Should we use SpanRenderStart / SpanRenderFinish in `swrast.h' - * for locking / unlocking the LFB? - * Optimize and check endianess for `read_R8G8B8_pixels' - */ - -/* $Id: fxddspan.c,v 1.25 2003/10/02 17:36:44 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -54,548 +45,415 @@ #include "fxglidew.h" #include "swrast/swrast.h" -#ifdef _MSC_VER -#ifdef _WIN32 -#pragma warning( disable : 4090 4022 ) -/* 4101 : "different 'const' qualifier" - * 4022 : "pointer mistmatch for actual parameter 'n' - */ -#endif -#endif - - - -#define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \ - FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) - +/************************************************************************/ +/***** Span functions *****/ +/************************************************************************/ -/* KW: Rearranged the args in the call to grLfbWriteRegion(). +#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 { \ + int _nc = 1; /* numcliprects */ \ + /* [dBorca] Hack alert: */ \ + /* remember, we need to flip the scissor, too */ \ + /* is it better to do it inside fxDDScissor? */ \ + while (_nc--) { \ + 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 { \ + int _nc = 1; /* numcliprects */ \ + /* [dBorca] Hack alert: */ \ + /* remember, we need to flip the scissor, too */ \ + /* is it better to do it inside fxDDScissor? */ \ + while (_nc--) { \ + 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... */ -#define LFB_WRITE_SPAN_MESA(dst_buffer, \ - dst_x, \ - dst_y, \ - src_width, \ - src_stride, \ - src_data) \ - writeRegionClipped(fxMesa, dst_buffer, \ - dst_x, \ - dst_y, \ - GR_LFB_SRC_FMT_8888, \ - src_width, \ - 1, \ - src_stride, \ - src_data) \ +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_565 -/************************************************************************/ -/***** Span functions *****/ -/************************************************************************/ +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 2 +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = TDFXPACKCOLOR565( color[RCOMP], color[GCOMP], color[BCOMP] ) -static void -fxDDWriteRGBASpan(const GLcontext * ctx, - GLuint n, GLint x, GLint y, - const GLubyte rgba[][4], const GLubyte mask[]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLuint i; - GLint bottom = fxMesa->height - 1; +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = \ + TDFXPACKCOLOR565( r, g, b ) - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p - if (mask) { - int span = 0; - - for (i = 0; i < n; i++) { - if (mask[i]) { - ++span; - } - else { - if (span > 0) { - LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + i - span, - bottom - y, - /* GR_LFB_SRC_FMT_8888, */ span, /*1, */ 0, - (void *) rgba[i - span]); - span = 0; - } - } - } - - if (span > 0) - LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + n - span, bottom - y, - /* GR_LFB_SRC_FMT_8888, */ span, /*1, */ 0, - (void *) rgba[n - span]); - } - else - LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x, bottom - y, /* GR_LFB_SRC_FMT_8888, */ - n, /* 1, */ 0, (void *) rgba); -} +#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" -static void -fxDDWriteRGBSpan(const GLcontext * ctx, - GLuint n, GLint x, GLint y, - const GLubyte rgb[][3], const GLubyte mask[]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLuint i; - GLint bottom = fxMesa->height - 1; - GLubyte rgba[MAX_WIDTH][4]; - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } +/* 32 bit, ARGB8888 color spanline and pixel functions */ - if (mask) { - int span = 0; - - for (i = 0; i < n; i++) { - if (mask[i]) { - rgba[span][RCOMP] = rgb[i][0]; - rgba[span][GCOMP] = rgb[i][1]; - rgba[span][BCOMP] = rgb[i][2]; - rgba[span][ACOMP] = 255; - ++span; - } - else { - if (span > 0) { - LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + i - span, - bottom - y, - /*GR_LFB_SRC_FMT_8888, */ span, /* 1, */ 0, - (void *) rgba); - span = 0; - } - } - } - - if (span > 0) - LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + n - span, bottom - y, - /*GR_LFB_SRC_FMT_8888, */ span, /* 1, */ 0, - (void *) rgba); - } - else { - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = rgb[i][0]; - rgba[i][GCOMP] = rgb[i][1]; - rgba[i][BCOMP] = rgb[i][2]; - rgba[i][ACOMP] = 255; - } - - LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x, bottom - y, /* GR_LFB_SRC_FMT_8888, */ - n, /* 1, */ 0, (void *) rgba); - } -} +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_8888 +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 4 -static void -fxDDWriteMonoRGBASpan(const GLcontext * ctx, - GLuint n, GLint x, GLint y, - const GLchan color[4], const GLubyte mask[]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLuint i; - GLint bottom = fxMesa->height - 1; - GLuint data[MAX_WIDTH]; - GrColor_t gColor = FXCOLOR4(color); +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = TDFXPACKCOLOR8888( color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP] ) - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = \ + TDFXPACKCOLOR8888( r, g, b, a ) - if (mask) { - int span = 0; - - for (i = 0; i < n; i++) { - if (mask[i]) { - data[span] = (GLuint) gColor; - ++span; - } - else { - if (span > 0) { - writeRegionClipped(fxMesa, fxMesa->currentFB, x + i - span, - bottom - y, GR_LFB_SRC_FMT_8888, span, 1, 0, - (void *) data); - span = 0; - } - } - } - - if (span > 0) - writeRegionClipped(fxMesa, fxMesa->currentFB, x + n - span, - bottom - y, GR_LFB_SRC_FMT_8888, span, 1, 0, - (void *) data); - } - else { - for (i = 0; i < n; i++) { - data[i] = (GLuint) gColor; - } +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p - writeRegionClipped(fxMesa, fxMesa->currentFB, x, bottom - y, - GR_LFB_SRC_FMT_8888, n, 1, 0, (void *) data); - } -} +#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" -#if 0 -static void -fxDDReadRGBASpan(const GLcontext * ctx, - GLuint n, GLint x, GLint y, GLubyte rgba[][4]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLushort data[MAX_WIDTH]; - GLuint i; - GLint bottom = fxMesa->height - 1; - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } +/************************************************************************/ +/***** Depth functions *****/ +/************************************************************************/ - assert(n < MAX_WIDTH); +#define DBG 0 - FX_grLfbReadRegion(fxMesa->currentFB, x, bottom - y, n, 1, 0, data); +#undef HW_WRITE_LOCK +#undef HW_WRITE_UNLOCK +#undef HW_READ_LOCK +#undef HW_READ_UNLOCK - for (i = 0; i < n; i++) { - GLushort pixel = data[i]; - rgba[i][RCOMP] = FX_PixelToR[pixel]; - rgba[i][GCOMP] = FX_PixelToG[pixel]; - rgba[i][BCOMP] = FX_PixelToB[pixel]; - rgba[i][ACOMP] = 255; - } -} -#endif +#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; -/* - * 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 -read_R5G6B5_span(const GLcontext * ctx, - GLuint n, GLint x, GLint y, GLubyte rgba[][4]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GrLfbInfo_t info; - BEGIN_BOARD_LOCK(); - 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 *data16 = (const GLushort *) info.lfbPtr - + (winY - y) * srcStride + (winX + x); - 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]; - GLuint pixel0 = pixel & 0xffff; - GLuint pixel1 = pixel >> 16; - rgba[i][RCOMP] = FX_PixelToR[pixel0]; - rgba[i][GCOMP] = FX_PixelToG[pixel0]; - rgba[i][BCOMP] = FX_PixelToB[pixel0]; - rgba[i][ACOMP] = 255; - rgba[i + 1][RCOMP] = FX_PixelToR[pixel1]; - rgba[i + 1][GCOMP] = FX_PixelToG[pixel1]; - rgba[i + 1][BCOMP] = FX_PixelToB[pixel1]; - rgba[i + 1][ACOMP] = 255; - } - if (extraPixel) { - GLushort pixel = data16[n]; - rgba[n][RCOMP] = FX_PixelToR[pixel]; - rgba[n][GCOMP] = FX_PixelToG[pixel]; - rgba[n][BCOMP] = FX_PixelToB[pixel]; - rgba[n][ACOMP] = 255; - } - - grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); - } - END_BOARD_LOCK(); -} +#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 ) ) { -/* - * 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 read_R5G5B5_span (const GLcontext * ctx, - GLuint n, - GLint x, GLint y, - GLubyte rgba[][4]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GrLfbInfo_t info; - BEGIN_BOARD_LOCK(); - 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 *data16 = (const GLushort *) info.lfbPtr - + (winY - y) * srcStride + (winX + x); - 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][RCOMP] = FX_rgb_scale_5[ pixel & 0x1f]; - rgba[i][GCOMP] = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; - rgba[i][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; - rgba[i][ACOMP] = (pixel & 0x8000) ? 255 : 0; - rgba[i + 1][RCOMP] = FX_rgb_scale_5[(pixel >> 16) & 0x1f]; - rgba[i + 1][GCOMP] = FX_rgb_scale_5[(pixel >> 21) & 0x1f]; - rgba[i + 1][BCOMP] = FX_rgb_scale_5[(pixel >> 26) & 0x1f]; - rgba[i + 1][ACOMP] = (pixel & 0x80000000) ? 255 : 0; - } - if (extraPixel) { - GLushort pixel = data16[n]; - rgba[n][RCOMP] = FX_rgb_scale_5[ pixel & 0x1f]; - rgba[n][GCOMP] = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; - rgba[n][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; - rgba[n][ACOMP] = (pixel & 0x8000) ? 255 : 0; - } - - grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); - } - END_BOARD_LOCK(); -} +#define HW_WRITE_UNLOCK() \ + grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_AUXBUFFER); \ + } -/* - * 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 read_R8G8B8_span (const GLcontext * ctx, - GLuint n, - GLint x, GLint y, - GLubyte rgba[][4]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - BEGIN_BOARD_LOCK(); - grLfbReadRegion(fxMesa->currentFB, x, fxMesa->height - 1 - y, n, 1, n * 4, rgba); - END_BOARD_LOCK(); -} +#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); \ + } -/************************************************************************/ -/***** Pixel functions *****/ -/************************************************************************/ -static void -fxDDWriteRGBAPixels(const GLcontext * ctx, - GLuint n, const GLint x[], const GLint y[], - CONST GLubyte rgba[][4], const GLubyte mask[]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLuint i; - GLint bottom = fxMesa->height - 1; +/* 16 bit, depth spanline and pixel functions */ - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_ZA16 - for (i = 0; i < n; i++) - if (mask[i]) - LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i], bottom - y[i], - 1, 1, (void *) rgba[i]); -} +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 2 -static void -fxDDWriteMonoRGBAPixels(const GLcontext * ctx, - GLuint n, const GLint x[], const GLint y[], - const GLchan color[4], const GLubyte mask[]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLuint i; - GLint bottom = fxMesa->height - 1; - GrColor_t gColor = FXCOLOR4(color); +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) - for (i = 0; i < n; i++) - if (mask[i]) - writeRegionClipped(fxMesa, fxMesa->currentFB, x[i], bottom - y[i], - GR_LFB_SRC_FMT_8888, 1, 1, 0, (void *) &gColor); -} +#define TAG(x) tdfx##x##_Z16 +#include "../dri/common/depthtmp.h" -static void -read_R5G6B5_pixels(const GLcontext * ctx, - GLuint n, const GLint x[], const GLint y[], - GLubyte rgba[][4], const GLubyte mask[]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GrLfbInfo_t info; - BEGIN_BOARD_LOCK(); - if (grLfbLock(GR_LFB_READ_ONLY, - fxMesa->currentFB, - GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { - const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */ - const GLint winX = 0; - const GLint winY = fxMesa->height - 1; - GLuint i; - for (i = 0; i < n; i++) { - if (mask[i]) { - const GLushort *data16 = (const GLushort *) info.lfbPtr - + (winY - y[i]) * srcStride + (winX + x[i]); - const GLushort pixel = *data16; - rgba[i][RCOMP] = FX_PixelToR[pixel]; - rgba[i][GCOMP] = FX_PixelToG[pixel]; - rgba[i][BCOMP] = FX_PixelToB[pixel]; - rgba[i][ACOMP] = 255; - } - } - grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); - } - END_BOARD_LOCK(); -} +/* 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 -static void read_R5G5B5_pixels (const GLcontext * ctx, - GLuint n, - const GLint x[], const GLint y[], - GLubyte rgba[][4], - const GLubyte mask[]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GrLfbInfo_t info; - BEGIN_BOARD_LOCK(); - if (grLfbLock(GR_LFB_READ_ONLY, - fxMesa->currentFB, - GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { - const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */ - const GLint winX = 0; - const GLint winY = fxMesa->height - 1; - GLuint i; - for (i = 0; i < n; i++) { - if (mask[i]) { - const GLushort *data16 = (const GLushort *) info.lfbPtr - + (winY - y[i]) * srcStride + (winX + x[i]); - const GLushort pixel = *data16; - rgba[i][RCOMP] = FX_rgb_scale_5[ pixel & 0x1f]; - rgba[i][GCOMP] = FX_rgb_scale_5[(pixel >> 5) & 0x1f]; - rgba[i][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; - rgba[i][ACOMP] = (pixel & 0x8000) ? 255 : 0; - } - } - grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); - } - END_BOARD_LOCK(); -} +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 4 +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d << 8 -static void -read_R8G8B8_pixels(const GLcontext * ctx, - GLuint n, const GLint x[], const GLint y[], - GLubyte rgba[][4], const GLubyte mask[]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GrLfbInfo_t info; - BEGIN_BOARD_LOCK(); - if (grLfbLock(GR_LFB_READ_ONLY, - fxMesa->currentFB, - GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) { - const GLint srcStride = info.strideInBytes / 4; /* stride in GLuints */ - const GLint winX = 0; - const GLint winY = fxMesa->height - 1; - GLuint i; - for (i = 0; i < n; i++) { - if (mask[i]) { - const GLuint *data32 = (const GLuint *) info.lfbPtr - + (winY - y[i]) * srcStride + (winX + x[i]); - const GLuint pixel = *data32; - *(GLuint *)&rgba[i][0] = pixel; - } - } - grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); - } - END_BOARD_LOCK(); -} +#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! + */ /************************************************************************/ -/***** Depth functions *****/ +/***** Span functions (optimized) *****/ /************************************************************************/ -void -fxDDWriteDepthSpan(GLcontext * ctx, - GLuint n, GLint x, GLint y, const GLdepth depth[], - const GLubyte mask[]) +/* + * 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, + GLuint n, + GLint x, GLint y, + GLubyte rgba[][4]) { - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLint bottom = fxMesa->height - 1; - - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } - - - if (mask) { - GLint i; - for (i = 0; i < n; i++) { - if (mask[i]) { - GLshort d = depth[i]; - writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y, - GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d); - } - } - } - else { - GLushort depth16[MAX_WIDTH]; - GLint i; - for (i = 0; i < n; i++) { - depth16[i] = depth[i]; - } - writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y, - GR_LFB_SRC_FMT_ZA16, n, 1, 0, (void *) depth16); - } + 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); + } } - -void -fxDDWriteDepth32Span(GLcontext * ctx, - GLuint n, GLint x, GLint y, const GLdepth depth[], - const GLubyte mask[]) +/* + * 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, + GLuint n, + GLint x, GLint y, + GLubyte rgba[][4]) { - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLint bottom = fxMesa->height - 1; - GLint i; - - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } - + 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); + } +} - if (mask) { - for (i = 0; i < n; i++) { - if (mask[i]) { - GLuint d = depth[i] << 8; - writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y, - GR_LFBWRITEMODE_Z32, 1, 1, 0, (void *) &d); - } - } - } - else { - GLuint depth32[MAX_WIDTH]; - for (i = 0; i < n; i++) { - depth32[i] = depth[i] << 8; - } - writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y, - GR_LFBWRITEMODE_Z32, n, 1, 0, (void *) depth32); - } +/* + * 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, + 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) *****/ +/************************************************************************/ + void -fxDDReadDepthSpan(GLcontext * ctx, - GLuint n, GLint x, GLint y, GLdepth depth[]) +fxReadDepthSpan_Z16(GLcontext * ctx, + GLuint n, GLint x, GLint y, GLdepth depth[]) { fxMesaContext fxMesa = FX_CONTEXT(ctx); GLint bottom = fxMesa->height - 1; @@ -614,116 +472,81 @@ fxDDReadDepthSpan(GLcontext * ctx, void -fxDDReadDepth32Span(GLcontext * ctx, - GLuint n, GLint x, GLint y, GLdepth depth[]) +fxReadDepthSpan_Z24(GLcontext * ctx, + 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, "%s(...)\n", __FUNCTION__); } grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth); + for (i = 0; i < n; i++) { + depth[i] &= 0xffffff; + } } +/************************************************************************/ +/***** Stencil functions (optimized) *****/ +/************************************************************************/ -void -fxDDWriteDepthPixels(GLcontext * ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth depth[], const GLubyte mask[]) +void fxWriteStencilSpan (GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLstencil stencil[], const GLubyte mask[]) { - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLint bottom = fxMesa->height - 1; - GLuint i; - - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } - - for (i = 0; i < n; i++) { - if (mask[i]) { - int xpos = x[i]; - int ypos = bottom - y[i]; - GLushort d = depth[i]; - writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos, - GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d); - } - } + /* + * XXX todo + */ } - void -fxDDWriteDepth32Pixels(GLcontext * ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth depth[], const GLubyte mask[]) +fxReadStencilSpan(GLcontext * ctx, + 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, "%s(...)\n", __FUNCTION__); } + grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, zs32); for (i = 0; i < n; i++) { - if (mask[i]) { - int xpos = x[i]; - int ypos = bottom - y[i]; - GLuint d = depth[i] << 8; - writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos, - GR_LFBWRITEMODE_Z32, 1, 1, 0, (void *) &d); - } + stencil[i] = zs32[i] >> 24; } } - -void -fxDDReadDepthPixels(GLcontext * ctx, GLuint n, - const GLint x[], const GLint y[], GLdepth depth[]) +void fxWriteStencilPixels (GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLstencil stencil[], + const GLubyte mask[]) { - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLint bottom = fxMesa->height - 1; - GLuint i; - - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } - - for (i = 0; i < n; i++) { - int xpos = x[i]; - int ypos = bottom - y[i]; - GLushort d; - grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &d); - depth[i] = d; - } + /* + * XXX todo + */ } - -void -fxDDReadDepth32Pixels(GLcontext * ctx, GLuint n, - const GLint x[], const GLint y[], GLdepth depth[]) +void fxReadStencilPixels (GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLstencil stencil[]) { - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLint bottom = fxMesa->height - 1; - GLuint i; - - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } - - for (i = 0; i < n; i++) { - int xpos = x[i]; - int ypos = bottom - y[i]; - grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &depth[i]); - } + /* + * XXX todo + */ } -/* Set the buffer used for reading */ -/* XXX support for separate read/draw buffers hasn't been tested */ +/* + * 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) { @@ -753,45 +576,73 @@ void fxSetupDDSpanPointers(GLcontext * ctx) { struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); + fxMesaContext fxMesa = FX_CONTEXT(ctx); swdd->SetBuffer = fxDDSetBuffer; - swdd->WriteRGBASpan = fxDDWriteRGBASpan; - swdd->WriteRGBSpan = fxDDWriteRGBSpan; - swdd->WriteMonoRGBASpan = fxDDWriteMonoRGBASpan; - swdd->WriteRGBAPixels = fxDDWriteRGBAPixels; - swdd->WriteMonoRGBAPixels = fxDDWriteMonoRGBAPixels; - - /* swdd->ReadRGBASpan =fxDDReadRGBASpan; */ - { - fxMesaContext fxMesa = FX_CONTEXT(ctx); switch (fxMesa->colDepth) { case 15: - swdd->ReadRGBASpan = read_R5G5B5_span; - swdd->ReadRGBAPixels = read_R5G5B5_pixels; - swdd->WriteDepthSpan = fxDDWriteDepthSpan; - swdd->WriteDepthPixels = fxDDWriteDepthPixels; - swdd->ReadDepthSpan = fxDDReadDepthSpan; - swdd->ReadDepthPixels = fxDDReadDepthPixels; + 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->ReadRGBASpan = read_R5G6B5_span; - swdd->ReadRGBAPixels = read_R5G6B5_pixels; - swdd->WriteDepthSpan = fxDDWriteDepthSpan; - swdd->WriteDepthPixels = fxDDWriteDepthPixels; - swdd->ReadDepthSpan = fxDDReadDepthSpan; - swdd->ReadDepthPixels = fxDDReadDepthPixels; + 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->ReadRGBASpan = read_R8G8B8_span; - swdd->ReadRGBAPixels = read_R8G8B8_pixels; - swdd->WriteDepthSpan = fxDDWriteDepth32Span; - swdd->WriteDepthPixels = fxDDWriteDepth32Pixels; - swdd->ReadDepthSpan = fxDDReadDepth32Span; - swdd->ReadDepthPixels = fxDDReadDepth32Pixels; + 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 } diff --git a/src/mesa/drivers/glide/fxddtex.c b/src/mesa/drivers/glide/fxddtex.c index 38a268922ae..da1e73d029c 100644 --- a/src/mesa/drivers/glide/fxddtex.c +++ b/src/mesa/drivers/glide/fxddtex.c @@ -1,5 +1,3 @@ -/* $Id: fxddtex.c,v 1.48 2003/10/02 17:36:44 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -41,6 +39,7 @@ #if defined(FX) #include "fxdrv.h" +#include "enums.h" #include "image.h" #include "teximage.h" #include "texformat.h" @@ -192,8 +191,10 @@ fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj, tfxTexInfo *ti; if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(%d, %x, %x, %x)\n", __FUNCTION__, - tObj->Name, (GLuint) tObj->DriverData, pname, param); + 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_2D) @@ -279,6 +280,7 @@ fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj, case GL_MIRRORED_REPEAT: ti->sClamp = GR_TEXTURECLAMP_MIRROR_EXT; break; + case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */ case GL_CLAMP: ti->sClamp = GR_TEXTURECLAMP_CLAMP; break; @@ -296,6 +298,7 @@ fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj, case GL_MIRRORED_REPEAT: ti->tClamp = GR_TEXTURECLAMP_MIRROR_EXT; break; + case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */ case GL_CLAMP: ti->tClamp = GR_TEXTURECLAMP_CLAMP; break; @@ -349,13 +352,23 @@ fxDDTexDel(GLcontext * ctx, struct gl_texture_object *tObj) tObj->DriverData = NULL; } +/* + * 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 void -convertPalette(FxU32 data[256], const struct gl_color_table *table) +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; @@ -373,7 +386,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = tableUB[i]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; case GL_LUMINANCE: for (i = 0; i < width; i++) { r = tableUB[i]; @@ -382,21 +395,22 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = 255; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + 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; } - break; + 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; } - break; + 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]; @@ -405,7 +419,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = 255; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return GR_TEXTABLE_PALETTE; case GL_RGBA: for (i = 0; i < width; i++) { r = tableUB[i * 4 + 0]; @@ -414,7 +428,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = tableUB[i * 4 + 3]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; } } @@ -434,7 +448,7 @@ fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj) if (!tObj->DriverData) tObj->DriverData = fxAllocTexObjData(fxMesa); ti = fxTMGetTexInfo(tObj); - convertPalette(ti->palette.data, &tObj->Palette); + ti->paltype = convertPalette(fxMesa, ti->palette.data, &tObj->Palette); fxTexInvalidate(ctx, tObj); } else { @@ -442,7 +456,7 @@ fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj) if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "%s(global)\n", __FUNCTION__); } - convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette); + fxMesa->glbPalType = convertPalette(fxMesa, fxMesa->glbPalette.data, &ctx->Texture.Palette); fxMesa->new_state |= FX_NEW_TEXTURING; } } @@ -460,7 +474,7 @@ fxDDTexUseGlbPalette(GLcontext * ctx, GLboolean state) if (state) { fxMesa->haveGlobalPaletteTexture = 1; - grTexDownloadTable(GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette)); + grTexDownloadTable(fxMesa->glbPalType, &(fxMesa->glbPalette)); } else { fxMesa->haveGlobalPaletteTexture = 0; @@ -501,27 +515,20 @@ logbase2(int n) } +/* 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) { - /* [koolsmoky] */ - static GrLOD_t lod[12] = { - GR_LOD_LOG2_1, - GR_LOD_LOG2_2, - GR_LOD_LOG2_4, - GR_LOD_LOG2_8, - GR_LOD_LOG2_16, - GR_LOD_LOG2_32, - GR_LOD_LOG2_64, - GR_LOD_LOG2_128, - GR_LOD_LOG2_256, - GR_LOD_LOG2_512, - GR_LOD_LOG2_1024, - GR_LOD_LOG2_2048 - }; - int logw, logh, ws, hs; GrLOD_t l; GrAspectRatio_t aspectratio; @@ -530,76 +537,56 @@ fxTexGetInfo(int w, int h, GrLOD_t * lodlevel, GrAspectRatio_t * ar, logw = logbase2(w); logh = logbase2(h); - switch (logw - logh) { + l = MAX2(logw, logh); + aspectratio = logw - logh; + ws = hs = 1; + + /* 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: - aspectratio = GR_ASPECT_LOG2_1x1; - l = lod[logw]; - s = t = 256.0f; - ws = hs = 1; + s = 256.0f; + t = 256.0f; break; case 1: - aspectratio = GR_ASPECT_LOG2_2x1; - l = lod[logw]; s = 256.0f; t = 128.0f; - ws = 1; - hs = 1; break; case 2: - aspectratio = GR_ASPECT_LOG2_4x1; - l = lod[logw]; s = 256.0f; t = 64.0f; - ws = 1; - hs = 1; break; case 3: - aspectratio = GR_ASPECT_LOG2_8x1; - l = lod[logw]; s = 256.0f; t = 32.0f; - ws = 1; - hs = 1; break; case -1: - aspectratio = GR_ASPECT_LOG2_1x2; - l = lod[logh]; s = 128.0f; t = 256.0f; - ws = 1; - hs = 1; break; case -2: - aspectratio = GR_ASPECT_LOG2_1x4; - l = lod[logh]; s = 64.0f; t = 256.0f; - ws = 1; - hs = 1; break; case -3: - aspectratio = GR_ASPECT_LOG2_1x8; - l = lod[logh]; s = 32.0f; t = 256.0f; - ws = 1; - hs = 1; break; default: - if ((logw - logh) > 3) { - aspectratio = GR_ASPECT_LOG2_8x1; - l = lod[logw]; + if (aspectratio > 3) { s = 256.0f; t = 32.0f; ws = 1; - hs = 1 << (logw - logh - 3); - } else /*if ((logw - logh) < -3)*/ { - aspectratio = GR_ASPECT_LOG2_1x8; - l = lod[logh]; + hs = 1 << (aspectratio - 3); + aspectratio = GR_ASPECT_LOG2_8x1; + } else /*if (aspectratio < -3)*/ { s = 32.0f; t = 256.0f; - ws = 1 << (logh - logw - 3); + ws = 1 << (-aspectratio - 3); hs = 1; + aspectratio = GR_ASPECT_LOG2_1x8; } } @@ -625,125 +612,6 @@ fxTexGetInfo(int w, int h, GrLOD_t * lodlevel, GrAspectRatio_t * ar, return 1; } -/* - * Given an OpenGL internal texture format, return the corresponding - * Glide internal texture format and base texture format. - */ -void -fxTexGetFormat(GLcontext *ctx, GLenum glformat, GrTextureFormat_t * tfmt, GLint * ifmt) /* [koolsmoky] */ -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLboolean allow32bpt = fxMesa->HaveTexFmt; - - switch (glformat) { - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - if (tfmt) - (*tfmt) = GR_TEXFMT_INTENSITY_8; - if (ifmt) - (*ifmt) = GL_LUMINANCE; - break; - 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: - if (tfmt) - (*tfmt) = GR_TEXFMT_ALPHA_INTENSITY_88; - if (ifmt) - (*ifmt) = GL_LUMINANCE_ALPHA; - break; - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - if (tfmt) - (*tfmt) = GR_TEXFMT_ALPHA_8; - if (ifmt) - (*ifmt) = GL_INTENSITY; - break; - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - if (tfmt) - (*tfmt) = GR_TEXFMT_ALPHA_8; - if (ifmt) - (*ifmt) = GL_ALPHA; - break; - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - if (tfmt) - (*tfmt) = GR_TEXFMT_RGB_565; - if (ifmt) - (*ifmt) = GL_RGB; - break; - case 3: - case GL_RGB: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - if (tfmt) - (*tfmt) = allow32bpt ? GR_TEXFMT_ARGB_8888 : GR_TEXFMT_RGB_565; - if (ifmt) - (*ifmt) = GL_RGB; - break; - case GL_RGBA2: - case GL_RGBA4: - if (tfmt) - (*tfmt) = GR_TEXFMT_ARGB_4444; - if (ifmt) - (*ifmt) = GL_RGBA; - break; - case 4: - case GL_RGBA: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - if (tfmt) - (*tfmt) = allow32bpt ? GR_TEXFMT_ARGB_8888 : GR_TEXFMT_ARGB_4444; - if (ifmt) - (*ifmt) = GL_RGBA; - break; - case GL_RGB5_A1: - if (tfmt) - (*tfmt) = GR_TEXFMT_ARGB_1555; - if (ifmt) - (*ifmt) = GL_RGBA; - break; - 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: - if (tfmt) - (*tfmt) = GR_TEXFMT_P_8; - if (ifmt) - (*ifmt) = GL_RGBA; /* XXX why is this RGBA? */ - break; - default: - fprintf(stderr, "%s: ERROR: unsupported internalFormat (0x%x)\n", - __FUNCTION__, glformat); - fxCloseHardware(); - exit(-1); - break; - } -} - static GLboolean fxIsTexSupported(GLenum target, GLint internalFormat, const struct gl_texture_image *image) @@ -820,8 +688,6 @@ fetch_alpha8(const struct gl_texture_image *texImage, i = i * mml->wScale; j = j * mml->hScale; - i = i * mml->width / texImage->Width; - j = j * mml->height / texImage->Height; texel = ((GLubyte *) texImage->Data) + j * mml->width + i; rgba[RCOMP] = 255; @@ -841,8 +707,6 @@ fetch_index8(const struct gl_texture_image *texImage, i = i * mml->wScale; j = j * mml->hScale; - i = i * mml->width / texImage->Width; - j = j * mml->height / texImage->Height; texel = ((GLubyte *) texImage->Data) + j * mml->width + i; *indexOut = *texel; @@ -961,6 +825,133 @@ PrintTexture(int w, int h, int c, const GLubyte * data) } +GLboolean fxDDIsCompressedFormat ( GLcontext *ctx, GLenum internalFormat ) +{ + if ((internalFormat == GL_COMPRESSED_RGB_FXT1_3DFX) || + (internalFormat == GL_COMPRESSED_RGBA_FXT1_3DFX) || + (internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) || + (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || + (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || + (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) || + (internalFormat == GL_RGB_S3TC) || + (internalFormat == GL_RGB4_S3TC) || + (internalFormat == GL_RGBA_S3TC) || + (internalFormat == GL_RGBA4_S3TC)) { + return GL_TRUE; + } + +/* [dBorca] + * we are handling differently the above formats from the generic + * GL_COMPRESSED_RGB[A]. For this, we will always have to separately + * check for the ones below! + */ + +#if FX_TC_NCC || FX_TC_NAPALM + if ((internalFormat == GL_COMPRESSED_RGB) || (internalFormat == GL_COMPRESSED_RGBA)) { + return GL_TRUE; + } +#endif + + return GL_FALSE; +} + + +GLuint fxDDCompressedTextureSize (GLcontext *ctx, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format) +{ + GLuint size; + int wScale, hScale; + + ASSERT(depth == 1); + + /* Determine width and height scale factors for texture. + * Remember, Glide is limited to 8:1 aspect ratios. + */ + fxTexGetInfo(width, height, + NULL, /* lod level */ + NULL, /* aspect ratio */ + NULL, NULL, /* sscale, tscale */ + &wScale, &hScale); + + width *= wScale; + height *= hScale; + + switch (format) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + /* round up width to next multiple of 8, height to next multiple of 4 */ + width = (width + 7) & ~7; + height = (height + 3) & ~3; + /* 16 bytes per 8x4 tile of RGB[A] texels */ + size = width * height / 2; + /* Textures smaller than 8x4 will effectively be made into 8x4 and + * take 16 bytes. + */ + if (size < 16) + size = 16; + return size; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + /* round up width, height to next multiple of 4 */ + width = (width + 3) & ~3; + height = (height + 3) & ~3; + /* 8 bytes per 4x4 tile of RGB[A] texels */ + size = width * height / 2; + /* Textures smaller than 4x4 will effectively be made into 4x4 and + * take 8 bytes. + */ + if (size < 8) + size = 8; + return size; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + /* round up width, height to next multiple of 4 */ + width = (width + 3) & ~3; + height = (height + 3) & ~3; + /* 16 bytes per 4x4 tile of RGBA texels */ + size = width * height; /* simple! */ + /* Textures smaller than 4x4 will effectively be made into 4x4 and + * take 16 bytes. + */ + if (size < 16) + size = 16; + return size; + case GL_COMPRESSED_RGB: +#if FX_TC_NAPALM + { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + return fxDDCompressedTextureSize(ctx, width, height, 1, GL_COMPRESSED_RGB_FXT1_3DFX); + } + } +#endif +#if FX_TC_NCC + return (width * height * 8 >> 3) + 12 * 4; +#endif + case GL_COMPRESSED_RGBA: +#if FX_TC_NAPALM + { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + return fxDDCompressedTextureSize(ctx, width, height, 1, GL_COMPRESSED_RGBA_FXT1_3DFX); + } + } +#endif +#if FX_TC_NCC + return (width * height * 16 >> 3) + 12 * 4; +#endif + default: + _mesa_problem(ctx, "bad texformat in fxDDCompressedTextureSize"); + return 0; + } +} + + const struct gl_texture_format * fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, GLenum srcFormat, GLenum srcType ) @@ -968,6 +959,21 @@ fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, fxMesaContext fxMesa = FX_CONTEXT(ctx); GLboolean allow32bpt = fxMesa->HaveTexFmt; + /* [dBorca] Hack alert: + * There is something wrong with this!!! Take an example: + * 1) start HW rendering + * 2) create a texture like this: + * glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0, + * GL_RGB, GL_UNSIGNED_BYTE, floorTexture); + * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + * 3) we get here with internalFormat==3 and return either + * _mesa_texformat_rgb565 or _mesa_texformat_argb8888 + * 4) at some point, we encounter total rasterization fallback + * 5) displaying a polygon with the above textures yield garbage on areas + * where pixel is larger than a texel, because our already set texel + * function doesn't match the real _mesa_texformat_argb888 + */ + if (TDFX_DEBUG & VERBOSE_TEXTURE) { fprintf(stderr, "fxDDChooseTextureFormat(...)\n"); } @@ -1056,20 +1062,24 @@ fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, : &_mesa_texformat_argb4444; case GL_RGB5_A1: return &_mesa_texformat_argb1555; -#if 0 /* GL_EXT_texture_compression_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; - /*case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return blah;*/ -#endif + /* 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; @@ -1097,11 +1107,11 @@ fxGlideFormat(GLint mesaFormat) return GR_TEXFMT_ARGB_4444; case MESA_FORMAT_ARGB1555: return GR_TEXFMT_ARGB_1555; -#if 1 /* [koolsmoky] getting ready for 32bpp textures */ case MESA_FORMAT_ARGB8888: return GR_TEXFMT_ARGB_8888; -#endif -#if 0 + 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; @@ -1109,11 +1119,6 @@ fxGlideFormat(GLint mesaFormat) return GR_TEXFMT_ARGB_CMP_DXT3; case MESA_FORMAT_RGBA_DXT5: return GR_TEXFMT_ARGB_CMP_DXT5; - /*case MESA_FORMAT_ARGB_CMP_FXT1: - return GR_TEXFMT_ARGB_CMP_FXT1; - case MESA_FORMAT_RGB_CMP_FXT1: - return GL_COMPRESSED_RGBA_FXT1_3DFX;*/ -#endif default: _mesa_problem(NULL, "Unexpected format in fxGlideFormat"); return 0; @@ -1126,32 +1131,30 @@ fxFetchFunction(GLint mesaFormat) { switch (mesaFormat) { case MESA_FORMAT_I8: - return fetch_intensity8; + return &fetch_intensity8; case MESA_FORMAT_A8: - return fetch_alpha8; + return &fetch_alpha8; case MESA_FORMAT_L8: - return fetch_luminance8; + return &fetch_luminance8; case MESA_FORMAT_CI8: - return fetch_index8; + return &fetch_index8; case MESA_FORMAT_AL88: - return fetch_luminance8_alpha8; + return &fetch_luminance8_alpha8; case MESA_FORMAT_RGB565: - return fetch_r5g6b5; + return &fetch_r5g6b5; case MESA_FORMAT_ARGB4444: - return fetch_r4g4b4a4; + return &fetch_r4g4b4a4; case MESA_FORMAT_ARGB1555: - return fetch_r5g5b5a1; -#if 1 /* [koolsmoky] getting ready for 32bpp textures */ + return &fetch_r5g5b5a1; case MESA_FORMAT_ARGB8888: - return fetch_a8r8g8b8; -#endif -#if 0 + return &fetch_a8r8g8b8; + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: case MESA_FORMAT_RGB_DXT1: case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGBA_DXT3: case MESA_FORMAT_RGBA_DXT5: - return fetch_r4g4b4a4; -#endif + return &fetch_r4g4b4a4; default: _mesa_problem(NULL, "Unexpected format in fxFetchFunction"); return NULL; @@ -1171,6 +1174,9 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, tfxMipMapLevel *mml; GLint texelBytes; + GLvoid *_final_texImage_Data; + const struct gl_texture_format *_final_texImage_TexFormat; + 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, @@ -1215,6 +1221,51 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, texelBytes = texImage->TexFormat->TexelBytes; /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/ + mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + /* dirty trick: will thrash CopyTex[Sub]Image */ +#if FX_TC_NCC || FX_TC_NAPALM + if (internalFormat == GL_COMPRESSED_RGB) { +#if FX_TC_NCC + mml->glideFormat = GR_TEXFMT_YIQ_422; +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + mml->glideFormat = GR_TEXFMT_ARGB_CMP_FXT1; + } +#endif + } else if (internalFormat == GL_COMPRESSED_RGBA) { +#if FX_TC_NCC + mml->glideFormat = GR_TEXFMT_AYIQ_8422; +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + mml->glideFormat = GR_TEXFMT_ARGB_CMP_FXT1; + } +#endif + } +#endif + + /* allocate mipmap buffer */ + assert(!texImage->Data); + if (texImage->IsCompressed) { + texImage->Data = MESA_PBUFFER_ALLOC(texImage->CompressedSize); + texelBytes = 4; + _final_texImage_TexFormat = &_mesa_texformat_argb8888; + _final_texImage_Data = MALLOC(mml->width * mml->height * 4); + if (!_final_texImage_Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } else { + texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); + _final_texImage_TexFormat = texImage->TexFormat; + _final_texImage_Data = texImage->Data; + } + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + if (mml->wScale != 1 || mml->hScale != 1) { /* rescale image to overcome 1:8 aspect limitation */ GLvoid *tempImage; @@ -1225,51 +1276,57 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, } /* unpack image, apply transfer ops and store in tempImage */ _mesa_transfer_teximage(ctx, 2, texImage->Format, - texImage->TexFormat, + _final_texImage_TexFormat, tempImage, width, height, 1, 0, 0, 0, width * texelBytes, 0, /* dstImageStride */ format, type, pixels, packing); - assert(!texImage->Data); - texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - FREE(tempImage); - return; - } _mesa_rescale_teximage2d(texelBytes, mml->width * texelBytes, /* dst stride */ width, height, mml->width, mml->height, - tempImage /*src*/, texImage->Data /*dst*/ ); + tempImage /*src*/, _final_texImage_Data /*dst*/ ); FREE(tempImage); } else { /* no rescaling needed */ - assert(!texImage->Data); - texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } /* unpack image, apply transfer ops and store in texImage->Data */ _mesa_transfer_teximage(ctx, 2, texImage->Format, - texImage->TexFormat, texImage->Data, + _final_texImage_TexFormat, _final_texImage_Data, width, height, 1, 0, 0, 0, texImage->Width * texelBytes, 0, /* dstImageStride */ format, type, pixels, packing); } - mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + /* now compress */ + if (texImage->IsCompressed) { +#if FX_TC_NCC + if ((mml->glideFormat == GR_TEXFMT_AYIQ_8422) || + (mml->glideFormat == GR_TEXFMT_YIQ_422)) { + TxMip txMip, pxMip; + txMip.width = mml->width; + txMip.height = mml->height; + txMip.depth = 1; + txMip.data[0] = _final_texImage_Data; + pxMip.data[0] = texImage->Data; + fxMesa->Glide.txMipQuantize(&pxMip, &txMip, mml->glideFormat, TX_DITHER_ERR, TX_COMPRESSION_STATISTICAL); + fxMesa->Glide.txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal); + MEMCPY((char *)texImage->Data + texImage->CompressedSize - 12 * 4, &(ti->palette.data[16]), 12 * 4); + } else +#endif + fxMesa->Glide.txImgQuantize(texImage->Data, _final_texImage_Data, mml->width, mml->height, mml->glideFormat, TX_DITHER_NONE); + FREE(_final_texImage_Data); + } + ti->info.format = mml->glideFormat; texImage->FetchTexel = fxFetchFunction(texImage->TexFormat->MesaFormat); /* [dBorca] * Hack alert: unsure... */ - if (!(fxMesa->new_state & FX_NEW_TEXTURING) && ti->validated && ti->isInTM) { + if (0 && ti->validated && ti->isInTM) { /*fprintf(stderr, "reloadmipmaplevels\n"); */ fxTMReloadMipMapLevel(fxMesa, texObj, level); } @@ -1294,6 +1351,10 @@ fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, tfxMipMapLevel *mml; GLint texelBytes; + /* [dBorca] Hack alert: + * fix the goddamn texture compression here + */ + if (TDFX_DEBUG & VERBOSE_TEXTURE) { fprintf(stderr, "fxDDTexSubImage2D: id=%d\n", texObj->Name); } @@ -1363,7 +1424,180 @@ fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, /* [dBorca] * Hack alert: unsure... */ - if (!(fxMesa->new_state & FX_NEW_TEXTURING) && ti->validated && ti->isInTM) + if (0 && ti->validated && ti->isInTM) + 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, "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; + + + /* 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); +#if FX_TC_NCC || FX_TC_NAPALM + if (internalFormat == GL_COMPRESSED_RGB) { +#if FX_TC_NCC + mml->glideFormat = GR_TEXFMT_YIQ_422; +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + mml->glideFormat = GR_TEXFMT_ARGB_CMP_FXT1; + } +#endif + } else if (internalFormat == GL_COMPRESSED_RGBA) { +#if FX_TC_NCC + mml->glideFormat = GR_TEXFMT_AYIQ_8422; +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + mml->glideFormat = GR_TEXFMT_ARGB_CMP_FXT1; + } +#endif + } +#endif + + /* allocate new storage for texture image, if needed */ + if (!texImage->Data) { + texImage->Data = MESA_PBUFFER_ALLOC(imageSize); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + + /* save the texture data */ + MEMCPY(texImage->Data, data, imageSize); +#if FX_TC_NCC + if ((mml->glideFormat == GR_TEXFMT_AYIQ_8422) || + (mml->glideFormat == GR_TEXFMT_YIQ_422)) { + MEMCPY(&(ti->palette.data[16]), (char *)data + imageSize - 12 * 4, 12 * 4); + } +#endif + + ti->info.format = mml->glideFormat; + texImage->FetchTexel = fxFetchFunction(texImage->TexFormat->MesaFormat); + + /* [dBorca] Hack alert: + * what about different size/texel? other anomalies? SW rescaling? + */ + + /* [dBorca] + * Hack alert: unsure... + */ + if (0 && ti->validated && ti->isInTM) { + /*fprintf(stderr, "reloadmipmaplevels\n"); */ + fxTMReloadMipMapLevel(fxMesa, texObj, level); + } + else { + /*fprintf(stderr, "invalidate2\n"); */ + 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; + + 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); + + /* + * We punt if we are not replacing the entire image. This + * is allowed by the spec. + * + * [dBorca] Hack alert: + * ohwell, we should NOT! Look into _mesa_store_compressed_texsubimage2d + * on how to calculate the sub-image. + */ + if ((xoffset != 0) && (yoffset != 0) + && (width != texImage->Width) + && (height != texImage->Height)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(CHICKEN)"); + return; + } + + /* [dBorca] Hack alert: + * what about different size/texel? other anomalies? SW rescaling? + */ + MEMCPY(texImage->Data, data, imageSize); + + /* [dBorca] + * Hack alert: unsure... + */ + if (0 && ti->validated && ti->isInTM) fxTMReloadMipMapLevel(fxMesa, texObj, level); else fxTexInvalidate(ctx, texObj); diff --git a/src/mesa/drivers/glide/fxdrv.h b/src/mesa/drivers/glide/fxdrv.h index b404d52fa62..c109f22f1e8 100644 --- a/src/mesa/drivers/glide/fxdrv.h +++ b/src/mesa/drivers/glide/fxdrv.h @@ -1,5 +1,3 @@ -/* $Id: fxdrv.h,v 1.59 2003/10/02 17:36:44 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -86,6 +84,14 @@ ( (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 @@ -147,6 +153,90 @@ #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 */ @@ -196,6 +286,7 @@ typedef struct tfxTexInfo_t GLfloat sScale, tScale; + GrTexTable_t paltype; GuTexPalette palette; GLboolean fixedPalette; @@ -229,6 +320,7 @@ typedef struct GrAlphaBlendFnc_t blendDstFuncRGB; GrAlphaBlendFnc_t blendSrcFuncAlpha; GrAlphaBlendFnc_t blendDstFuncAlpha; + GrAlphaBlendOp_t blendEq; /* Depth test */ @@ -317,13 +409,6 @@ tfxUnitsState; _NEW_COLOR) \ -/* These lookup table are used to extract RGB values in [0,255] from - * 16-bit pixel values. - */ -extern GLubyte FX_PixelToR[0x10000]; -extern GLubyte FX_PixelToG[0x10000]; -extern GLubyte FX_PixelToB[0x10000]; - /* 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]; @@ -335,6 +420,7 @@ typedef void (*fx_point_func) (fxMesaContext, GrVertex *); struct tfxMesaContext { + GrTexTable_t glbPalType; GuTexPalette glbPalette; GLcontext *glCtx; /* the core Mesa context */ @@ -443,10 +529,12 @@ struct tfxMesaContext * 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[100]; @@ -485,6 +573,10 @@ extern void fxPrintTextureData(tfxTexInfo * ti); extern const struct gl_texture_format * fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, GLenum srcFormat, GLenum srcType ); +extern GLboolean fxDDIsCompressedFormat (GLcontext *ctx, GLenum internalFormat); +extern GLuint fxDDCompressedTextureSize (GLcontext *ctx, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format); extern void fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, @@ -492,7 +584,6 @@ extern void fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, 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, @@ -501,17 +592,33 @@ extern void fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 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 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 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 fxDDBlendFunc(GLcontext *, GLenum, GLenum); +extern void fxDDBlendFuncSeparate(GLcontext *, GLenum, GLenum, GLenum, GLenum); +extern void fxDDBlendEquation(GLcontext *, GLenum); extern void fxDDDepthMask(GLcontext *, GLboolean); extern void fxDDDepthFunc(GLcontext *, GLenum); extern void fxDDStencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask); @@ -532,6 +639,7 @@ extern void fxTMReloadMipMapLevel(fxMesaContext, struct gl_texture_object *, 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] */ @@ -570,16 +678,19 @@ extern int fxDDInitFxMesaContext(fxMesaContext fxMesa); extern void fxDDDestroyFxMesaContext(fxMesaContext fxMesa); -void fxColorMask (fxMesaContext fxMesa, GLboolean enable); - - extern void fxSetScissorValues(GLcontext * ctx); extern void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where); -extern void fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder); extern void fxCheckIsInHardware(GLcontext *ctx); +/* fxsetup: + * semi-private functions + */ +void fxSetupCull (GLcontext * ctx); +void fxSetupScissor (GLcontext * ctx); +void fxSetupColorMask (GLcontext * ctx); + /* Flags for software fallback cases */ #define FX_FALLBACK_TEXTURE_1D_3D 0x0001 #define FX_FALLBACK_DRAW_BUFFER 0x0002 @@ -595,4 +706,11 @@ extern void fxCheckIsInHardware(GLcontext *ctx); extern GLuint fx_check_IsInHardware(GLcontext *ctx); +/* run-time debugging */ +#if FX_DEBUG +extern int TDFX_DEBUG; +#else +#define TDFX_DEBUG 0 +#endif + #endif diff --git a/src/mesa/drivers/glide/fxg.c b/src/mesa/drivers/glide/fxg.c index 3d00e080b17..9f241851000 100644 --- a/src/mesa/drivers/glide/fxg.c +++ b/src/mesa/drivers/glide/fxg.c @@ -31,6 +31,8 @@ */ +#ifdef FX + #include <stdio.h> #include <stdarg.h> #include <assert.h> @@ -38,17 +40,23 @@ #define DEBUG_TRAP_internal #include "fxg.h" +/* texus.h */ +FX_ENTRY void FX_CALL txImgQuantize (char *dst, char *src, int w, int h, FxU32 format, FxU32 dither); +FX_ENTRY void FX_CALL txMipQuantize (TxMip *pxMip, TxMip *txMip, int fmt, FxU32 d, FxU32 comp); +FX_ENTRY void FX_CALL txPalToNcc (GuNccTable *ncc_table, const FxU32 *pal); +/* texus.h */ + /****************************************************************************\ * logging * \****************************************************************************/ #if DEBUG_TRAP -#define TRAP_LOG trap_printf +#define TRAP_LOG trp_printf #ifdef __GNUC__ __attribute__ ((format(printf, 1, 2))) #endif /* __GNUC__ */ -int trap_printf (const char *format, ...) +int trp_printf (const char *format, ...) { va_list arg; int n; @@ -232,8 +240,10 @@ const char *TRP_BLEND (GrAlphaBlendFnc_t func) 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_RESERVED_8); - TRAP_CASE_STRING(GR_BLEND_RESERVED_9); + 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); @@ -731,8 +741,6 @@ const char *TRP_BLENDOP (GrAlphaBlendOp_t op) TRAP_CASE_STRING(GR_BLEND_OP_ADD); TRAP_CASE_STRING(GR_BLEND_OP_SUB); TRAP_CASE_STRING(GR_BLEND_OP_REVSUB); - TRAP_CASE_STRING(GR_BLEND_SAME_COLOR_EXT); - TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SAME_COLOR_EXT); TRAP_NODEFAULT; } } @@ -783,6 +791,25 @@ const char *TRP_TMU (GrChipID_t tmu) } } +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; + } +} + /****************************************************************************\ @@ -799,6 +826,11 @@ void (FX_CALL *real_grChromaRangeExt) (GrColor_t color, GrColor_t range, GrChrom 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); @@ -1857,6 +1889,41 @@ void FX_CALL trap_grTexChromaRangeExt (GrChipID_t tmu, #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, @@ -2087,19 +2154,87 @@ void FX_CALL trap_grTBufferWriteMaskExt (FxU32 tmask) (*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)); + 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)); + 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); + txPalToNcc(ncc_table, pal); +#undef FN_NAME +} #endif /****************************************************************************\ +* housekeeping (fake pointers) +\****************************************************************************/ +void FX_CALL fake_grTexDownloadTableExt (GrChipID_t tmu, + GrTexTable_t type, + void *data) +{ + grTexDownloadTable(type, data); +} + +void FX_CALL fake_grTexDownloadTablePartialExt (GrChipID_t tmu, + GrTexTable_t type, + void *data, + int start, + int end) +{ + grTexDownloadTablePartial(type, data, start, end); +} + +void FX_CALL fake_grTexNCCTableExt (GrChipID_t tmu, + GrNCCTable_t table) +{ + grTexNCCTable(table); +} + + + +/****************************************************************************\ * interface \****************************************************************************/ void tdfx_hook_glide (struct tdfx_glide *Glide) { #if DEBUG_TRAP -#define GET_EXT_ADDR(name) *(GrProc *)&real_##name = grGetProcAddress(#name), Glide->name = trap_##name +#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_TXS_ADDR(name) Glide->name = trap_##name #else /* DEBUG_TRAP */ -#define GET_EXT_ADDR(name) *(GrProc *)&Glide->name = grGetProcAddress(#name) +#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_TXS_ADDR(name) Glide->name = name #endif /* DEBUG_TRAP */ /* @@ -2111,6 +2246,10 @@ void tdfx_hook_glide (struct tdfx_glide *Glide) GET_EXT_ADDR(grChromaRangeExt); GET_EXT_ADDR(grTexChromaModeExt); GET_EXT_ADDR(grTexChromaRangeExt); + /* pointcast */ + GET_EXT_FAKE(grTexDownloadTableExt); + GET_EXT_FAKE(grTexDownloadTablePartialExt); + GET_EXT_FAKE(grTexNCCTableExt); /* tbext */ GET_EXT_ADDR(grTextureBufferExt); GET_EXT_ADDR(grTextureAuxBufferExt); @@ -2131,5 +2270,14 @@ void tdfx_hook_glide (struct tdfx_glide *Glide) GET_EXT_ADDR(grAlphaBlendFunctionExt); GET_EXT_ADDR(grTBufferWriteMaskExt); + /* + ** texus + */ + GET_TXS_ADDR(txImgQuantize); + GET_TXS_ADDR(txMipQuantize); + GET_TXS_ADDR(txPalToNcc); + #undef GET_EXT_ADDR } + +#endif /* FX */ diff --git a/src/mesa/drivers/glide/fxg.h b/src/mesa/drivers/glide/fxg.h index 234e52aee8c..2841bab16cb 100644 --- a/src/mesa/drivers/glide/fxg.h +++ b/src/mesa/drivers/glide/fxg.h @@ -307,6 +307,30 @@ void FX_CALL trap_guFogGenerateLinear (GrFog_t *fogtable, float nearZ, float far #endif /* DEBUG_TRAP_internal */ #endif /* DEBUG_TRAP */ + + +/* <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; +typedef void (*TxErrorCallbackFnc_t) (const char *string, FxBool fatal); +#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 @@ -318,6 +342,11 @@ struct tdfx_glide { 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); @@ -342,9 +371,9 @@ struct tdfx_glide { /* ** Texus2 functions */ - void (*txImgQuantize) (void *xxx_unknown_arguments); - void (*txImgDequantizeFXT1) (void *txMip, void *pxMip); - void (*txErrorSetCallback) (void *fnc); + 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); diff --git a/src/mesa/drivers/glide/fxglidew.c b/src/mesa/drivers/glide/fxglidew.c index 6e89f00ed83..76df0286937 100644 --- a/src/mesa/drivers/glide/fxglidew.c +++ b/src/mesa/drivers/glide/fxglidew.c @@ -1,5 +1,3 @@ -/* $Id: fxglidew.c,v 1.22 2003/10/02 17:36:44 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -196,7 +194,9 @@ FX_grSstQueryHardware(GrHwConfiguration * config) grSstSelect(i); extension = grGetString(GR_HARDWARE); - if (strstr(extension, "Voodoo Banshee")) { + 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; @@ -204,12 +204,12 @@ FX_grSstQueryHardware(GrHwConfiguration * config) config->SSTs[i].type = GR_SSTTYPE_Voodoo4; } else if (strstr(extension, "Voodoo5")) { config->SSTs[i].type = GR_SSTTYPE_Voodoo5; - } else { /* Voodoo1,2,rush */ - /* ZZZ TO DO */ + } else { /* Voodoo1,rush */ + /* ZZZ TO DO: Need to distinguish whether we have V1 or Rush. */ config->SSTs[i].type = GR_SSTTYPE_VOODOO; } - grGet(GR_MEMORY_FB, 4, &result); + grGet(GR_MEMORY_FB, 4, &result); /* ZZZ: differs after grSstWinOpen */ config->SSTs[i].fbRam = result / (1024 * 1024); grGet(GR_NUM_TMU, 4, &result); @@ -219,25 +219,25 @@ FX_grSstQueryHardware(GrHwConfiguration * config) config->SSTs[i].fbiRev = result; for (j = 0; j < config->SSTs[i].nTexelfx; j++) { - grGet(GR_MEMORY_TMU, 4, &result); + grGet(GR_MEMORY_TMU, 4, &result); /* ZZZ: differs after grSstWinOpen */ 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); config->SSTs[i].HaveTexus2 = GL_FALSE; - /* need to get the number of SLI units for napalm */ + /* number of Voodoo chips */ grGet(GR_NUM_FB, 4, (void *) &numFB); config->SSTs[i].numChips = numFB; - /* this can only be useful for Voodoo2: - * sliDetect = ((config->SSTs[i].type == GR_SSTTYPE_Voodoo2) && (numFB > 1)); - */ + } tdfx_hook_glide(&config->Glide); diff --git a/src/mesa/drivers/glide/fxglidew.h b/src/mesa/drivers/glide/fxglidew.h index f6177e4ff58..31a8fa3b02e 100644 --- a/src/mesa/drivers/glide/fxglidew.h +++ b/src/mesa/drivers/glide/fxglidew.h @@ -1,5 +1,3 @@ -/* $Id: fxglidew.h,v 1.16 2003/10/02 17:36:44 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -71,13 +69,15 @@ typedef struct { 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 [koolsmoky] */ + 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 */ FxBool HaveTexus2; /* Texus 2 - FXT1 */ } SSTs[MAX_NUM_SST]; /* configuration for each board */ @@ -216,12 +216,4 @@ extern FxBool FX_grSstControl(FxU32 code); -#if FX_DEBUG -extern int TDFX_DEBUG; -#else -#define TDFX_DEBUG 0 -#endif - - - #endif /* __FX_GLIDE_WARPER__ */ diff --git a/src/mesa/drivers/glide/fxopengl.def b/src/mesa/drivers/glide/fxopengl.def index 9d0d3eb5012..897905b4b40 100644 --- a/src/mesa/drivers/glide/fxopengl.def +++ b/src/mesa/drivers/glide/fxopengl.def @@ -1,3 +1,5 @@ +LIBRARY OpenGL32 +DESCRIPTION "Mesa 5.1" EXPORTS glAccum glActiveStencilFaceEXT diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c index 9ebc603ae7a..22c34cecaf3 100644 --- a/src/mesa/drivers/glide/fxsetup.c +++ b/src/mesa/drivers/glide/fxsetup.c @@ -1,5 +1,3 @@ -/* $Id: fxsetup.c,v 1.40 2003/10/02 17:36:44 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -79,19 +77,13 @@ fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj) else FX_smallLodLog2(ti->info) = FX_largeLodLog2(ti->info); -/*jejeje*/ -ti->baseLevelInternalFormat = tObj->Image[minl]->Format; -#if 0 - fxTexGetFormat(ctx, tObj->Image[minl]->TexFormat->BaseFormat, &(ti->info.format), - &(ti->baseLevelInternalFormat)); /* [koolsmoky] */ -#endif + ti->baseLevelInternalFormat = tObj->Image[minl]->Format; switch (tObj->WrapS) { case GL_MIRRORED_REPEAT: ti->sClamp = GR_TEXTURECLAMP_MIRROR_EXT; break; - case GL_CLAMP_TO_EDGE: - /* What's this really mean compared to GL_CLAMP? */ + case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */ case GL_CLAMP: ti->sClamp = GR_TEXTURECLAMP_CLAMP; break; @@ -105,8 +97,7 @@ ti->baseLevelInternalFormat = tObj->Image[minl]->Format; case GL_MIRRORED_REPEAT: ti->tClamp = GR_TEXTURECLAMP_MIRROR_EXT; break; - case GL_CLAMP_TO_EDGE: - /* What's this really mean compared to GL_CLAMP? */ + case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */ case GL_CLAMP: ti->tClamp = GR_TEXTURECLAMP_CLAMP; break; @@ -301,6 +292,10 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) fprintf(stderr, "%s(%p (%d))\n", __FUNCTION__, (void *)tObj, tObj->Name); } +#if 1 /* [dBorca] Good... bad... I'm the guy with the gun! */ + ti->lastTimeUsed = fxMesa->texBindNumber; +#endif + /* Make sure we're not loaded incorrectly */ if (ti->isInTM) { if (ti->LODblend) { @@ -318,13 +313,8 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) if (ti->LODblend) fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU_SPLIT); else { - /* XXX putting textures into the second memory bank when the - * first bank is full is not working at this time. - */ - if (/*[dBorca]: fixme*/0 && fxMesa->haveTwoTMUs) { - if (fxMesa->freeTexMem[FX_TMU0] > - grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, - &(ti->info))) { + if (fxMesa->haveTwoTMUs) { + if (fxTMCheckStartAddr(fxMesa, FX_TMU0, ti)) { fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0); } else { @@ -337,13 +327,23 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) } 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, "%s: uploading texture palette\n", __FUNCTION__); } - grTexDownloadTable(GR_TEXTABLE_PALETTE, &(ti->palette)); + grTexDownloadTable(ti->paltype, &(ti->palette)); } +#if FX_TC_NCC + if ((ti->info.format == GR_TEXFMT_AYIQ_8422) || + (ti->info.format == GR_TEXFMT_YIQ_422)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading NCC table\n", __FUNCTION__); + } + grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette)); + } +#endif grTexClampMode(GR_TMU0, ti->sClamp, ti->tClamp); grTexClampMode(GR_TMU1, ti->sClamp, ti->tClamp); @@ -363,13 +363,23 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) else tmu = ti->whichTMU; + /* pointcast */ if ((ti->info.format == GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) { if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "%s: uploading texture palette\n", __FUNCTION__); } - grTexDownloadTable(GR_TEXTABLE_PALETTE, &(ti->palette)); + fxMesa->Glide.grTexDownloadTableExt(tmu, ti->paltype, &(ti->palette)); + } +#if FX_TC_NCC + if ((ti->info.format == GR_TEXFMT_AYIQ_8422) || + (ti->info.format == GR_TEXFMT_YIQ_422)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading NCC table\n", __FUNCTION__); + } + fxMesa->Glide.grTexDownloadTableExt(tmu, GR_TEXTABLE_NCC0, &(ti->palette)); } +#endif /* 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 @@ -390,66 +400,86 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) static void fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend) { + struct tdfx_texcombine tex0, tex1; + if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "%s(%d, %d)\n", __FUNCTION__, tmu, LODblend); } + tex0.InvertRGB = FXFALSE; + tex0.InvertAlpha = FXFALSE; + tex1.InvertRGB = FXFALSE; + tex1.InvertAlpha = FXFALSE; + if (LODblend) { - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_BLEND, - GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION, - GR_COMBINE_FUNCTION_BLEND, - GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION, - FXFALSE, FXFALSE); - - if (fxMesa->haveTwoTMUs) - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); + 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) { - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); - if (fxMesa->haveTwoTMUs) { - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_ZERO, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_ZERO, - GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); - } + 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 { - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); - - /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */ - - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_BLEND, - GR_COMBINE_FACTOR_ONE, - GR_COMBINE_FUNCTION_BLEND, - GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE); + tex1.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorRGB = GR_COMBINE_FACTOR_NONE; + tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; + + /* [dBorca] Hack alert: + * don't use GR_COMBINE_FUNCTION_SCALE_OTHER + * such that Glide recognizes 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; @@ -503,59 +533,154 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset) fprintf(stderr, "%s: envmode is %s\n", __FUNCTION__, _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: - grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - locala, GR_COMBINE_OTHER_NONE, FXFALSE); + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; - grColorCombine(GR_COMBINE_FUNCTION_BLEND, - GR_COMBINE_FACTOR_TEXTURE_ALPHA, - localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + colorComb.Function = GR_COMBINE_FUNCTION_BLEND; + colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; break; case GL_MODULATE: - grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_LOCAL, - locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE); - - if (ifmt == GL_ALPHA) - grColorCombine(GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - localc, GR_COMBINE_OTHER_NONE, FXFALSE); - else - grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_LOCAL, - localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + 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 (TDFX_DEBUG & VERBOSE_DRIVER) - fprintf(stderr, "%s: GL_BLEND not yet supported\n", __FUNCTION__); + 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 { + /* [dBorca] Hack alert: + * only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB) + */ + 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 { + _mesa_problem(NULL, "can't GL_BLEND with SST1"); + return; + } + } + + 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)) - grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - locala, GR_COMBINE_OTHER_NONE, FXFALSE); - else - grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_ONE, - locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE); - - if (ifmt == GL_ALPHA) - grColorCombine(GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - localc, GR_COMBINE_OTHER_NONE, FXFALSE); - else - grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_ONE, - localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + 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) + if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "%s: %x Texture.EnvMode not yet supported\n", __FUNCTION__, ctx->Texture.Unit[textureset].EnvMode); - break; + } + 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 @@ -678,18 +803,42 @@ fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa, } } + /* [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) { - /* [dBorca] - * all TMUs share the same table. - * The next test shouldn't be TMU specific... - */ + /* pointcast */ + if (ti1->info.format == GR_TEXFMT_P_8) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading texture palette for TMU1\n", __FUNCTION__); + } + fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, ti1->paltype, &(ti1->palette)); + } if (ti0->info.format == GR_TEXFMT_P_8) { if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s: uploading texture palette TMU0\n", __FUNCTION__); + fprintf(stderr, "%s: uploading texture palette for TMU0\n", __FUNCTION__); } - grTexDownloadTable(GR_TEXTABLE_PALETTE, &(ti0->palette)); + fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, ti0->paltype, &(ti0->palette)); + } + } +#if FX_TC_NCC + /* pointcast */ + if ((ti1->info.format == GR_TEXFMT_AYIQ_8422) || + (ti1->info.format == GR_TEXFMT_YIQ_422)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading NCC0 table for TMU1\n", __FUNCTION__); } + fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, GR_TEXTABLE_NCC0, &(ti1->palette)); } + if ((ti0->info.format == GR_TEXFMT_AYIQ_8422) || + (ti0->info.format == GR_TEXFMT_YIQ_422)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading NCC0 table for TMU0\n", __FUNCTION__); + } + fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, GR_TEXTABLE_NCC0, &(ti0->palette)); + } +#endif grTexSource(tmu0, ti0->tm[tmu0]->startAddr, GR_MIPMAPLEVELMASK_BOTH, &(ti0->info)); @@ -715,6 +864,8 @@ 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[0].Current2D; @@ -769,6 +920,16 @@ fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx) 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): { @@ -777,120 +938,111 @@ fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx) isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA); isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA); - if (isalpha[FX_TMU1]) - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_ZERO, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE); - else - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); - - if (isalpha[FX_TMU0]) - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_ONE, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE); - else - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_LOCAL, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE); - - grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_LOCAL, - localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); - - grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_LOCAL, - locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + 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 (tmu1 == FX_TMU1) { - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE); - - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_LOCAL, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE); + 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 { - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); - - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, - FXFALSE, FXFALSE); + 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; } - grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - locala, GR_COMBINE_OTHER_NONE, FXFALSE); + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; - grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_ONE, - localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + 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) { - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_ZERO, - GR_COMBINE_FACTOR_NONE, FXFALSE, FXTRUE); - - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_LOCAL, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE); - + 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 { - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); - - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_LOCAL, - GR_COMBINE_FUNCTION_BLEND_OTHER, - GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE); + 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) - grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - locala, GR_COMBINE_OTHER_NONE, FXFALSE); - else - grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_ONE, - locala, GR_COMBINE_OTHER_NONE, FXFALSE); - + 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; + } - grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_ONE, - localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; break; @@ -901,45 +1053,69 @@ fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx) isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA); isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA); - if (isalpha[FX_TMU1]) - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_ZERO, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE); - else - grTexCombine(GR_TMU1, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); - - if (isalpha[FX_TMU0]) - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_ONE, - GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, - GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE); - else - grTexCombine(GR_TMU0, - GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, - GR_COMBINE_FACTOR_ONE, - GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, - GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE); - - grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_LOCAL, - localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE); - - grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, - GR_COMBINE_FACTOR_LOCAL, - locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE); + 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; } default: fprintf(stderr, "%s: Unexpected dual texture mode encountered\n", __FUNCTION__); - break; + 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 ***************************/ @@ -967,16 +1143,22 @@ fxSetupTextureNone_NoLock(GLcontext * ctx) localc = GR_COMBINE_LOCAL_CONSTANT; grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL, - GR_COMBINE_FACTOR_NONE, - locala, GR_COMBINE_OTHER_NONE, FXFALSE); + 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); + GR_COMBINE_FACTOR_NONE, + localc, + GR_COMBINE_OTHER_NONE, + FXFALSE); fxMesa->lastUnitsMode = FX_UM_NONE; } +#include "fxsetup.h" + /************************************************************************/ /************************** Texture Mode SetUp **************************/ /************************************************************************/ @@ -990,20 +1172,38 @@ fxSetupTexture_NoLock(GLcontext * ctx) fprintf(stderr, "%s(...)\n", __FUNCTION__); } - /* Texture Combine, Color Combine and Alpha Combine. */ - if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && - ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT && - fxMesa->haveTwoTMUs) { - fxSetupTextureDoubleTMU_NoLock(ctx); - } - else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) { - fxSetupTextureSingleTMU_NoLock(ctx, 0); - } - else if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) { - fxSetupTextureSingleTMU_NoLock(ctx, 1); - } - else { - fxSetupTextureNone_NoLock(ctx); + if (fxMesa->HaveCmbExt) { + /* Texture Combine, Color Combine and Alpha Combine. */ + if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && + ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT && + fxMesa->haveTwoTMUs) { + fxSetupTextureDoubleTMUNapalm_NoLock(ctx); + } + else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) { + fxSetupTextureSingleTMUNapalm_NoLock(ctx, 0); + } + else if (ctx->Texture.Unit[1]._ReallyEnabled == 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_2D_BIT && + ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT && + fxMesa->haveTwoTMUs) { + fxSetupTextureDoubleTMU_NoLock(ctx); + } + else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) { + fxSetupTextureSingleTMU_NoLock(ctx, 0); + } + else if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) { + fxSetupTextureSingleTMU_NoLock(ctx, 1); + } + else { + fxSetupTextureNone_NoLock(ctx); + } } } @@ -1019,117 +1219,211 @@ fxSetupTexture(GLcontext * ctx) /**************************** Blend SetUp *******************************/ /************************************************************************/ -/* XXX consider supporting GL_INGR_blend_func_separate */ void -fxDDBlendFunc(GLcontext * ctx, GLenum sfactor, GLenum dfactor) +fxDDBlendFuncSeparate(GLcontext * ctx, GLenum sfactor, GLenum dfactor, GLenum asfactor, GLenum adfactor) { fxMesaContext fxMesa = FX_CONTEXT(ctx); tfxUnitsState *us = &fxMesa->unitsState; + GLboolean have32bpp = (fxMesa->colDepth == 32); + GLboolean haveAlpha = fxMesa->haveHwAlpha; GrAlphaBlendFnc_t sfact, dfact, asfact, adfact; - /* From the Glide documentation: - For alpha source and destination blend function factor - parameters, Voodoo Graphics supports only - GR_BLEND_ZERO and GR_BLEND_ONE. + /* [dBorca] Hack alert: + * We should condition *DST_ALPHA* modes + * by the boolean `haveAlpha' above! + * It indicates whether we really have HW alpha buffer... */ +/* +When the value A_COLOR is selected as the destination alpha blending factor, +the source pixel color is used as the destination blending factor. When the +value A_COLOR is selected as the source alpha blending factor, the destination +pixel color is used as the source blending factor. When the value A_SAMECOLOR +is selected as the destination alpha blending factor, the destination pixel +color is used as the destination blending factor. When the value A_SAMECOLOR +is selected as the source alpha blending factor, the source pixel color is +used as the source blending factor. Note also that the alpha blending +function 0xf (A_COLORBEFOREFOG/ASATURATE) is different depending upon whether +it is being used as a source or destination alpha blending function. When the +value 0xf is selected as the destination alpha blending factor, the source +color before the fog unit ("unfogged" color) is used as the destination +blending factor -- this alpha blending function is useful for multi-pass +rendering with atmospheric effects. When the value 0xf is selected as the +source alpha blending factor, the alpha-saturate anti-aliasing algorithm is +selected -- this MIN function performs polygonal anti-aliasing for polygons +which are drawn front-to-back. + +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 +*/ + switch (sfactor) { case GL_ZERO: - asfact = sfact = GR_BLEND_ZERO; + sfact = GR_BLEND_ZERO; break; case GL_ONE: - asfact = sfact = GR_BLEND_ONE; + sfact = GR_BLEND_ONE; break; case GL_DST_COLOR: sfact = GR_BLEND_DST_COLOR; - asfact = GR_BLEND_ONE; break; case GL_ONE_MINUS_DST_COLOR: sfact = GR_BLEND_ONE_MINUS_DST_COLOR; - asfact = GR_BLEND_ONE; break; case GL_SRC_ALPHA: sfact = GR_BLEND_SRC_ALPHA; - asfact = GR_BLEND_ONE; break; case GL_ONE_MINUS_SRC_ALPHA: sfact = GR_BLEND_ONE_MINUS_SRC_ALPHA; - asfact = GR_BLEND_ONE; break; case GL_DST_ALPHA: sfact = GR_BLEND_DST_ALPHA; - asfact = GR_BLEND_ONE; break; case GL_ONE_MINUS_DST_ALPHA: sfact = GR_BLEND_ONE_MINUS_DST_ALPHA; - asfact = GR_BLEND_ONE; break; case GL_SRC_ALPHA_SATURATE: sfact = GR_BLEND_ALPHA_SATURATE; - asfact = GR_BLEND_ONE; break; case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: /* USELESS */ - asfact = sfact = GR_BLEND_ONE; + sfact = GR_BLEND_ONE; break; default: - asfact = sfact = GR_BLEND_ONE; + sfact = GR_BLEND_ONE; break; } - if ((sfact != us->blendSrcFuncRGB) || (asfact != us->blendSrcFuncAlpha)) { - us->blendSrcFuncRGB = sfact; - us->blendSrcFuncAlpha = asfact; - fxMesa->new_state |= FX_NEW_BLEND; + switch (asfactor) { + case GL_ZERO: + asfact = GR_BLEND_ZERO; + break; + case GL_ONE: + asfact = GR_BLEND_ONE; + break; + case GL_DST_COLOR: + asfact = GR_BLEND_ONE/*bad*/; + break; + case GL_ONE_MINUS_DST_COLOR: + asfact = GR_BLEND_ONE/*bad*/; + break; + case GL_SRC_ALPHA: + asfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_ONE_MINUS_SRC_ALPHA: + asfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_DST_ALPHA: + asfact = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_ONE_MINUS_DST_ALPHA: + asfact = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ONE/*bad*/; + break; + case GL_SRC_ALPHA_SATURATE: + asfact = GR_BLEND_ONE/*bad*/; + break; + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + /* USELESS */ + asfact = GR_BLEND_ONE/*bad*/; + break; + default: + asfact = GR_BLEND_ONE/*bad*/; + break; } switch (dfactor) { case GL_ZERO: - adfact = dfact = GR_BLEND_ZERO; + dfact = GR_BLEND_ZERO; break; case GL_ONE: - adfact = dfact = GR_BLEND_ONE; + dfact = GR_BLEND_ONE; break; case GL_SRC_COLOR: dfact = GR_BLEND_SRC_COLOR; - adfact = GR_BLEND_ZERO; break; case GL_ONE_MINUS_SRC_COLOR: dfact = GR_BLEND_ONE_MINUS_SRC_COLOR; - adfact = GR_BLEND_ZERO; break; case GL_SRC_ALPHA: dfact = GR_BLEND_SRC_ALPHA; - adfact = GR_BLEND_ZERO; break; case GL_ONE_MINUS_SRC_ALPHA: dfact = GR_BLEND_ONE_MINUS_SRC_ALPHA; - adfact = GR_BLEND_ZERO; break; case GL_DST_ALPHA: /* dfact=GR_BLEND_DST_ALPHA; */ /* We can't do DST_ALPHA */ dfact = GR_BLEND_ONE; - adfact = GR_BLEND_ZERO; break; case GL_ONE_MINUS_DST_ALPHA: /* dfact=GR_BLEND_ONE_MINUS_DST_ALPHA; */ /* We can't do DST_ALPHA */ dfact = GR_BLEND_ZERO; + break; + case GL_SRC_ALPHA_SATURATE: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + /* USELESS */ + dfact = GR_BLEND_ZERO; + 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: + adfact = GR_BLEND_ZERO/*bad*/; + break; + case GL_ONE_MINUS_SRC_COLOR: + adfact = GR_BLEND_ZERO/*bad*/; + break; + case GL_SRC_ALPHA: + adfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*bad*/; + break; + case GL_ONE_MINUS_SRC_ALPHA: + adfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*bad*/; + break; + case GL_DST_ALPHA: + adfact = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ZERO/*bad*/; + break; + case GL_ONE_MINUS_DST_ALPHA: + adfact = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/; + break; case GL_SRC_ALPHA_SATURATE: case GL_DST_COLOR: case GL_ONE_MINUS_DST_COLOR: /* USELESS */ - adfact = dfact = GR_BLEND_ZERO; + adfact = GR_BLEND_ZERO/*bad*/; break; default: - adfact = dfact = GR_BLEND_ZERO; + adfact = GR_BLEND_ZERO/*bad*/; 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; @@ -1137,18 +1431,66 @@ fxDDBlendFunc(GLcontext * ctx, GLenum sfactor, GLenum dfactor) } } +void +fxDDBlendFunc(GLcontext * ctx, GLenum sfactor, GLenum dfactor) +{ + fxDDBlendFuncSeparate(ctx, sfactor, dfactor, sfactor, dfactor); +} + +void +fxDDBlendEquation(GLcontext * ctx, GLenum mode) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + GrAlphaBlendOp_t q; + + switch (mode) { + case GL_FUNC_ADD_EXT: + q = GR_BLEND_OP_ADD; + break; + case GL_FUNC_SUBTRACT_EXT: + q = GR_BLEND_OP_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT_EXT: + q = GR_BLEND_OP_REVSUB; + break; + default: + return; + } + + if ((q != us->blendEq) && fxMesa->HavePixExt) { + us->blendEq = q; + fxMesa->new_state |= FX_NEW_BLEND; + } +} + static void fxSetupBlend(GLcontext * ctx) { - fxMesaContext fxMesa = FX_CONTEXT(ctx); - tfxUnitsState *us = &fxMesa->unitsState; - - 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); + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; + + if (fxMesa->HavePixExt) { + if (us->blendEnabled) { + fxMesa->Glide.grAlphaBlendFunctionExt(us->blendSrcFuncRGB, us->blendDstFuncRGB, + us->blendEq, + us->blendSrcFuncAlpha, us->blendDstFuncAlpha, + us->blendEq); + } 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); + } + } } /************************************************************************/ @@ -1336,25 +1678,6 @@ fxSetupStencil (GLcontext * ctx) /**************************** Color Mask SetUp **************************/ /************************************************************************/ -void fxColorMask (fxMesaContext fxMesa, GLboolean enable) -{ -/* These are used in calls to FX_grColorMask() */ -static const FxBool false4[4] = { FXFALSE, FXFALSE, FXFALSE, FXFALSE }; -static const FxBool true4[4] = { FXTRUE, FXTRUE, FXTRUE, FXTRUE }; - - const FxBool *rgba = enable ? true4 : false4; - - if (fxMesa->colDepth != 16) { - /* 32bpp mode or 15bpp mode */ - fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP], - rgba[BCOMP], rgba[ACOMP] && fxMesa->haveHwAlpha); - } - else { - /* 16 bpp mode */ - grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP], rgba[ACOMP] && fxMesa->haveHwAlpha); - } -} - void fxDDColorMask(GLcontext * ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a) @@ -1367,16 +1690,24 @@ fxDDColorMask(GLcontext * ctx, (void) a; } -static void +void fxSetupColorMask(GLcontext * ctx) { fxMesaContext fxMesa = FX_CONTEXT(ctx); - if (ctx->Color.DrawBuffer == GL_NONE) { - fxColorMask(fxMesa, GL_FALSE); + if (fxMesa->colDepth != 16) { + /* 32bpp mode or 15bpp mode */ + fxMesa->Glide.grColorMaskExt(ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha); } else { - fxColorMask(fxMesa, GL_TRUE); + /* 16 bpp mode */ + grColorMask(ctx->Color.ColorMask[RCOMP] | + ctx->Color.ColorMask[GCOMP] | + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha); } } @@ -1453,30 +1784,34 @@ fxSetScissorValues(GLcontext * ctx) { fxMesaContext fxMesa = FX_CONTEXT(ctx); int xmin, xmax; - int ymin, ymax, check; + 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; - check = 1; + + 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; - check = 0; } - if (xmin < fxMesa->clipMinX) - xmin = fxMesa->clipMinX; - if (xmax > fxMesa->clipMaxX) - xmax = fxMesa->clipMaxX; - if (ymin < fxMesa->screen_height - fxMesa->clipMaxY) - ymin = fxMesa->screen_height - fxMesa->clipMaxY; - if (ymax > fxMesa->screen_height - fxMesa->clipMinY) - ymax = fxMesa->screen_height - fxMesa->clipMinY; + + fxMesa->clipMinX = xmin; + fxMesa->clipMinY = ymin; + fxMesa->clipMaxX = xmax; + fxMesa->clipMaxY = ymax; grClipWindow(xmin, ymin, xmax, ymax); } diff --git a/src/mesa/drivers/glide/fxsetup.h b/src/mesa/drivers/glide/fxsetup.h new file mode 100644 index 00000000000..9f028fb999e --- /dev/null +++ b/src/mesa/drivers/glide/fxsetup.h @@ -0,0 +1,1131 @@ +/* + * 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 */ +/* [dBorca] Hack alert: + * 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->Current2D; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s(...)\n", __FUNCTION__); + } + + 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: + /* [dBorca] Hack alert: + * INCOMPLETE!!! + */ + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) { + fprintf(stderr, "COMBINE_EXT: %s + %s\n", + _mesa_lookup_enum_by_nr(texUnit->CombineModeRGB), + _mesa_lookup_enum_by_nr(texUnit->CombineModeA)); + } + + alphaComb.Shift = texUnit->CombineScaleShiftA; + colorComb.Shift = texUnit->CombineScaleShiftRGB; + + switch (texUnit->CombineModeRGB) { + case GL_MODULATE: + /* Arg0 * Arg1 == (A + 0) * C + 0 */ + TEXENV_SETUP_ARG_RGB(colorComb.SourceA, + texUnit->CombineSourceRGB[0], + texUnit->CombineOperandRGB[0], + localc, locala); + TEXENV_SETUP_MODE_RGB(colorComb.ModeA, + texUnit->CombineOperandRGB[0]); + colorComb.SourceB = GR_CMBX_ZERO; + colorComb.ModeB = GR_FUNC_MODE_ZERO; + TEXENV_SETUP_ARG_RGB(colorComb.SourceC, + texUnit->CombineSourceRGB[1], + texUnit->CombineOperandRGB[1], + localc, locala); + colorComb.InvertC = TEXENV_OPERAND_INVERTED( + texUnit->CombineOperandRGB[1]); + colorComb.SourceD = GR_CMBX_ZERO; + break; + default: + fprintf(stderr, "COMBINE_EXT_color: %s\n", + _mesa_lookup_enum_by_nr(texUnit->CombineModeRGB)); + } + + switch (texUnit->CombineModeA) { + case GL_MODULATE: + /* Arg0 * Arg1 == (A + 0) * C + 0 */ + TEXENV_SETUP_ARG_A(alphaComb.SourceA, + texUnit->CombineSourceA[0], + texUnit->CombineOperandA[0], + locala); + TEXENV_SETUP_MODE_A(alphaComb.ModeA, + texUnit->CombineOperandA[0]); + alphaComb.SourceB = GR_CMBX_ZERO; + alphaComb.ModeB = GR_FUNC_MODE_ZERO; + TEXENV_SETUP_ARG_A(alphaComb.SourceC, + texUnit->CombineSourceA[1], + texUnit->CombineOperandA[1], + locala); + alphaComb.InvertC = TEXENV_OPERAND_INVERTED( + texUnit->CombineOperandA[1]); + alphaComb.SourceD = GR_CMBX_ZERO; + break; + default: + fprintf(stderr, "COMBINE_EXT_alpha: %s\n", + _mesa_lookup_enum_by_nr(texUnit->CombineModeA)); + } + + 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; +#if 0 + { + FxU32 A_RGB, B_RGB, C_RGB, D_RGB; + FxU32 Amode_RGB, Bmode_RGB; + FxBool Cinv_RGB, Dinv_RGB, Ginv_RGB; + FxU32 Shift_RGB; + FxU32 A_A, B_A, C_A, D_A; + FxU32 Amode_A, Bmode_A; + FxBool Cinv_A, Dinv_A, Ginv_A; + FxU32 Shift_A; + + /* + * + * In the formulas below, we write: + * o "1(x)" for the identity function applied to x, + * so 1(x) = x. + * o "0(x)" for the constant function 0, so + * 0(x) = 0 for all values of x. + * + * Calculate the color combination. + */ + Shift_RGB = texUnit->CombineScaleShiftRGB; + Shift_A = texUnit->CombineScaleShiftA; + switch (texUnit->CombineModeRGB) { + case GL_REPLACE: + /* + * The formula is: Arg0 + * We implement this by the formula: + * (Arg0 + 0(0))*(1-0) + 0 + */ + TEXENV_SETUP_ARG_RGB(A_RGB, + texUnit->CombineSourceRGB[0], + texUnit->CombineOperandRGB[0], + incomingRGB, incomingAlpha); + TEXENV_SETUP_MODE_RGB(Amode_RGB, + texUnit->CombineOperandRGB[0]); + B_RGB = C_RGB = D_RGB = GR_CMBX_ZERO; + Bmode_RGB = GR_FUNC_MODE_ZERO; + Cinv_RGB = FXTRUE; + Dinv_RGB = Ginv_RGB = FXFALSE; + break; + case GL_MODULATE: + /* + * The formula is: Arg0 * Arg1 + * + * We implement this by the formula + * (Arg0 + 0(0)) * Arg1 + 0(0) + */ + TEXENV_SETUP_ARG_RGB(A_RGB, + texUnit->CombineSourceRGB[0], + texUnit->CombineOperandRGB[0], + incomingRGB, incomingAlpha); + TEXENV_SETUP_MODE_RGB(Amode_RGB, + texUnit->CombineOperandRGB[0]); + B_RGB = GR_CMBX_ZERO; + Bmode_RGB = GR_CMBX_ZERO; + TEXENV_SETUP_ARG_RGB(C_RGB, + texUnit->CombineSourceRGB[1], + texUnit->CombineOperandRGB[1], + incomingRGB, incomingAlpha); + Cinv_RGB = TEXENV_OPERAND_INVERTED + (texUnit->CombineOperandRGB[1]); + D_RGB = GR_CMBX_ZERO; + Dinv_RGB = Ginv_RGB = FXFALSE; + break; + case GL_ADD: + /* + * The formula is Arg0 + Arg1 + */ + TEXENV_SETUP_ARG_RGB(A_RGB, + texUnit->CombineSourceRGB[0], + texUnit->CombineOperandRGB[0], + incomingRGB, incomingAlpha); + TEXENV_SETUP_MODE_RGB(Amode_RGB, + texUnit->CombineOperandRGB[0]); + TEXENV_SETUP_ARG_RGB(B_RGB, + texUnit->CombineSourceRGB[1], + texUnit->CombineOperandRGB[1], + incomingRGB, incomingAlpha); + TEXENV_SETUP_MODE_RGB(Bmode_RGB, + texUnit->CombineOperandRGB[1]); + C_RGB = D_RGB = GR_CMBX_ZERO; + Cinv_RGB = FXTRUE; + Dinv_RGB = Ginv_RGB = FXFALSE; + break; + case GL_ADD_SIGNED_EXT: + /* + * The formula is: Arg0 + Arg1 - 0.5. + * We compute this by calculating: + * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA} + * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA} + * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA} + * we cannot implement the formula properly. + */ + TEXENV_SETUP_ARG_RGB(A_RGB, + texUnit->CombineSourceRGB[0], + texUnit->CombineOperandRGB[0], + incomingRGB, incomingAlpha); + TEXENV_SETUP_ARG_RGB(B_RGB, + texUnit->CombineSourceRGB[1], + texUnit->CombineOperandRGB[1], + incomingRGB, incomingAlpha); + if (!TEXENV_OPERAND_INVERTED(texUnit->CombineOperandRGB[0])) { + /* + * A is not inverted. So, choose it. + */ + Amode_RGB = GR_FUNC_MODE_X_MINUS_HALF; + if (!TEXENV_OPERAND_INVERTED + (texUnit->CombineOperandRGB[1])) { + Bmode_RGB = GR_FUNC_MODE_X; + } + else { + Bmode_RGB = GR_FUNC_MODE_ONE_MINUS_X; + } + } + else { + /* + * A is inverted, so try to subtract 1/2 + * from B. + */ + Amode_RGB = GR_FUNC_MODE_ONE_MINUS_X; + if (!TEXENV_OPERAND_INVERTED + (texUnit->CombineOperandRGB[1])) { + Bmode_RGB = GR_FUNC_MODE_X_MINUS_HALF; + } + else { + /* + * Both are inverted. This is the case + * we cannot handle properly. We just + * choose to not add the - 1/2. + */ + Bmode_RGB = GR_FUNC_MODE_ONE_MINUS_X; + return GL_FALSE; + } + } + C_RGB = D_RGB = GR_CMBX_ZERO; + Cinv_RGB = FXTRUE; + Dinv_RGB = Ginv_RGB = FXFALSE; + break; + case GL_INTERPOLATE_EXT: + /* + * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2). + * We compute this by the formula: + * (Arg0 - Arg1) * Arg2 + Arg1 + * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1 + * == Arg0 * Arg2 + Arg1 * (1 - Arg2) + * However, if both Arg1 is ONE_MINUS_X, the HW does + * not support it properly. + */ + TEXENV_SETUP_ARG_RGB(A_RGB, + texUnit->CombineSourceRGB[0], + texUnit->CombineOperandRGB[0], + incomingRGB, incomingAlpha); + TEXENV_SETUP_MODE_RGB(Amode_RGB, + texUnit->CombineOperandRGB[0]); + TEXENV_SETUP_ARG_RGB(B_RGB, + texUnit->CombineSourceRGB[1], + texUnit->CombineOperandRGB[1], + incomingRGB, incomingAlpha); + if (TEXENV_OPERAND_INVERTED(texUnit->CombineOperandRGB[1])) { + /* + * This case is wrong. + */ + Bmode_RGB = GR_FUNC_MODE_NEGATIVE_X; + return GL_FALSE; + } + else { + Bmode_RGB = GR_FUNC_MODE_NEGATIVE_X; + } + /* + * The Source/Operand for the C value must + * specify some kind of alpha value. + */ + TEXENV_SETUP_ARG_A(C_RGB, + texUnit->CombineSourceRGB[2], + texUnit->CombineOperandRGB[2], + incomingAlpha); + Cinv_RGB = FXFALSE; + D_RGB = GR_CMBX_B; + Dinv_RGB = Ginv_RGB = FXFALSE; + break; + default: + /* + * This is here mostly to keep from getting + * a compiler warning about these not being set. + * However, this should set all the texture values + * to zero. + */ + A_RGB = B_RGB = C_RGB = D_RGB = GR_CMBX_ZERO; + Amode_RGB = Bmode_RGB = GR_FUNC_MODE_X; + Cinv_RGB = Dinv_RGB = Ginv_RGB = FXFALSE; + break; + } + /* + * Calculate the alpha combination. + */ + switch (texUnit->CombineModeA) { + case GL_REPLACE: + /* + * The formula is: Arg0 + * We implement this by the formula: + * (Arg0 + 0(0))*(1-0) + 0 + */ + TEXENV_SETUP_ARG_A(A_A, + texUnit->CombineSourceA[0], + texUnit->CombineOperandA[0], + incomingAlpha); + TEXENV_SETUP_MODE_A(Amode_A, + texUnit->CombineOperandA[0]); + B_A = GR_CMBX_ITALPHA; + Bmode_A = GR_FUNC_MODE_ZERO; + C_A = D_A = GR_CMBX_ZERO; + Cinv_A = FXTRUE; + Dinv_A = Ginv_A = FXFALSE; + break; + case GL_MODULATE: + /* + * The formula is: Arg0 * Arg1 + * + * We implement this by the formula + * (Arg0 + 0(0)) * Arg1 + 0(0) + */ + TEXENV_SETUP_ARG_A(A_A, + texUnit->CombineSourceA[0], + texUnit->CombineOperandA[0], + incomingAlpha); + TEXENV_SETUP_MODE_A(Amode_A, + texUnit->CombineOperandA[0]); + B_A = GR_CMBX_ZERO; + Bmode_A = GR_CMBX_ZERO; + TEXENV_SETUP_ARG_A(C_A, + texUnit->CombineSourceA[1], + texUnit->CombineOperandA[1], + incomingAlpha); + Cinv_A = TEXENV_OPERAND_INVERTED + (texUnit->CombineOperandA[1]); + D_A = GR_CMBX_ZERO; + Dinv_A = Ginv_A = FXFALSE; + break; + case GL_ADD: + /* + * The formula is Arg0 + Arg1 + */ + TEXENV_SETUP_ARG_A(A_A, + texUnit->CombineSourceA[0], + texUnit->CombineOperandA[0], + incomingAlpha); + TEXENV_SETUP_MODE_A(Amode_A, + texUnit->CombineOperandA[0]); + TEXENV_SETUP_ARG_A(B_A, + texUnit->CombineSourceA[1], + texUnit->CombineOperandA[1], + incomingAlpha); + TEXENV_SETUP_MODE_A(Bmode_A, + texUnit->CombineOperandA[1]); + C_A = D_A = GR_CMBX_ZERO; + Cinv_A = FXTRUE; + Dinv_A = Ginv_A = FXFALSE; + break; + case GL_ADD_SIGNED_EXT: + /* + * The formula is: Arg0 + Arg1 - 0.5. + * We compute this by calculating: + * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA} + * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA} + * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA} + * we cannot implement the formula properly. + */ + TEXENV_SETUP_ARG_A(A_A, + texUnit->CombineSourceA[0], + texUnit->CombineOperandA[0], + incomingAlpha); + TEXENV_SETUP_ARG_A(B_A, + texUnit->CombineSourceA[1], + texUnit->CombineOperandA[1], + incomingAlpha); + if (!TEXENV_OPERAND_INVERTED(texUnit->CombineOperandA[0])) { + /* + * A is not inverted. So, choose it. + */ + Amode_A = GR_FUNC_MODE_X_MINUS_HALF; + if (!TEXENV_OPERAND_INVERTED + (texUnit->CombineOperandA[1])) { + Bmode_A = GR_FUNC_MODE_X; + } else { + Bmode_A = GR_FUNC_MODE_ONE_MINUS_X; + } + } else { + /* + * A is inverted, so try to subtract 1/2 + * from B. + */ + Amode_A = GR_FUNC_MODE_ONE_MINUS_X; + if (!TEXENV_OPERAND_INVERTED + (texUnit->CombineOperandA[1])) { + Bmode_A = GR_FUNC_MODE_X_MINUS_HALF; + } else { + /* + * Both are inverted. This is the case + * we cannot handle properly. We just + * choose to not add the - 1/2. + */ + Bmode_A = GR_FUNC_MODE_ONE_MINUS_X; + return GL_FALSE; + } + } + C_A = D_A = GR_CMBX_ZERO; + Cinv_A = FXTRUE; + Dinv_A = Ginv_A = FXFALSE; + break; + case GL_INTERPOLATE_EXT: + /* + * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2). + * We compute this by the formula: + * (Arg0 - Arg1) * Arg2 + Arg1 + * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1 + * == Arg0 * Arg2 + Arg1 * (1 - Arg2) + * However, if both Arg1 is ONE_MINUS_X, the HW does + * not support it properly. + */ + TEXENV_SETUP_ARG_A(A_A, + texUnit->CombineSourceA[0], + texUnit->CombineOperandA[0], + incomingAlpha); + TEXENV_SETUP_MODE_A(Amode_A, + texUnit->CombineOperandA[0]); + TEXENV_SETUP_ARG_A(B_A, + texUnit->CombineSourceA[1], + texUnit->CombineOperandA[1], + incomingAlpha); + if (!TEXENV_OPERAND_INVERTED(texUnit->CombineOperandA[1])) { + Bmode_A = GR_FUNC_MODE_NEGATIVE_X; + } + else { + /* + * This case is wrong. + */ + Bmode_A = GR_FUNC_MODE_NEGATIVE_X; + return GL_FALSE; + } + /* + * The Source/Operand for the C value must + * specify some kind of alpha value. + */ + TEXENV_SETUP_ARG_A(C_A, + texUnit->CombineSourceA[2], + texUnit->CombineOperandA[2], + incomingAlpha); + Cinv_A = FXFALSE; + D_A = GR_CMBX_B; + Dinv_A = Ginv_A = FXFALSE; + break; + default: + /* + * This is here mostly to keep from getting + * a compiler warning about these not being set. + * However, this should set all the alpha values + * to one. + */ + A_A = B_A = C_A = D_A = GR_CMBX_ZERO; + Amode_A = Bmode_A = GR_FUNC_MODE_X; + Cinv_A = Dinv_A = FXFALSE; + Ginv_A = FXTRUE; + break; + } + /* + * Save the parameters. + */ + env->Color.SourceA = A_RGB; + env->Color.ModeA = Amode_RGB; + env->Color.SourceB = B_RGB; + env->Color.ModeB = Bmode_RGB; + env->Color.SourceC = C_RGB; + env->Color.InvertC = Cinv_RGB; + env->Color.SourceD = D_RGB; + env->Color.InvertD = Dinv_RGB; + env->Color.Shift = Shift_RGB; + env->Color.Invert = Ginv_RGB; + env->Alpha.SourceA = A_A; + env->Alpha.ModeA = Amode_A; + env->Alpha.SourceB = B_A; + env->Alpha.ModeB = Bmode_A; + env->Alpha.SourceC = C_A; + env->Alpha.InvertC = Cinv_A; + env->Alpha.SourceD = D_A; + env->Alpha.InvertD = Dinv_A; + env->Alpha.Shift = Shift_A; + env->Alpha.Invert = Ginv_A; + env->EnvColor = PACK_RGBA32(texUnit->EnvColor[0] * 255.0F, + texUnit->EnvColor[1] * 255.0F, + texUnit->EnvColor[2] * 255.0F, + texUnit->EnvColor[3] * 255.0F); + } + break; +#endif + default: + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: %x Texture.EnvMode not yet supported\n", __FUNCTION__, + 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, "%s(%d, %d)\n", __FUNCTION__, tmu, LODblend); + } + + if (LODblend) { + /* [dBorca] Hack alert: + * 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 { + grTexCombine(GR_TMU0, + GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_ONE, + FXFALSE, + FXFALSE); + /* + 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); + */ + + 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].Current2D; + int tmu; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s(%d)\n", __FUNCTION__, 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, "%s: envmode is %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode)); + + /* [dBorca] Hack alert: + * what if we're in split mode? (LODBlend) + */ + 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[0].Current2D; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].Current2D; + GLuint unitsmode; + int tmu0 = 0, tmu1 = 1; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s(...)\n", __FUNCTION__); + } + + 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, "%s: envmode is %s/%s\n", __FUNCTION__, + _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 */ + /* [dBorca] Hack alert: + * TODO: revise this ASAP!!! + */ + fxSetupTextureEnvNapalm_NoLock(ctx, FX_TMU1 - tmu0, tmu0, tmu0 != 0); + fxSetupTextureEnvNapalm_NoLock(ctx, FX_TMU1 - tmu1, tmu1, tmu1 != 0); +} + +/************************* No Texture ***************************/ + +static void +fxSetupTextureNoneNapalm_NoLock(GLcontext * ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s(...)\n", __FUNCTION__); + } + + /* 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/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c index 648649c0328..90704e34793 100644 --- a/src/mesa/drivers/glide/fxtexman.c +++ b/src/mesa/drivers/glide/fxtexman.c @@ -1,5 +1,3 @@ -/* $Id: fxtexman.c,v 1.17 2003/10/02 17:36:44 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -45,6 +43,7 @@ #include "fxdrv.h" int texSwaps = 0; +static FxU32 texBoundMask; #define FX_2MB_SPLIT 0x200000 @@ -120,30 +119,37 @@ fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end) fxCloseHardware(); exit(-1); } - result->next = NULL; } 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, boundary; + FxU32 start, end, blockstart, blockend, chunk; start = grTexMinAddress(tmu); end = grTexMaxAddress(tmu); - boundary = (fxMesa->type >= GR_SSTTYPE_Banshee) ? (end - start) : FX_2MB_SPLIT; + chunk = (fxMesa->type >= GR_SSTTYPE_Banshee) ? (end - start) : FX_2MB_SPLIT; if (fxMesa->verbose) { fprintf(stderr, "Voodoo %s configuration:\n", @@ -152,7 +158,7 @@ fxTMUInit(fxMesaContext fxMesa, int tmu) (unsigned int) start); fprintf(stderr, "Voodoo Higher texture memory address (%u)\n", (unsigned int) end); - fprintf(stderr, "Voodoo Splitting Texture memory in %luMB blocks:\n", boundary >> 20); + fprintf(stderr, "Voodoo Splitting Texture memory in %luMB blocks:\n", chunk >> 20); } fxMesa->freeTexMem[tmu] = end - start; @@ -161,16 +167,18 @@ fxTMUInit(fxMesaContext fxMesa, int tmu) last = 0; blockstart = start; while (blockstart < end) { - if (blockstart + boundary > end) + if (blockstart + chunk > end) blockend = end; else - blockend = blockstart + boundary; + blockend = blockstart + chunk; if (fxMesa->verbose) fprintf(stderr, "Voodoo %07u-%07u\n", (unsigned int) blockstart, (unsigned int) blockend); tmn = fxTMNewRangeNode(fxMesa, blockstart, blockend); + tmn->next = NULL; + if (last) last->next = tmn; @@ -178,7 +186,7 @@ fxTMUInit(fxMesaContext fxMesa, int tmu) fxMesa->tmFree[tmu] = tmn; last = tmn; - blockstart += boundary; + blockstart += chunk; } } @@ -189,6 +197,10 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) int result; struct gl_texture_object *obj; + if (fxMesa->HaveTexUma) { + tmu = FX_TMU0; + } + while (1) { prev = 0; tmp = fxMesa->tmFree[tmu]; @@ -225,11 +237,37 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) } } +int fxTMCheckStartAddr (fxMesaContext fxMesa, GLint tmu, tfxTexInfo *ti) +{ + MemRange *prev, *tmp; + int size; + struct gl_texture_object *obj; + + 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; - FxU32 boundary = (fxMesa->type >= GR_SSTTYPE_Banshee) ? -1 : (FX_2MB_SPLIT - 1); + + if (fxMesa->HaveTexUma) { + tmu = FX_TMU0; + } if (range->startAddr == range->endAddr) { fxTMDeleteRangeNode(fxMesa, range); @@ -252,7 +290,7 @@ fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range) range->next = tmp; if (tmp) { if (range->endAddr == tmp->startAddr - && tmp->startAddr & boundary) { + && tmp->startAddr & texBoundMask) { /* Combine */ tmp->startAddr = range->startAddr; fxTMDeleteRangeNode(fxMesa, range); @@ -261,7 +299,7 @@ fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range) } if (prev) { if (prev->endAddr == range->startAddr - && range->startAddr & boundary) { + && range->startAddr & texBoundMask) { /* Combine */ prev->endAddr = range->endAddr; prev->next = range->next; @@ -312,7 +350,7 @@ fxTMFindOldestObject(fxMesaContext fxMesa, int tmu) } /* examine priority */ - if (obj->Priority < lowestPriority) { + if (tmp->Priority < lowestPriority) { lowestPriority = tmp->Priority; lowestPriorityObj = tmp; } @@ -320,8 +358,7 @@ fxTMFindOldestObject(fxMesaContext fxMesa, int tmu) tmp = tmp->Next; } - if (lowestPriority < 1.0) { - ASSERT(lowestPriorityObj); + if (lowestPriorityObj != NULL) { if (TDFX_DEBUG & VERBOSE_TEXTURE) { fprintf(stderr, "fxTMFindOldestObject: %d pri=%f\n", lowestPriorityObj->Name, lowestPriority); } @@ -521,7 +558,17 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, } tmu = (int) ti->whichTMU; +#if 0 + /* [dBorca] + * We get here by (see Tex[Sub]Image2D), thus we are in TMU. + * Also, we just set the correct TMU above. fxTMMoveInTM will + * bail early, so don't bother... + */ fxTMMoveInTM(fxMesa, tObj, tmu); +#else + fxMesa->stats.reqTexUpload++; + fxMesa->stats.texUpload++; +#endif lodlevel = ti->info.largeLodLog2 - (level - ti->minLevel); @@ -749,10 +796,16 @@ fxTMInit(fxMesaContext fxMesa) fxMesa->texBindNumber = 0; fxMesa->tmPool = 0; + if (fxMesa->HaveTexUma) { + grEnable(GR_TEXTURE_UMA_EXT); + } + fxTMUInit(fxMesa, FX_TMU0); - if (fxMesa->haveTwoTMUs) + if (!fxMesa->HaveTexUma && fxMesa->haveTwoTMUs) fxTMUInit(fxMesa, FX_TMU1); + + texBoundMask = (fxMesa->type >= GR_SSTTYPE_Banshee) ? -1 : (FX_2MB_SPLIT - 1); } void diff --git a/src/mesa/drivers/glide/fxtris.c b/src/mesa/drivers/glide/fxtris.c index 3c6f51a3264..08ecc6dd81b 100644 --- a/src/mesa/drivers/glide/fxtris.c +++ b/src/mesa/drivers/glide/fxtris.c @@ -1,5 +1,3 @@ -/* $Id: fxtris.c,v 1.24 2003/10/02 17:36:44 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -332,7 +330,7 @@ do { \ #define LOCAL_VARS(n) \ fxMesaContext fxMesa = FX_CONTEXT(ctx); \ GLubyte color[n][4]; \ - (void) color; + (void) color; @@ -532,6 +530,7 @@ static void init_rast_tab( void ) /* 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, @@ -547,7 +546,7 @@ static void fx_render_vb_points( GLcontext *ctx, fprintf(stderr, "fx_render_vb_points\n"); } - fxRenderPrimitive(ctx, GL_POINTS); + INIT(GL_POINTS); /* Adjust point coords */ for (i = start; i < count; i++) { @@ -578,7 +577,7 @@ static void fx_render_vb_line_strip( GLcontext *ctx, fprintf(stderr, "fx_render_vb_line_strip\n"); } - fxRenderPrimitive(ctx, GL_LINE_STRIP); + INIT(GL_LINE_STRIP); /* adjust line coords */ for (i = start; i < count; i++) { @@ -611,7 +610,7 @@ static void fx_render_vb_line_loop( GLcontext *ctx, fprintf(stderr, "fx_render_vb_line_loop\n"); } - fxRenderPrimitive(ctx, GL_LINE_LOOP); + INIT(GL_LINE_LOOP); if (!(flags & PRIM_BEGIN)) { j++; @@ -651,7 +650,7 @@ static void fx_render_vb_lines( GLcontext *ctx, fprintf(stderr, "fx_render_vb_lines\n"); } - fxRenderPrimitive(ctx, GL_LINES); + INIT(GL_LINES); /* adjust line coords */ for (i = start; i < count; i++) { @@ -682,7 +681,7 @@ static void fx_render_vb_triangles( GLcontext *ctx, fprintf(stderr, "fx_render_vb_triangles\n"); } - fxRenderPrimitive(ctx, GL_TRIANGLES); + INIT(GL_TRIANGLES); #if 0 /* [dBorca] @@ -718,7 +717,7 @@ static void fx_render_vb_tri_strip( GLcontext *ctx, fprintf(stderr, "fx_render_vb_tri_strip\n"); } - fxRenderPrimitive(ctx, GL_TRIANGLE_STRIP); + INIT(GL_TRIANGLE_STRIP); if (flags & PRIM_PARITY) mode = GR_TRIANGLE_STRIP_CONTINUE; @@ -743,7 +742,7 @@ static void fx_render_vb_tri_fan( GLcontext *ctx, fprintf(stderr, "fx_render_vb_tri_fan\n"); } - fxRenderPrimitive(ctx, GL_TRIANGLE_FAN); + INIT(GL_TRIANGLE_FAN); grDrawVertexArrayContiguous( GR_TRIANGLE_FAN, count-start, fxVB + start, sizeof(GrVertex) ); @@ -763,7 +762,7 @@ static void fx_render_vb_quads( GLcontext *ctx, fprintf(stderr, "fx_render_vb_quads\n"); } - fxRenderPrimitive(ctx, GL_QUADS); + INIT(GL_QUADS); for (i = start ; i < count-3 ; i += 4 ) { #define VERT(x) (fxVB + (x)) @@ -786,7 +785,7 @@ static void fx_render_vb_quad_strip( GLcontext *ctx, fprintf(stderr, "fx_render_vb_quad_strip\n"); } - fxRenderPrimitive(ctx, GL_QUAD_STRIP); + INIT(GL_QUAD_STRIP); count -= (count-start)&1; @@ -807,7 +806,7 @@ static void fx_render_vb_poly( GLcontext *ctx, fprintf(stderr, "fx_render_vb_poly\n"); } - fxRenderPrimitive(ctx, GL_POLYGON); + INIT(GL_POLYGON); grDrawVertexArrayContiguous( GR_POLYGON, count-start, fxVB + start, sizeof(GrVertex)); @@ -838,6 +837,7 @@ static void (*fx_render_tab_verts[GL_POLYGON+2])(GLcontext *, fx_render_vb_poly, fx_render_vb_noop, }; +#undef INIT(x) /**********************************************************************/ @@ -1026,11 +1026,24 @@ static void fxRunPipeline( GLcontext *ctx ) 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; + /* [dBorca] Hack alert: + * the above _NEW_PROJECTION is not included in the test below, + * so we may end up with fxMesa->new_state still dirty by the end + * of the routine. The fact is, we don't have NearFar callback + * anymore. We could use fxDDDepthRange instead, but it seems + * fog needs to be updated only by a fog-basis. + * Implementing fxDDDepthRange correctly is another story: + * that, together with a presumable fxDDViewport function would set + * fxMesa->SetupNewInputs |= VERT_BIT_CLIP; + * which might be useful in fxBuildVertices... + */ +#endif if (new_gl_state & (_FX_NEW_IS_IN_HARDWARE | _FX_NEW_RENDERSTATE | @@ -1097,8 +1110,6 @@ static GLenum reduced_prim[GL_POLYGON+1] = { */ static void fxRasterPrimitive( GLcontext *ctx, GLenum prim ) { - extern void fxSetupCull (GLcontext *ctx); - fxMesaContext fxMesa = FX_CONTEXT( ctx ); fxMesa->raster_primitive = prim; @@ -1176,7 +1187,7 @@ void fxCheckIsInHardware( GLcontext *ctx ) if (newfallback) { if (oldfallback == 0) { if (fxMesa->verbose) { - fprintf(stderr, "Voodoo ! begin SW 0x08%x %s\n", newfallback, getFallbackString(newfallback)); + fprintf(stderr, "Voodoo ! enter SW 0x%08x %s\n", newfallback, getFallbackString(newfallback)); } _swsetup_Wakeup( ctx ); } @@ -1197,7 +1208,7 @@ void fxCheckIsInHardware( GLcontext *ctx ) fxChooseVertexState(ctx); fxDDChooseRenderState(ctx); if (fxMesa->verbose) { - fprintf(stderr, "Voodoo ! end SW 0x08%x %s\n", oldfallback, getFallbackString(oldfallback)); + fprintf(stderr, "Voodoo ! leave SW 0x%08x %s\n", oldfallback, getFallbackString(oldfallback)); } } } diff --git a/src/mesa/drivers/glide/fxvb.c b/src/mesa/drivers/glide/fxvb.c index 2923530d466..8d3647ad60e 100644 --- a/src/mesa/drivers/glide/fxvb.c +++ b/src/mesa/drivers/glide/fxvb.c @@ -1,5 +1,3 @@ -/* $Id: fxvb.c,v 1.19.2.1 2003/11/21 13:40:21 keithw Exp $ */ - /* * Mesa 3-D graphics library * Version: 5.1 @@ -118,7 +116,7 @@ static void interp_extras( GLcontext *ctx, GET_COLOR(VB->ColorPtr[1], dst), GET_COLOR(VB->ColorPtr[1], out), GET_COLOR(VB->ColorPtr[1], in) ); -#if 0 /* [dBorca] leaving disabled for now */ +#if 1 /* [dBorca] GL_EXT_separate_specular_color */ if (VB->SecondaryColorPtr[1]) { INTERP_3CHAN( t, GET_COLOR(VB->SecondaryColorPtr[1], dst), @@ -143,7 +141,7 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) if (VB->ColorPtr[1]) { COPY_CHAN4( GET_COLOR(VB->ColorPtr[1], dst), GET_COLOR(VB->ColorPtr[1], src) ); -#if 0 /* [dBorca] leaving disabled for now */ +#if 1 /* [dBorca] GL_EXT_separate_specular_color */ if (VB->SecondaryColorPtr[1]) { COPY_CHAN4( GET_COLOR(VB->SecondaryColorPtr[1], dst), GET_COLOR(VB->SecondaryColorPtr[1], src) ); @@ -395,7 +393,7 @@ void fxFreeVB( GLcontext *ctx ) } if (fxMesa->UbyteColor.Ptr) { - ALIGN_FREE(fxMesa->UbyteColor.Ptr); + ALIGN_FREE((void *)fxMesa->UbyteColor.Ptr); fxMesa->UbyteColor.Ptr = 0; } } diff --git a/src/mesa/drivers/glide/fxvbtmp.h b/src/mesa/drivers/glide/fxvbtmp.h index d1a022ff5e4..7d5741cd75d 100644 --- a/src/mesa/drivers/glide/fxvbtmp.h +++ b/src/mesa/drivers/glide/fxvbtmp.h @@ -1,5 +1,3 @@ -/* $Id: fxvbtmp.h,v 1.13 2003/10/02 17:36:45 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.1 @@ -29,6 +27,10 @@ */ +#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 ) @@ -89,9 +91,9 @@ static void TAG(emit)( GLcontext *ctx, if (IND & SETUP_XYZW) { if (mask[i] == 0) { /* unclipped */ - v->x = s[0] * proj[0][0] + s[12]; - v->y = s[5] * proj[0][1] + s[13]; - v->ooz = s[10] * proj[0][2] + s[14]; + 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]; } else { /* clipped */ @@ -122,32 +124,24 @@ static void TAG(emit)( GLcontext *ctx, } 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].sow = tc0[0][0] * u0scale * w; - v->tmuvtx[0].tow = tc0[0][1] * v0scale * w; v->tmuvtx[0].oow = w; if (tc0_size == 4) - v->tmuvtx[0].oow = tc0[0][3] * w; - } - else { - v->tmuvtx[0].sow = tc0[0][0] * u0scale * w; - v->tmuvtx[0].tow = tc0[0][1] * v0scale * w; + 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].sow = tc1[0][0] * u1scale * w; - v->tmuvtx[1].tow = tc1[0][1] * v1scale * w; v->tmuvtx[1].oow = w; if (tc1_size == 4) - v->tmuvtx[1].oow = tc1[0][3] * w; + v->tmuvtx[1].oow *= tc1[0][3]; } - else { - v->tmuvtx[1].sow = tc1[0][0] * u1scale * w; - v->tmuvtx[1].tow = tc1[0][1] * v1scale * w; - } tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride); } } @@ -197,9 +191,9 @@ static void TAG(interp)( GLcontext *ctx, const GLfloat wout = 1.0F / out->oow; const GLfloat win = 1.0F / in->oow; - dst->x = s[0] * dstclip[0] * oow + s[12]; - dst->y = s[5] * dstclip[1] * oow + s[13]; - dst->ooz = s[10] * dstclip[2] * oow + s[14]; + 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) { diff --git a/src/mesa/drivers/glide/fxwgl.c b/src/mesa/drivers/glide/fxwgl.c index 1337585aec8..4609880f8d3 100644 --- a/src/mesa/drivers/glide/fxwgl.c +++ b/src/mesa/drivers/glide/fxwgl.c @@ -1,5 +1,3 @@ -/* $Id: fxwgl.c,v 1.18 2003/10/02 17:36:45 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -59,6 +57,11 @@ extern "C" #define MAX_MESA_ATTRS 20 +#if (_MSC_VER >= 1200) +#pragma warning( push ) +#pragma warning( disable : 4273 ) +#endif + struct __extensions__ { PROC proc; @@ -71,7 +74,7 @@ struct __pixelformat__ GLint mesaAttr[MAX_MESA_ATTRS]; }; -//WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *); +WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *); struct __pixelformat__ pix[] = { /* 16bit RGB565 single buffer with depth */ @@ -166,53 +169,6 @@ struct __pixelformat__ pix[] = { FXMESA_NONE} } , -#if 1 - /* 24bit RGB888 single buffer with depth */ - { - {sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, - PFD_TYPE_RGBA, - 24, - 8, 0, 8, 8, 8, 16, 0, 0, - 0, 0, 0, 0, 0, - 24, - 8, - 0, - PFD_MAIN_PLANE, - 0, 0, 0, 0} - , - {FXMESA_COLORDEPTH, 32, - FXMESA_ALPHA_SIZE, 8, - FXMESA_DEPTH_SIZE, 24, - FXMESA_STENCIL_SIZE, 8, - FXMESA_ACCUM_SIZE, 0, - FXMESA_NONE} - } - , - /* 24bit RGB888 double buffer with depth */ - { - {sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | - PFD_DOUBLEBUFFER | PFD_SWAP_COPY, - PFD_TYPE_RGBA, - 24, - 8, 0, 8, 8, 8, 16, 0, 0, - 0, 0, 0, 0, 0, - 24, - 8, - 0, - PFD_MAIN_PLANE, - 0, 0, 0, 0} - , - {FXMESA_COLORDEPTH, 32, - FXMESA_DOUBLEBUFFER, - FXMESA_ALPHA_SIZE, 8, - FXMESA_DEPTH_SIZE, 24, - FXMESA_STENCIL_SIZE, 8, - FXMESA_ACCUM_SIZE, 0, - FXMESA_NONE} - }, -#endif /* 32bit ARGB8888 single buffer with depth */ { {sizeof(PIXELFORMATDESCRIPTOR), 1, @@ -365,7 +321,7 @@ wglCreateContext(HDC hdc) SetWindowLong(hWnd, GWL_WNDPROC, (LONG) __wglMonitor); } -#ifdef FX_DEBUG +#if FX_DEBUG freopen("MESA.LOG", "w", stderr); #endif @@ -915,7 +871,7 @@ wglDescribeLayerPlane(HDC hdc, int iPixelFormat, int iLayerPlane, GLAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart, - int cEntries, CONST COLORREF *pcr) + int cEntries, COLORREF *pcr) { SetLastError(0); return (FALSE); @@ -936,4 +892,8 @@ wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane, int iStart, return(FALSE); } +#if (_MSC_VER >= 1200) +#pragma warning( pop ) +#endif + #endif /* FX */ |