From f03cb2e4eea23fd82e9837e05f0ab3a83cb474c7 Mon Sep 17 00:00:00 2001 From: Daniel Borca Date: Tue, 21 Oct 2003 08:31:02 +0000 Subject: Napalm total immersion --- src/mesa/drivers/glide/fxapi.c | 3 +- src/mesa/drivers/glide/fxdd.c | 467 ++++++++++++--- src/mesa/drivers/glide/fxddspan.c | 395 ++++++------- src/mesa/drivers/glide/fxddtex.c | 19 +- src/mesa/drivers/glide/fxdrv.h | 16 +- src/mesa/drivers/glide/fxg.c | 8 +- src/mesa/drivers/glide/fxglidew.c | 3 +- src/mesa/drivers/glide/fxglidew.h | 3 +- src/mesa/drivers/glide/fxsetup.c | 380 +++++++++---- src/mesa/drivers/glide/fxsetup.h | 1128 +++++++++++++++++++++++++++++++++++++ src/mesa/drivers/glide/fxtexman.c | 49 +- src/mesa/drivers/glide/fxtris.c | 21 +- src/mesa/drivers/glide/fxvb.c | 2 - src/mesa/drivers/glide/fxvbtmp.h | 2 - src/mesa/drivers/glide/fxwgl.c | 4 +- 15 files changed, 2098 insertions(+), 402 deletions(-) create mode 100644 src/mesa/drivers/glide/fxsetup.h (limited to 'src/mesa/drivers/glide') diff --git a/src/mesa/drivers/glide/fxapi.c b/src/mesa/drivers/glide/fxapi.c index 02b00a84c9..2ebb451b2d 100644 --- a/src/mesa/drivers/glide/fxapi.c +++ b/src/mesa/drivers/glide/fxapi.c @@ -1,5 +1,3 @@ -/* $Id: fxapi.c,v 1.40 2003/10/13 11:14:58 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -324,6 +322,7 @@ fxMesaCreateContext(GLuint win, 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; diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index 7087c30b66..fec2ee9d72 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.103 2003/10/14 14:56:45 dborca 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" @@ -200,6 +195,12 @@ 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 ); @@ -492,44 +493,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 */ @@ -568,10 +573,14 @@ 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); */ + 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 0 + /* [dBorca] + * who uses bgr, anyway? Expecting the V2 from HM... :D + */ if (fxMesa->bgrOrder) color = (FxU16) (((FxU16) 0xf8 & b) << (11 - 3)) | @@ -580,14 +589,23 @@ fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py, color = (FxU16) (((FxU16) 0xf8 & r) << (11 - 3)) | (((FxU16) 0xfc & g) << (5 - 3 + 1)) | (((FxU16) 0xf8 & b) >> 3); +#else + if (fxMesa->colDepth == 15) { + color = TDFXPACKCOLOR1555(b, g, r, a); + mode = GR_LFBWRITEMODE_1555; + } else { + color = TDFXPACKCOLOR565(b, g, r); + mode = GR_LFBWRITEMODE_565; + } +#endif } 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; } @@ -656,14 +674,188 @@ 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); +#if 0 + /* [dBorca] + * who uses bgr, anyway? Expecting the V2 from HM... :D + */ + 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); +#else + color = TDFXPACKCOLOR8888(b, g, r, a); +#endif + } + + 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; @@ -771,14 +963,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; @@ -839,7 +1032,7 @@ static void fxDDReadPixels555 (GLcontext * ctx, 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 >> 5) & 0x1f]; *d++ = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; *d++ = (pixel & 0x8000) ? 255 : 0; *d++ = FX_rgb_scale_5[(pixel >> 16) & 0x1f]; @@ -850,7 +1043,7 @@ static void fxDDReadPixels555 (GLcontext * ctx, 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 >> 5) & 0x1f]; *d++ = FX_rgb_scale_5[(pixel >> 10) & 0x1f]; *d++ = (pixel & 0x8000) ? 255 : 0; } @@ -882,14 +1075,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; @@ -930,17 +1124,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); @@ -957,6 +1169,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) { @@ -1031,6 +1342,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; @@ -1151,6 +1463,7 @@ fxDDInitExtensions(GLcontext * ctx) _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"); @@ -1170,9 +1483,14 @@ fxDDInitExtensions(GLcontext * ctx) _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"); + } - /* env_combine: not ready yet */ - /*_mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" );*/ + if (fxMesa->HavePixExt) { + _mesa_enable_extension(ctx, "GL_EXT_blend_subtract"); } if (fxMesa->HaveMirExt) { @@ -1206,8 +1524,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)) { @@ -1237,6 +1564,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 || @@ -1250,6 +1578,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) @@ -1289,6 +1618,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; @@ -1339,18 +1669,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; @@ -1387,6 +1720,8 @@ fxSetupDDPointers(GLcontext * ctx) 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 c7d5021923..3e242f9bd7 100644 --- a/src/mesa/drivers/glide/fxddspan.c +++ b/src/mesa/drivers/glide/fxddspan.c @@ -1,5 +1,3 @@ -/* $Id: fxddspan.c,v 1.26 2003/10/09 15:12:21 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -48,41 +46,9 @@ #include "swrast/swrast.h" -#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) - - - -/* KW: Rearranged the args in the call to grLfbWriteRegion(). - */ -#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) \ - - /************************************************************************/ /***** Span functions *****/ /************************************************************************/ -#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)) -/************************************************************************/ - #define DBG 0 @@ -135,20 +101,26 @@ #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 miny = fxMesa->clipMinY; \ + const int maxy = Y_FLIP(fxMesa->clipMinY); \ const int maxx = fxMesa->clipMaxX; \ - const int maxy = fxMesa->clipMaxY; + 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 miny = fxMesa->clipMinY; \ + const int maxy = Y_FLIP(fxMesa->clipMinY); \ const int maxx = fxMesa->clipMaxX; \ - const int maxy = fxMesa->clipMaxY; + const int miny = Y_FLIP(fxMesa->clipMaxY); #define HW_ENDCLIPLOOP() \ } \ @@ -188,6 +160,13 @@ /* 16 bit, RGB565 color spanline and pixel functions */ +/* [dBorca] Hack alert: + * This is wrong. The alpha value is lost, even when we provide + * HW alpha (565 w/o depth buffering). To really update alpha buffer, + * we would need to do the 565 writings via 8888 colorformat and rely + * on the Voodoo to perform color scaling. In which case our 565 span + * would look nicer! But this violates FSAA rules... + */ #undef LFB_MODE #define LFB_MODE GR_LFBWRITEMODE_565 @@ -251,6 +230,105 @@ #include "../dri/common/spantmp.h" +/************************************************************************/ +/***** Depth functions *****/ +/************************************************************************/ + +#define DBG 0 + +#undef HW_WRITE_LOCK +#undef HW_WRITE_UNLOCK +#undef HW_READ_LOCK +#undef HW_READ_UNLOCK + +#define HW_CLIPLOOP HW_WRITE_CLIPLOOP + +#define LOCAL_DEPTH_VARS \ + GLuint pitch = info.strideInBytes; \ + GLuint height = fxMesa->height; \ + char *buf = (char *)((char *)info.lfbPtr + 0 /* x, y offset */); \ + (void) buf; + +#define HW_WRITE_LOCK() \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GrLfbInfo_t info; \ + info.size = sizeof(GrLfbInfo_t); \ + if ( grLfbLock( GR_LFB_WRITE_ONLY, \ + GR_BUFFER_AUXBUFFER, LFB_MODE, \ + GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) { + +#define HW_WRITE_UNLOCK() \ + grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_AUXBUFFER); \ + } + +#define HW_READ_LOCK() \ + fxMesaContext fxMesa = FX_CONTEXT(ctx); \ + GrLfbInfo_t info; \ + info.size = sizeof(GrLfbInfo_t); \ + if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER, \ + LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) { + +#define HW_READ_UNLOCK() \ + grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER); \ + } + + +/* 16 bit, depth spanline and pixel functions */ + +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_ZA16 + +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 2 + +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) + +#define TAG(x) tdfx##x##_Z16 +#include "../dri/common/depthtmp.h" + + +/* 24 bit, depth spanline and pixel functions (for use w/ stencil) */ +/* [dBorca] Hack alert: + * This is evil. The incoming Mesa's 24bit depth value + * is shifted left 8 bits, to obtain a full 32bit value, + * which will be thrown into the framebuffer. We rely on + * the fact that Voodoo hardware transforms a 32bit value + * into 24bit value automatically and, MOST IMPORTANT, won't + * alter the upper 8bits of the value already existing in the + * framebuffer (where stencil resides). + */ + +#undef LFB_MODE +#define LFB_MODE GR_LFBWRITEMODE_Z32 + +#undef BYTESPERPIXEL +#define BYTESPERPIXEL 4 + +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d << 8 + +#define READ_DEPTH( d, _x, _y ) \ + d = (*(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch)) & 0xffffff + +#define TAG(x) tdfx##x##_Z24 +#include "../dri/common/depthtmp.h" + + +/* 32 bit, depth spanline and pixel functions (for use w/o stencil) */ +/* [dBorca] Hack alert: + * This is more evil. We make Mesa run in 32bit depth, but + * tha Voodoo HW can only handle 24bit depth. Well, exploiting + * the pixel pipeline, we can achieve 24:8 format for greater + * precision... + * If anyone tells me how to really store 32bit values into the + * depth buffer, I'll write the *_Z32 routines. Howver, bear in + * mind that means running without stencil! + */ + /************************************************************************/ /***** Span functions (optimized) *****/ /************************************************************************/ @@ -378,88 +456,24 @@ static void fxReadRGBASpan_ARGB8888 (const GLcontext * ctx, GLint x, GLint y, GLubyte rgba[][4]) { - /* Hack alert: WRONG! */ 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 *****/ +/***** Depth functions (optimized) *****/ /************************************************************************/ void -fxDDWriteDepthSpan(GLcontext * ctx, - GLuint n, GLint x, GLint y, const GLdepth depth[], - const GLubyte mask[]) -{ - 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); - } -} - - -void -fxDDWriteDepth32Span(GLcontext * ctx, - GLuint n, GLint x, GLint y, const GLdepth depth[], - const GLubyte mask[]) -{ - fxMesaContext fxMesa = FX_CONTEXT(ctx); - GLint bottom = fxMesa->height - 1; - GLint i; - - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s(...)\n", __FUNCTION__); - } - - - 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); - } -} - - -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; @@ -478,116 +492,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) { @@ -631,10 +610,10 @@ fxSetupDDSpanPointers(GLcontext * ctx) swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_ARGB1555; swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB1555; - swdd->WriteDepthSpan = fxDDWriteDepthSpan; - swdd->WriteDepthPixels = fxDDWriteDepthPixels; - swdd->ReadDepthSpan = fxDDReadDepthSpan; - swdd->ReadDepthPixels = fxDDReadDepthPixels; + swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z16; + swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z16; + swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z16; + swdd->ReadDepthPixels = tdfxReadDepthPixels_Z16; break; case 16: swdd->WriteRGBASpan = tdfxWriteRGBASpan_RGB565; @@ -644,11 +623,11 @@ fxSetupDDSpanPointers(GLcontext * ctx) swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_RGB565; swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_RGB565; swdd->ReadRGBAPixels = tdfxReadRGBAPixels_RGB565; - - swdd->WriteDepthSpan = fxDDWriteDepthSpan; - swdd->WriteDepthPixels = fxDDWriteDepthPixels; - swdd->ReadDepthSpan = fxDDReadDepthSpan; - swdd->ReadDepthPixels = fxDDReadDepthPixels; + + swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z16; + swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z16; + swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z16; + swdd->ReadDepthPixels = tdfxReadDepthPixels_Z16; break; case 32: swdd->WriteRGBASpan = tdfxWriteRGBASpan_ARGB8888; @@ -656,29 +635,23 @@ fxSetupDDSpanPointers(GLcontext * ctx) swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB8888; swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB8888; swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB8888; - swdd->ReadRGBASpan = tdfxReadRGBASpan_ARGB8888; + swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_ARGB8888; swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB8888; - swdd->WriteDepthSpan = fxDDWriteDepth32Span; - swdd->WriteDepthPixels = fxDDWriteDepth32Pixels; - swdd->ReadDepthSpan = fxDDReadDepth32Span; - swdd->ReadDepthPixels = fxDDReadDepth32Pixels; + swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z24; + swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z24; + swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z24; + swdd->ReadDepthPixels = tdfxReadDepthPixels_Z24; break; } -#if 0 - if ( fxMesa->haveHwStencil ) { - swdd->WriteStencilSpan = write_stencil_span; - swdd->ReadStencilSpan = read_stencil_span; - swdd->WriteStencilPixels = write_stencil_pixels; - swdd->ReadStencilPixels = read_stencil_pixels; + if (fxMesa->haveHwStencil) { + swdd->WriteStencilSpan = fxWriteStencilSpan; + swdd->ReadStencilSpan = fxReadStencilSpan; + swdd->WriteStencilPixels = fxWriteStencilPixels; + swdd->ReadStencilPixels = fxReadStencilPixels; } - - swdd->WriteDepthSpan = tdfxDDWriteDepthSpan; - swdd->WriteDepthPixels = tdfxDDWriteDepthPixels; - swdd->ReadDepthSpan = tdfxDDReadDepthSpan; - swdd->ReadDepthPixels = tdfxDDReadDepthPixels; - +#if 0 swdd->WriteCI8Span = NULL; swdd->WriteCI32Span = NULL; swdd->WriteMonoCISpan = NULL; @@ -687,8 +660,8 @@ fxSetupDDSpanPointers(GLcontext * ctx) swdd->ReadCI32Span = NULL; swdd->ReadCI32Pixels = NULL; - swdd->SpanRenderStart = tdfxSpanRenderStart; /* BEGIN_BOARD_LOCK */ - swdd->SpanRenderFinish = tdfxSpanRenderFinish; /* END_BOARD_LOCK */ + 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 346d3625b0..8b64a8e2c6 100644 --- a/src/mesa/drivers/glide/fxddtex.c +++ b/src/mesa/drivers/glide/fxddtex.c @@ -1,5 +1,3 @@ -/* $Id: fxddtex.c,v 1.51 2003/10/14 14:56:45 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -715,6 +713,7 @@ fetch_alpha8(const struct gl_texture_image *texImage, i = i * mml->wScale; j = j * mml->hScale; + /* [dBorca] why, oh... why? */ i = i * mml->width / texImage->Width; j = j * mml->height / texImage->Height; @@ -736,6 +735,7 @@ fetch_index8(const struct gl_texture_image *texImage, i = i * mml->wScale; j = j * mml->hScale; + /* [dBorca] why, oh... why? */ i = i * mml->width / texImage->Width; j = j * mml->height / texImage->Height; @@ -863,6 +863,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_argb565 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"); } diff --git a/src/mesa/drivers/glide/fxdrv.h b/src/mesa/drivers/glide/fxdrv.h index 204fef78ce..996c1be2bb 100644 --- a/src/mesa/drivers/glide/fxdrv.h +++ b/src/mesa/drivers/glide/fxdrv.h @@ -1,5 +1,3 @@ -/* $Id: fxdrv.h,v 1.61 2003/10/14 14:56:45 dborca 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 @@ -313,6 +319,7 @@ typedef struct GrAlphaBlendFnc_t blendDstFuncRGB; GrAlphaBlendFnc_t blendSrcFuncAlpha; GrAlphaBlendFnc_t blendDstFuncAlpha; + GrAlphaBlendOp_t blendEq; /* Depth test */ @@ -531,6 +538,7 @@ struct tfxMesaContext FxBool HaveTexFmt; /* TEXFMT */ FxBool HaveCmbExt; /* COMBINE */ FxBool HaveMirExt; /* TEXMIRROR */ + FxBool HaveTexUma; /* TEXUMA */ FxBool HaveTexus2; /* Texus 2 - FXT1 */ struct tdfx_glide Glide; char rendererString[100]; @@ -597,6 +605,8 @@ 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); @@ -617,6 +627,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] */ @@ -665,6 +676,7 @@ extern void fxCheckIsInHardware(GLcontext *ctx); /* fxsetup: * semi-private functions */ +void fxSetupCull (GLcontext * ctx); void fxSetupScissor (GLcontext * ctx); void fxSetupColorMask (GLcontext * ctx); diff --git a/src/mesa/drivers/glide/fxg.c b/src/mesa/drivers/glide/fxg.c index 25b2bb6b9c..99c2066af1 100644 --- a/src/mesa/drivers/glide/fxg.c +++ b/src/mesa/drivers/glide/fxg.c @@ -30,8 +30,6 @@ * Web : http://www.geocities.com/dborca */ -#ifdef FX - #include #include @@ -243,6 +241,8 @@ const char *TRP_BLEND (GrAlphaBlendFnc_t func) TRAP_CASE_STRING(GR_BLEND_RESERVED_E); TRAP_CASE_STRING(GR_BLEND_ALPHA_SATURATE); /*TRAP_CASE_STRING(GR_BLEND_PREFOG_COLOR); ==GR_BLEND_ALPHA_SATURATE*/ + TRAP_CASE_STRING(GR_BLEND_SAME_COLOR_EXT); + TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SAME_COLOR_EXT); TRAP_NODEFAULT; } } @@ -733,8 +733,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; } } @@ -2135,5 +2133,3 @@ void tdfx_hook_glide (struct tdfx_glide *Glide) #undef GET_EXT_ADDR } - -#endif /* FX */ diff --git a/src/mesa/drivers/glide/fxglidew.c b/src/mesa/drivers/glide/fxglidew.c index e20949e062..0e6ff6a530 100644 --- a/src/mesa/drivers/glide/fxglidew.c +++ b/src/mesa/drivers/glide/fxglidew.c @@ -1,5 +1,3 @@ -/* $Id: fxglidew.c,v 1.23 2003/10/13 11:14:58 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -230,6 +228,7 @@ FX_grSstQueryHardware(GrHwConfiguration * config) 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; /* number of Voodoo chips */ diff --git a/src/mesa/drivers/glide/fxglidew.h b/src/mesa/drivers/glide/fxglidew.h index fb354ffd6f..7f7bd692ee 100644 --- a/src/mesa/drivers/glide/fxglidew.h +++ b/src/mesa/drivers/glide/fxglidew.h @@ -1,5 +1,3 @@ -/* $Id: fxglidew.h,v 1.18 2003/10/13 11:14:58 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -78,6 +76,7 @@ typedef struct { 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 */ diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c index d9c42dd088..40fd4a5f9c 100644 --- a/src/mesa/drivers/glide/fxsetup.c +++ b/src/mesa/drivers/glide/fxsetup.c @@ -1,5 +1,3 @@ -/* $Id: fxsetup.c,v 1.42 2003/10/13 11:14:58 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -315,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 { @@ -431,8 +424,10 @@ fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend) tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE; - /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */ - + /* [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; @@ -549,49 +544,49 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset) } break; case GL_BLEND: -#if 1 - if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s: GL_BLEND not quite supported\n", __FUNCTION__); - } - return; -#else - /* - * XXX we can't do real GL_BLEND mode. These settings assume that - * the TexEnv color is black and incoming fragment color is white. - */ 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; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; } else if (ifmt == GL_INTENSITY) { /* Av = Af * (1 - It) + Ac * It */ - /* XXX this is wrong */ - alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; - alphaComb.Factor = GR_COMBINE_FACTOR_NONE; - alphaComb.Other = GR_COMBINE_OTHER_NONE; + 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; + 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_ONE; - colorComb.Other = GR_COMBINE_OTHER_TEXTURE; - colorComb.Invert = FXTRUE; + 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; + } } - /* XXX return GL_FALSE for modes we don't support */ + + 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; -#endif case GL_REPLACE: if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE)) { alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; @@ -613,6 +608,41 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset) colorComb.Other = GR_COMBINE_OTHER_TEXTURE; } break; + case GL_ADD: + if (ifmt == GL_ALPHA || + ifmt == GL_LUMINANCE_ALPHA || + ifmt == GL_RGBA) { + /* product of texel and fragment alpha */ + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + else if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { + /* fragment alpha is unchanged */ + alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; + alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Other = GR_COMBINE_OTHER_NONE; + } + else { + /* sum of texel and fragment alpha */ + alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + alphaComb.Factor = GR_COMBINE_FACTOR_ONE; + alphaComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + + if (ifmt == GL_ALPHA) { + /* rgb unchanged */ + colorComb.Function = GR_COMBINE_FUNCTION_LOCAL; + colorComb.Factor = GR_COMBINE_FACTOR_NONE; + colorComb.Other = GR_COMBINE_OTHER_NONE; + } + else { + /* sum of texel and fragment rgb */ + colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + } + break; default: if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "%s: %x Texture.EnvMode not yet supported\n", __FUNCTION__, @@ -1083,6 +1113,8 @@ fxSetupTextureNone_NoLock(GLcontext * ctx) fxMesa->lastUnitsMode = FX_UM_NONE; } +#include "fxsetup.h" + /************************************************************************/ /************************** Texture Mode SetUp **************************/ /************************************************************************/ @@ -1096,20 +1128,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); + } } } @@ -1125,117 +1175,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; @@ -1243,18 +1387,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); + } + } } /************************************************************************/ @@ -1468,8 +1660,8 @@ fxSetupColorMask(GLcontext * ctx) } else { /* 16 bpp mode */ - grColorMask(ctx->Color.ColorMask[RCOMP] || - ctx->Color.ColorMask[GCOMP] || + grColorMask(ctx->Color.ColorMask[RCOMP] | + ctx->Color.ColorMask[GCOMP] | ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha); } diff --git a/src/mesa/drivers/glide/fxsetup.h b/src/mesa/drivers/glide/fxsetup.h new file mode 100644 index 0000000000..90aefe2758 --- /dev/null +++ b/src/mesa/drivers/glide/fxsetup.h @@ -0,0 +1,1128 @@ +/* + * 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; + 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: + 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 35b4205106..90704e3479 100644 --- a/src/mesa/drivers/glide/fxtexman.c +++ b/src/mesa/drivers/glide/fxtexman.c @@ -1,5 +1,3 @@ -/* $Id: fxtexman.c,v 1.18 2003/10/09 15:12:21 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -199,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]; @@ -235,11 +237,38 @@ 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; + if (fxMesa->HaveTexUma) { + tmu = FX_TMU0; + } + if (range->startAddr == range->endAddr) { fxTMDeleteRangeNode(fxMesa, range); return; @@ -529,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); @@ -757,9 +796,13 @@ 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); diff --git a/src/mesa/drivers/glide/fxtris.c b/src/mesa/drivers/glide/fxtris.c index 4eb536a813..d60b874027 100644 --- a/src/mesa/drivers/glide/fxtris.c +++ b/src/mesa/drivers/glide/fxtris.c @@ -1,5 +1,3 @@ -/* $Id: fxtris.c,v 1.25 2003/10/09 15:12:21 dborca 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; @@ -1026,11 +1024,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 | @@ -1174,7 +1185,7 @@ void fxCheckIsInHardware( GLcontext *ctx ) if (newfallback) { if (oldfallback == 0) { if (fxMesa->verbose) { - fprintf(stderr, "Voodoo ! begin SW 0x%08x %s\n", newfallback, getFallbackString(newfallback)); + fprintf(stderr, "Voodoo ! enter SW 0x%08x %s\n", newfallback, getFallbackString(newfallback)); } _swsetup_Wakeup( ctx ); } @@ -1195,7 +1206,7 @@ void fxCheckIsInHardware( GLcontext *ctx ) fxChooseVertexState(ctx); fxDDChooseRenderState(ctx); if (fxMesa->verbose) { - fprintf(stderr, "Voodoo ! end SW 0x%08x %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 857093b5c9..c8d6495f54 100644 --- a/src/mesa/drivers/glide/fxvb.c +++ b/src/mesa/drivers/glide/fxvb.c @@ -1,5 +1,3 @@ -/* $Id: fxvb.c,v 1.20 2003/10/09 15:12:21 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 5.1 diff --git a/src/mesa/drivers/glide/fxvbtmp.h b/src/mesa/drivers/glide/fxvbtmp.h index 306a47c9b3..7d5741cd75 100644 --- a/src/mesa/drivers/glide/fxvbtmp.h +++ b/src/mesa/drivers/glide/fxvbtmp.h @@ -1,5 +1,3 @@ -/* $Id: fxvbtmp.h,v 1.14 2003/10/09 15:12:21 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.1 diff --git a/src/mesa/drivers/glide/fxwgl.c b/src/mesa/drivers/glide/fxwgl.c index f03def4996..8ab9d23c98 100644 --- a/src/mesa/drivers/glide/fxwgl.c +++ b/src/mesa/drivers/glide/fxwgl.c @@ -1,5 +1,3 @@ -/* $Id: fxwgl.c,v 1.19 2003/10/13 11:14:58 dborca Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -365,7 +363,7 @@ wglCreateContext(HDC hdc) SetWindowLong(hWnd, GWL_WNDPROC, (LONG) __wglMonitor); } -#ifdef FX_DEBUG +#if FX_DEBUG freopen("MESA.LOG", "w", stderr); #endif -- cgit v1.2.3