diff options
author | Felix Kuehling <fxkuehl@gmx.de> | 2005-04-23 17:18:57 +0000 |
---|---|---|
committer | Felix Kuehling <fxkuehl@gmx.de> | 2005-04-23 17:18:57 +0000 |
commit | 9b4536a654774e3df330e9f238475aa20e30f7a3 (patch) | |
tree | 0914b87511904e1553c9737fbda0c03f8e56f2b2 | |
parent | df943a40411d2b71381e5053d7c59e8cd2400fff (diff) |
Texturing fixes for Savage3D/MX/IX:
- force emitting texAddr when the texture image changed (flush caches)
- set transparent texture color key to something improbable
(couldn't find a way to disable it completely)
- fixed texture environment modes GL_DECAL and GL_REPLACE
- made texture environment mode GL_BLEND a software fallback
- added two custom texture formats for promoting from GL_ALPHA to ARGB8888
and 4444. Since the hardware can't be made to ignore the RGB color
components, set them to 1 instead of 0. This gives the correct results
- disabled GL_EXT_texture_env_add on Savage3D/MX/IX
- map both GL_CLAMP and GL_CLAMP_TO_EDGE to hardware mode "wrap". It doesn't
match either mode exactly by the spec, so we should either fall back on both
or none. I chose the latter.
- fall back to software when s and t wrapping modes differ (hardware has only
one bit for both)
-rw-r--r-- | src/mesa/drivers/dri/savage/savage_xmesa.c | 10 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagestate.c | 18 | ||||
-rw-r--r-- | src/mesa/drivers/dri/savage/savagetex.c | 236 |
3 files changed, 240 insertions, 24 deletions
diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index c3bf710e25..0b3dbbd03c 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -123,10 +123,14 @@ unsigned long time_sum=0; struct timeval tv_s1,tv_f1; #endif -static const char *const card_extensions[] = +static const char *const common_extensions[] = { "GL_ARB_multitexture", "GL_EXT_texture_lod_bias", + NULL +}; +static const char *const s4_extensions[] = +{ "GL_EXT_texture_env_add", NULL }; @@ -522,7 +526,9 @@ savageCreateContext( const __GLcontextModes *mesaVis, debug_control ); #endif - driInitExtensions( ctx, card_extensions, GL_TRUE ); + driInitExtensions( ctx, common_extensions, GL_TRUE ); + if (savageScreen->chipset >= S3_SAVAGE4) + driInitExtensions( ctx, s4_extensions, GL_FALSE ); savageDDInitStateFuncs( ctx ); savageDDInitSpanFuncs( ctx ); diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c index c3df5f4f87..c772a24844 100644 --- a/src/mesa/drivers/dri/savage/savagestate.c +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -1461,6 +1461,13 @@ static void savageUpdateRegister_s4(savageContextPtr imesa) } static void savageUpdateRegister_s3d(savageContextPtr imesa) { + /* In case the texture image was changed without changing the + * texture address as well, we need to force emitting the texture + * address in order to flush texture cashes. */ + if ((imesa->dirty & SAVAGE_UPLOAD_TEX0) && + imesa->oldRegs.s3d.texAddr.ui == imesa->regs.s3d.texAddr.ui) + imesa->oldRegs.s3d.texAddr.ui = 0xffffffff; + /* Some temporary hacks to workaround lockups. Not sure if they are * still needed. But they work for now. */ imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE; @@ -1626,12 +1633,15 @@ static void savageDDInitState_s3d( savageContextPtr imesa ) imesa->regs.s3d.destTexWatermarks.ui = 0x4f000000; #endif - /* clrCmpAlphaBlendCtrl is needed to get alphatest and - * alpha blending working properly - */ - imesa->regs.s3d.texCtrl.ni.dBias = 0x08; imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE; + /* texXprEn is needed to get alphatest and alpha blending working + * properly. However, this makes texels with color texXprClr + * completely transparent in some texture environment modes. I + * couldn't find a way to disable this. So choose an arbitrary and + * improbable color. (0 is a bad choice, makes all black texels + * transparent.) */ + imesa->regs.s3d.texXprClr.ui = 0x26ae26ae; /* programm a valid tex address, in case texture state is emitted * in wrong order. */ if (imesa->lastTexHeap == 2 && imesa->savageScreen->textureSize[1]) { diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c index 6641231371..0acfc2117b 100644 --- a/src/mesa/drivers/dri/savage/savagetex.c +++ b/src/mesa/drivers/dri/savage/savagetex.c @@ -42,6 +42,9 @@ #include "texstore.h" #include "texobj.h" +#include "convolve.h" +#include "colormac.h" + #include "swrast/swrast.h" #include "xmlpool.h" @@ -462,6 +465,170 @@ savageAllocTexObj( struct gl_texture_object *texObj ) return t; } +/* Mesa texture formats for alpha-images on Savage3D/IX/MX + * + * Promoting texture images to ARGB888 or ARGB4444 doesn't work + * because we can't tell the hardware to ignore the color components + * and only use the alpha component. So we define our own texture + * formats that promote to ARGB8888 or ARGB4444 and set the color + * components to white. This way we get the correct result. */ +static GLboolean +_savage_texstore_a1114444 (GLcontext *ctx, GLuint dims, + GLenum baseInternalFormat, + const struct gl_texture_format *dstFormat, + GLvoid *dstAddr, + GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, + GLint dstRowStride, GLint dstImageStride, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking); +static GLboolean +_savage_texstore_a1118888 (GLcontext *ctx, GLuint dims, + GLenum baseInternalFormat, + const struct gl_texture_format *dstFormat, + GLvoid *dstAddr, + GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, + GLint dstRowStride, GLint dstImageStride, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking); + +static struct gl_texture_format _savage_texformat_a1114444 = { + MESA_FORMAT_ARGB4444, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 4, /* RedBits */ + 4, /* GreenBits */ + 4, /* BlueBits */ + 4, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + _savage_texstore_a1114444, /* StoreTexImageFunc */ + NULL, NULL, NULL, NULL, NULL, NULL /* FetchTexel* filled in by + * savageDDInitTextureFuncs */ +}; +static struct gl_texture_format _savage_texformat_a1118888 = { + MESA_FORMAT_ARGB8888, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 8, /* RedBits */ + 8, /* GreenBits */ + 8, /* BlueBits */ + 8, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 4, /* TexelBytes */ + _savage_texstore_a1118888, /* StoreTexImageFunc */ + NULL, NULL, NULL, NULL, NULL, NULL /* FetchTexel* filled in by + * savageDDInitTextureFuncs */ +}; + +static GLboolean +_savage_texstore_a1114444 (GLcontext *ctx, GLuint dims, + GLenum baseInternalFormat, + const struct gl_texture_format *dstFormat, + GLvoid *dstAddr, + GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, + GLint dstRowStride, GLint dstImageStride, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking) +{ + /* general path */ + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, + baseInternalFormat, + baseInternalFormat, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); + const GLchan *src = tempImage; + GLubyte *dstImage = (GLubyte *) dstAddr + + dstZoffset * dstImageStride + + dstYoffset * dstRowStride + + dstXoffset * dstFormat->TexelBytes; + GLint img, row, col; + + ASSERT(dstFormat == &_savage_texformat_a1114444); + ASSERT(baseInternalFormat == GL_ALPHA); + + if (!tempImage) + return GL_FALSE; + _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); + for (img = 0; img < srcDepth; img++) { + GLubyte *dstRow = dstImage; + for (row = 0; row < srcHeight; row++) { + GLushort *dstUI = (GLushort *) dstRow; + for (col = 0; col < srcWidth; col++) { + dstUI[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[0]), + 255, 255, 255 ); + src += 1; + } + dstRow += dstRowStride; + } + dstImage += dstImageStride; + } + _mesa_free((void *) tempImage); + + return GL_TRUE; +} +static GLboolean +_savage_texstore_a1118888 (GLcontext *ctx, GLuint dims, + GLenum baseInternalFormat, + const struct gl_texture_format *dstFormat, + GLvoid *dstAddr, + GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, + GLint dstRowStride, GLint dstImageStride, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking) +{ + /* general path */ + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, + baseInternalFormat, + baseInternalFormat, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); + const GLchan *src = tempImage; + GLubyte *dstImage = (GLubyte *) dstAddr + + dstZoffset * dstImageStride + + dstYoffset * dstRowStride + + dstXoffset * dstFormat->TexelBytes; + GLint img, row, col; + + ASSERT(dstFormat == &_savage_texformat_a1118888); + ASSERT(baseInternalFormat == GL_ALPHA); + + if (!tempImage) + return GL_FALSE; + _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); + for (img = 0; img < srcDepth; img++) { + GLubyte *dstRow = dstImage; + for (row = 0; row < srcHeight; row++) { + GLuint *dstUI = (GLuint *) dstRow; + for (col = 0; col < srcWidth; col++) { + dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[0]), + 255, 255, 255 ); + src += 1; + } + dstRow += dstRowStride; + } + dstImage += dstImageStride; + } + _mesa_free((void *) tempImage); + + return GL_TRUE; +} + /* Called by the _mesa_store_teximage[123]d() functions. */ static const struct gl_texture_format * savageChooseTextureFormat( GLcontext *ctx, GLint internalFormat, @@ -541,14 +708,14 @@ savageChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_ALPHA: case GL_COMPRESSED_ALPHA: return isSavage4 ? &_mesa_texformat_a8 : ( - do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444); + do32bpt ? &_savage_texformat_a1118888 : &_savage_texformat_a1114444); case GL_ALPHA4: - return isSavage4 ? &_mesa_texformat_a8 : &_mesa_texformat_argb4444; + return isSavage4 ? &_mesa_texformat_a8 : &_savage_texformat_a1114444; case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: return isSavage4 ? &_mesa_texformat_a8 : ( - !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444); + !force16bpt ? &_savage_texformat_a1118888 : &_savage_texformat_a1114444); case 1: case GL_LUMINANCE: @@ -1321,13 +1488,12 @@ static void savageUpdateTexState_s3d( GLcontext *ctx ) GLuint format; /* disable */ - if (ctx->Texture.Unit[0]._ReallyEnabled == 0) { - imesa->regs.s3d.texCtrl.ui = 0; - imesa->regs.s3d.texCtrl.ni.texEn = GL_FALSE; - imesa->regs.s3d.texCtrl.ni.dBias = 0x08; - imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE; + imesa->regs.s3d.texCtrl.ui = 0; + imesa->regs.s3d.texCtrl.ni.texEn = GL_FALSE; + imesa->regs.s3d.texCtrl.ni.dBias = 0x08; + imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE; + if (ctx->Texture.Unit[0]._ReallyEnabled == 0) return; - } tObj = ctx->Texture.Unit[0]._Current; if ((ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT)) @@ -1360,12 +1526,28 @@ static void savageUpdateTexState_s3d( GLcontext *ctx ) /* FIXME: copied from utah-glx, probably needs some tuning */ switch (ctx->Texture.Unit[0].EnvMode) { case GL_DECAL: - imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_DECAL_S3D; + imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_DECALALPHA_S3D; break; case GL_REPLACE: - imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_COPY_S3D; + switch (format) { + case GL_ALPHA: /* FIXME */ + imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = 1; + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = 4; + break; + case GL_RGB: + case GL_LUMINANCE: + imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_DECAL_S3D; + break; + case GL_INTENSITY: + imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_COPY_S3D; + } break; - case GL_BLEND: /* FIXIT */ + case GL_BLEND: /* hardware can't do GL_BLEND */ + FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); + return; case GL_MODULATE: imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_MODULATEALPHA_S3D; break; @@ -1378,14 +1560,16 @@ static void savageUpdateTexState_s3d( GLcontext *ctx ) imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE; imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE; - /* FIXME: this is how the utah-driver works. I doubt it's the ultimate - truth. */ + /* The Savage3D can't handle different wrapping modes in s and t. + * If they are not the same, fall back to software. */ + if (t->setup.sWrapMode != t->setup.tWrapMode) { + FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); + return; + } imesa->regs.s3d.texCtrl.ni.uWrapEn = 0; imesa->regs.s3d.texCtrl.ni.vWrapEn = 0; - if (t->setup.sWrapMode == GL_CLAMP) - imesa->regs.s3d.texCtrl.ni.wrapMode = TAM_Clamp; - else - imesa->regs.s3d.texCtrl.ni.wrapMode = TAM_Wrap; + imesa->regs.s3d.texCtrl.ni.wrapMode = + (t->setup.sWrapMode == GL_REPEAT) ? TAM_Wrap : TAM_Clamp; switch (t->setup.minFilter) { case GL_NEAREST: @@ -1766,4 +1950,20 @@ void savageDDInitTextureFuncs( struct dd_function_table *functions ) functions->DeleteTexture = savageDeleteTexture; functions->IsTextureResident = driIsTextureResident; functions->TexParameter = savageTexParameter; + + /* Texel fetching with our custom texture formats works just like + * the standard argb formats. */ + _savage_texformat_a1114444.FetchTexel1D = _mesa_texformat_argb4444.FetchTexel1D; + _savage_texformat_a1114444.FetchTexel2D = _mesa_texformat_argb4444.FetchTexel2D; + _savage_texformat_a1114444.FetchTexel3D = _mesa_texformat_argb4444.FetchTexel3D; + _savage_texformat_a1114444.FetchTexel1Df= _mesa_texformat_argb4444.FetchTexel1Df; + _savage_texformat_a1114444.FetchTexel2Df= _mesa_texformat_argb4444.FetchTexel2Df; + _savage_texformat_a1114444.FetchTexel3Df= _mesa_texformat_argb4444.FetchTexel3Df; + + _savage_texformat_a1118888.FetchTexel1D = _mesa_texformat_argb8888.FetchTexel1D; + _savage_texformat_a1118888.FetchTexel2D = _mesa_texformat_argb8888.FetchTexel2D; + _savage_texformat_a1118888.FetchTexel3D = _mesa_texformat_argb8888.FetchTexel3D; + _savage_texformat_a1118888.FetchTexel1Df= _mesa_texformat_argb8888.FetchTexel1Df; + _savage_texformat_a1118888.FetchTexel2Df= _mesa_texformat_argb8888.FetchTexel2Df; + _savage_texformat_a1118888.FetchTexel3Df= _mesa_texformat_argb8888.FetchTexel3Df; } |