From: Daniel Borca Date: Wed, 29 Oct 2003 14:40:43 +0000 (+0000) Subject: changes to accomodate texture compression X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=63a5ca08f3bdaee975c9b059caf15ffd3ddd8d38;p=mesa.git changes to accomodate texture compression --- diff --git a/src/mesa/drivers/glide/fxapi.c b/src/mesa/drivers/glide/fxapi.c index 2ebb451b2dd..b726240cba9 100644 --- a/src/mesa/drivers/glide/fxapi.c +++ b/src/mesa/drivers/glide/fxapi.c @@ -318,6 +318,7 @@ fxMesaCreateContext(GLuint win, } fxMesa->type = voodoo->type; + fxMesa->HavePalExt = voodoo->HavePalExt; fxMesa->HavePixExt = voodoo->HavePixExt; fxMesa->HaveTexFmt = voodoo->HaveTexFmt; fxMesa->HaveCmbExt = voodoo->HaveCmbExt; diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index fec2ee9d72a..895271fcbac 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -1427,6 +1427,13 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) fxDDInitExtensions(ctx); +#if 0 + /* [dBorca] Hack alert: + * do we want dither? It just looks bad... + */ + grEnable(GR_ALLOW_MIPMAP_DITHER); + grTexNccTable(GR_NCCTABLE_NCC0); /* set this once... no multipass */ +#endif grGlideGetState((GrState *) fxMesa->state); return 1; @@ -1474,15 +1481,36 @@ fxDDInitExtensions(GLcontext * ctx) _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" ); } -#if 0 /* not ready yet */ - /* banshee/avenger should enable this for NCC */ - _mesa_enable_extension( ctx, "GL_ARB_texture_compression" ); -#endif - if (0/*IS_NAPALM*/) { - /* tex_compress: not ready yet */ - _mesa_enable_extension( ctx, "GL_3DFX_texture_compression_FXT1" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); - /*_mesa_enable_extension( ctx, "GL_S3_s3tc" );*/ + /* [dBorca] Hack alert: + * True texture compression can be done only on Napalm. + * We will advertise, however, generic texture compression + * on all Voodoo cards; the Mesa logic allows us to eventually + * fallback to uncompressed. This will fix those dumb applications + * which refuse to run w/o texture compression! We actually _can_ + * do texture compression for pre-Napalm cores, through NCC. But + * NCC poses many issues: + * 1) NCC w/o DITHER_ERR has poor quality and NCC w/ DITHER_ERR is + * damn slow! + * 2) NCC compression cannot be used with multitexturing, because + * the decompression tables are not per TMU anymore (bear in mind + * that earlier Voodoos could handle 2 NCC tables for each TMU -- + * just look for POINTCAST_PALETTE). As a last resort, we could + * fake NCC multitexturing through multipass rendering, but... + * ohwell, it's not worth the effort... + * This stand true for multitexturing palletized textures. + * 3) since NCC is not an OpenGL standard (as opposed to FXT1), we + * would need to plug deeper into the core... First, we would need to + * bind NCC to GL_COMPRESSED_RGB[A]. Then, we would need to trick + * Mesa into reporting our texture as compressed. Last, we would need + * to stash the NCC decompression table into the mipmap data and adjust + * CompressedSize accordingly! + */ + _mesa_enable_extension(ctx, "GL_ARB_texture_compression"); + + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + _mesa_enable_extension(ctx, "GL_3DFX_texture_compression_FXT1"); + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + /*_mesa_enable_extension(ctx, "GL_S3_s3tc");*/ } if (fxMesa->HaveCmbExt) { @@ -1697,11 +1725,13 @@ fxSetupDDPointers(GLcontext * ctx) ctx->Driver.TexSubImage2D = fxDDTexSubImage2D; ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; - ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage2D = fxDDCompressedTexImage2D; ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; - ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage2D = fxDDCompressedTexSubImage2D; ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + ctx->Driver.IsCompressedFormat = fxDDIsCompressedFormat; + ctx->Driver.CompressedTextureSize = fxDDCompressedTextureSize; ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; diff --git a/src/mesa/drivers/glide/fxddtex.c b/src/mesa/drivers/glide/fxddtex.c index 8b64a8e2c68..bfff09aea17 100644 --- a/src/mesa/drivers/glide/fxddtex.c +++ b/src/mesa/drivers/glide/fxddtex.c @@ -367,8 +367,8 @@ fxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj) /* * Convert a gl_color_table texture palette to Glide's format. */ -static void -convertPalette(FxU32 data[256], const struct gl_color_table *table) +static GrTexTable_t +convertPalette(const fxMesaContext fxMesa, FxU32 data[256], const struct gl_color_table *table) { const GLubyte *tableUB = (const GLubyte *) table->Table; GLint width = table->Size; @@ -386,7 +386,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = tableUB[i]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; case GL_LUMINANCE: for (i = 0; i < width; i++) { r = tableUB[i]; @@ -395,21 +395,22 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = 255; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return GR_TEXTABLE_PALETTE; case GL_ALPHA: for (i = 0; i < width; i++) { r = g = b = 255; a = tableUB[i]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; case GL_LUMINANCE_ALPHA: for (i = 0; i < width; i++) { r = g = b = tableUB[i * 2 + 0]; a = tableUB[i * 2 + 1]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; + default: case GL_RGB: for (i = 0; i < width; i++) { r = tableUB[i * 3 + 0]; @@ -418,7 +419,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = 255; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return GR_TEXTABLE_PALETTE; case GL_RGBA: for (i = 0; i < width; i++) { r = tableUB[i * 4 + 0]; @@ -427,7 +428,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = tableUB[i * 4 + 3]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return fxMesa->HavePalExt ? GR_TEXTABLE_PALETTE_6666_EXT : GR_TEXTABLE_PALETTE; } } @@ -447,7 +448,7 @@ fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj) if (!tObj->DriverData) tObj->DriverData = fxAllocTexObjData(fxMesa); ti = fxTMGetTexInfo(tObj); - convertPalette(ti->palette.data, &tObj->Palette); + ti->paltype = convertPalette(fxMesa, ti->palette.data, &tObj->Palette); fxTexInvalidate(ctx, tObj); } else { @@ -455,7 +456,7 @@ fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj) if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "%s(global)\n", __FUNCTION__); } - convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette); + fxMesa->glbPalType = convertPalette(fxMesa, fxMesa->glbPalette.data, &ctx->Texture.Palette); fxMesa->new_state |= FX_NEW_TEXTURING; } } @@ -473,7 +474,7 @@ fxDDTexUseGlbPalette(GLcontext * ctx, GLboolean state) if (state) { fxMesa->haveGlobalPaletteTexture = 1; - grTexDownloadTable(GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette)); + grTexDownloadTable(fxMesa->glbPalType, &(fxMesa->glbPalette)); } else { fxMesa->haveGlobalPaletteTexture = 0; @@ -856,6 +857,127 @@ PrintTexture(int w, int h, int c, const GLubyte * data) } +#define fxDDIsCompressedFormatMacro(internalFormat) (\ + ((internalFormat) == GL_COMPRESSED_RGB_FXT1_3DFX) || \ + ((internalFormat) == GL_COMPRESSED_RGBA_FXT1_3DFX) || \ + ((internalFormat) == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) || \ + ((internalFormat) == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || \ + ((internalFormat) == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || \ + ((internalFormat) == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)) + +/* [dBorca] + * we are handling differently the above formats from the generic + * GL_COMPRESSED_RGB[A]. For this, we will never call the function + * below! It is just a callback for core functions. + */ + +GLboolean fxDDIsCompressedFormat ( GLcontext *ctx, GLenum internalFormat ) +{ + if (fxDDIsCompressedFormatMacro(internalFormat)) { + return GL_TRUE; + } + +#if FX_TC_NCC || FX_TC_NAPALM + if ((internalFormat == GL_COMPRESSED_RGB) || (internalFormat == GL_COMPRESSED_RGBA)) { + return GL_TRUE; + } +#endif + + return GL_FALSE; +} + + +GLuint fxDDCompressedTextureSize (GLcontext *ctx, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format) +{ + GLuint size; + int wScale, hScale; + + ASSERT(depth == 1); + + /* Determine width and height scale factors for texture. + * Remember, Glide is limited to 8:1 aspect ratios. + */ + fxTexGetInfo(width, height, + NULL, /* lod level */ + NULL, /* aspect ratio */ + NULL, NULL, /* sscale, tscale */ + &wScale, &hScale); + + width *= wScale; + height *= hScale; + + switch (format) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + /* round up to multiple of 4 */ + size = ((width + 7) / 8) * ((height + 3) / 4) * 16; + /* Textures smaller than 4x4 will effectively be made into 4x4 and + * take 8 bytes. + */ + if (size < 16) + size = 16; + return size; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + /* round up width, height to next multiple of 4 */ + width = (width + 3) & ~3; + height = (height + 3) & ~3; + /* 8 bytes per 4x4 tile of RGB[A] texels */ + size = (width * height * 8) / 16; + /* Textures smaller than 4x4 will effectively be made into 4x4 and + * take 8 bytes. + */ + if (size < 8) + size = 8; + return size; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + /* round up width, height to next multiple of 4 */ + width = (width + 3) & ~3; + height = (height + 3) & ~3; + /* 16 bytes per 4x4 tile of RGBA texels */ + size = width * height; /* simple! */ + /* Textures smaller than 4x4 will effectively be made into 4x4 and + * take 16 bytes. + */ + if (size < 16) + size = 16; + return size; + case GL_COMPRESSED_RGB: +#if FX_TC_NAPALM + { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + return fxDDCompressedTextureSize(ctx, width, height, 1, GL_COMPRESSED_RGB_FXT1_3DFX); + } + } +#endif +#if FX_TC_NCC + /* should really use `txBitsPerPixel' instead of 8; also add NCC table */ + return (width * height * 8 >> 3) + 12 * 4; +#endif + case GL_COMPRESSED_RGBA: +#if FX_TC_NAPALM + { + fxMesaContext fxMesa = FX_CONTEXT(ctx); + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + return fxDDCompressedTextureSize(ctx, width, height, 1, GL_COMPRESSED_RGBA_FXT1_3DFX); + } + } +#endif +#if FX_TC_NCC + /* should really use `txBitsPerPixel' instead of 16; also add NCC table */ + return (width * height * 16 >> 3) + 12 * 4; +#endif + default: + _mesa_problem(ctx, "bad texformat in fxDDCompressedTextureSize"); + return 0; + } +} + + const struct gl_texture_format * fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, GLenum srcFormat, GLenum srcType ) @@ -871,7 +993,7 @@ fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, * 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 + * _mesa_texformat_rgb565 or _mesa_texformat_argb8888 * 4) at some point, we encounter total rasterization fallback * 5) displaying a polygon with the above textures yield garbage on areas * where pixel is larger than a texel, because our already set texel @@ -966,7 +1088,6 @@ fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, : &_mesa_texformat_argb4444; case GL_RGB5_A1: return &_mesa_texformat_argb1555; -#if 0 /* GL_EXT_texture_compression_s3tc */ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return &_mesa_texformat_rgb_dxt1; @@ -976,10 +1097,11 @@ fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, return &_mesa_texformat_rgba_dxt3; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return &_mesa_texformat_rgba_dxt5; - /*case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return blah;*/ -#endif + /* GL_3DFX_texture_compression_FXT1 */ + case GL_COMPRESSED_RGB_FXT1_3DFX: + return &_mesa_texformat_rgb_fxt1; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return &_mesa_texformat_rgba_fxt1; default: _mesa_problem(NULL, "unexpected format in fxDDChooseTextureFormat"); return NULL; @@ -1009,7 +1131,9 @@ fxGlideFormat(GLint mesaFormat) return GR_TEXFMT_ARGB_1555; case MESA_FORMAT_ARGB8888: return GR_TEXFMT_ARGB_8888; -#if 0 + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return GR_TEXFMT_ARGB_CMP_FXT1; case MESA_FORMAT_RGB_DXT1: case MESA_FORMAT_RGBA_DXT1: return GR_TEXFMT_ARGB_CMP_DXT1; @@ -1017,11 +1141,6 @@ fxGlideFormat(GLint mesaFormat) return GR_TEXFMT_ARGB_CMP_DXT3; case MESA_FORMAT_RGBA_DXT5: return GR_TEXFMT_ARGB_CMP_DXT5; - /*case MESA_FORMAT_ARGB_CMP_FXT1: - return GR_TEXFMT_ARGB_CMP_FXT1; - case MESA_FORMAT_RGB_CMP_FXT1: - return GL_COMPRESSED_RGBA_FXT1_3DFX;*/ -#endif default: _mesa_problem(NULL, "Unexpected format in fxGlideFormat"); return 0; @@ -1051,13 +1170,13 @@ fxFetchFunction(GLint mesaFormat) return fetch_r5g5b5a1; case MESA_FORMAT_ARGB8888: return fetch_a8r8g8b8; -#if 0 + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: case MESA_FORMAT_RGB_DXT1: case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGBA_DXT3: case MESA_FORMAT_RGBA_DXT5: return fetch_r4g4b4a4; -#endif default: _mesa_problem(NULL, "Unexpected format in fxFetchFunction"); return NULL; @@ -1077,6 +1196,10 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, tfxMipMapLevel *mml; GLint texelBytes; + GLvoid *_final_texImage_Data; + const struct gl_texture_format *_final_texImage_TexFormat; + GLboolean isCompressed = fxDDIsCompressedFormatMacro(internalFormat); + if (TDFX_DEBUG & VERBOSE_TEXTURE) { fprintf(stderr, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n", texObj->Name, texImage->IntFormat, format, type, @@ -1121,6 +1244,55 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, texelBytes = texImage->TexFormat->TexelBytes; /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/ + mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + /* dirty trick: will thrash CopyTex[Sub]Image */ +#if FX_TC_NCC || FX_TC_NAPALM + if (internalFormat == GL_COMPRESSED_RGB) { +#if FX_TC_NCC + isCompressed = GL_TRUE; + mml->glideFormat = GR_TEXFMT_YIQ_422; +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + isCompressed = GL_TRUE; + mml->glideFormat = GR_TEXFMT_ARGB_CMP_FXT1; + } +#endif + } else if (internalFormat == GL_COMPRESSED_RGBA) { +#if FX_TC_NCC + isCompressed = GL_TRUE; + mml->glideFormat = GR_TEXFMT_AYIQ_8422; +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + isCompressed = GL_TRUE; + mml->glideFormat = GR_TEXFMT_ARGB_CMP_FXT1; + } +#endif + } +#endif + + /* allocate mipmap buffer */ + assert(!texImage->Data); + if (isCompressed) { + texImage->Data = MESA_PBUFFER_ALLOC(texImage->CompressedSize); + texelBytes = 4; + _final_texImage_TexFormat = &_mesa_texformat_argb8888; + _final_texImage_Data = MALLOC(mml->width * mml->height * 4); + if (!_final_texImage_Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } else { + texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); + _final_texImage_TexFormat = texImage->TexFormat; + _final_texImage_Data = texImage->Data; + } + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + if (mml->wScale != 1 || mml->hScale != 1) { /* rescale image to overcome 1:8 aspect limitation */ GLvoid *tempImage; @@ -1131,51 +1303,57 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, } /* unpack image, apply transfer ops and store in tempImage */ _mesa_transfer_teximage(ctx, 2, texImage->Format, - texImage->TexFormat, + _final_texImage_TexFormat, tempImage, width, height, 1, 0, 0, 0, width * texelBytes, 0, /* dstImageStride */ format, type, pixels, packing); - assert(!texImage->Data); - texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - FREE(tempImage); - return; - } _mesa_rescale_teximage2d(texelBytes, mml->width * texelBytes, /* dst stride */ width, height, mml->width, mml->height, - tempImage /*src*/, texImage->Data /*dst*/ ); + tempImage /*src*/, _final_texImage_Data /*dst*/ ); FREE(tempImage); } else { /* no rescaling needed */ - assert(!texImage->Data); - texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } /* unpack image, apply transfer ops and store in texImage->Data */ _mesa_transfer_teximage(ctx, 2, texImage->Format, - texImage->TexFormat, texImage->Data, + _final_texImage_TexFormat, _final_texImage_Data, width, height, 1, 0, 0, 0, texImage->Width * texelBytes, 0, /* dstImageStride */ format, type, pixels, packing); } - mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + /* now compress */ + if (isCompressed) { +#if FX_TC_NCC + if ((mml->glideFormat == GR_TEXFMT_AYIQ_8422) || + (mml->glideFormat == GR_TEXFMT_YIQ_422)) { + TxMip txMip, pxMip; + txMip.width = mml->width; + txMip.height = mml->height; + txMip.depth = 1; + txMip.data[0] = _final_texImage_Data; + pxMip.data[0] = texImage->Data; + fxMesa->Glide.txMipQuantize(&pxMip, &txMip, mml->glideFormat, TX_DITHER_ERR, TX_COMPRESSION_STATISTICAL); + fxMesa->Glide.txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal); + MEMCPY((char *)texImage->Data + texImage->CompressedSize - 12 * 4, &(ti->palette), 12 * 4); + } else +#endif + fxMesa->Glide.txImgQuantize(texImage->Data, _final_texImage_Data, mml->width, mml->height, mml->glideFormat, TX_DITHER_NONE); + FREE(_final_texImage_Data); + } + ti->info.format = mml->glideFormat; texImage->FetchTexel = fxFetchFunction(texImage->TexFormat->MesaFormat); /* [dBorca] * Hack alert: unsure... */ - if (!(fxMesa->new_state & FX_NEW_TEXTURING) && ti->validated && ti->isInTM) { + if (0 && ti->validated && ti->isInTM) { /*fprintf(stderr, "reloadmipmaplevels\n"); */ fxTMReloadMipMapLevel(fxMesa, texObj, level); } @@ -1200,6 +1378,10 @@ fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, tfxMipMapLevel *mml; GLint texelBytes; + /* [dBorca] Hack alert: + * fix the goddamn texture compression here + */ + if (TDFX_DEBUG & VERBOSE_TEXTURE) { fprintf(stderr, "fxDDTexSubImage2D: id=%d\n", texObj->Name); } @@ -1269,7 +1451,181 @@ fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, /* [dBorca] * Hack alert: unsure... */ - if (!(fxMesa->new_state & FX_NEW_TEXTURING) && ti->validated && ti->isInTM) + if (0 && ti->validated && ti->isInTM) + fxTMReloadMipMapLevel(fxMesa, texObj, level); + else + fxTexInvalidate(ctx, texObj); +} + + +void +fxDDCompressedTexImage2D (GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrTextureFormat_t gldFormat; + tfxTexInfo *ti; + tfxMipMapLevel *mml; + GLint dstWidth, dstHeight, wScale, hScale; + + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxDDCompressedTexImage2D: id=%d int 0x%x %dx%d\n", + texObj->Name, internalFormat, + width, height); + } + + if (!fxIsTexSupported(target, internalFormat, texImage)) { + _mesa_problem(NULL, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n"); + return; + } + +#if FX_TC_NCC || FX_TC_NAPALM + if ((internalFormat != GL_COMPRESSED_RGB) && (internalFormat != GL_COMPRESSED_RGBA)) +#endif + if (!fxDDIsCompressedFormatMacro(internalFormat)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(format)"); + return; + } + + if (!texObj->DriverData) { + texObj->DriverData = fxAllocTexObjData(fxMesa); + if (!texObj->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } + } + ti = fxTMGetTexInfo(texObj); + + if (!texImage->DriverData) { + texImage->DriverData = CALLOC(sizeof(tfxMipMapLevel)); + if (!texImage->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + mml = FX_MIPMAP_DATA(texImage); + + /* Determine the appropriate Glide texel format, + * given the user's internal texture format hint. + */ + gldFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); +#if FX_TC_NCC || FX_TC_NAPALM + if (internalFormat == GL_COMPRESSED_RGB) { +#if FX_TC_NCC + gldFormat = GR_TEXFMT_YIQ_422; +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + gldFormat = GR_TEXFMT_ARGB_CMP_FXT1; + } +#endif + } else if (internalFormat == GL_COMPRESSED_RGBA) { +#if FX_TC_NCC + gldFormat = GR_TEXFMT_AYIQ_8422; +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + gldFormat = GR_TEXFMT_ARGB_CMP_FXT1; + } +#endif + } +#endif + + /* Determine width and height scale factors for texture. + * Remember, Glide is limited to 8:1 aspect ratios. + */ + fxTexGetInfo(width, height, + NULL, /* lod level */ + NULL, /* aspect ratio */ + NULL, NULL, /* sscale, tscale */ + &wScale, &hScale); + dstWidth = width * wScale; + dstHeight = height * hScale; + + /* allocate new storage for texture image, if needed */ + if (!texImage->Data) { + texImage->Data = MESA_PBUFFER_ALLOC(imageSize); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + + /* save the texture data */ + MEMCPY(texImage->Data, data, imageSize); +#if FX_TC_NCC + if ((gldFormat == GR_TEXFMT_AYIQ_8422) || + (gldFormat == GR_TEXFMT_YIQ_422)) { + MEMCPY(&(ti->palette), (char *)texImage->Data + imageSize - 12 * 4, 12 * 4); + } +#endif + + /* [dBorca] Hack alert: + * what about different size/texel? other anomalies? SW rescaling? + */ + if (1 || mml->glideFormat != gldFormat || + mml->width != dstWidth || mml->height != dstHeight || + !ti->validated || !ti->isInTM || (fxMesa->new_state & FX_NEW_TEXTURING)) { + mml->glideFormat = gldFormat; + mml->width = dstWidth; + mml->height = dstHeight; + fxTexInvalidate(ctx, texObj); + } else { + fxTMReloadMipMapLevel(fxMesa, texObj, level); + } +} + + +void +fxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLint height, GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti; + tfxMipMapLevel *mml; + + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxDDCompressedTexSubImage2D: id=%d\n", texObj->Name); + } + + ti = fxTMGetTexInfo(texObj); + assert(ti); + mml = FX_MIPMAP_DATA(texImage); + assert(mml); + + /* + * We punt if we are not replacing the entire image. This + * is allowed by the spec. + * + * [dBorca] Hack alert: + * ohwell, we should NOT! Look into _mesa_store_compressed_texsubimage2d + * on how to calculate the sub-image. + */ + if ((xoffset != 0) && (yoffset != 0) + && (width != texImage->Width) + && (height != texImage->Height)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(CHICKEN)"); + return; + } + + /* [dBorca] Hack alert: + * what about different size/texel? other anomalies? SW rescaling? + */ + MEMCPY(texImage->Data, data, imageSize); + + /* [dBorca] + * Hack alert: unsure... + */ + if (0 && ti->validated && ti->isInTM) fxTMReloadMipMapLevel(fxMesa, texObj, level); else fxTexInvalidate(ctx, texObj); diff --git a/src/mesa/drivers/glide/fxdrv.h b/src/mesa/drivers/glide/fxdrv.h index 996c1be2bb4..46b53574a99 100644 --- a/src/mesa/drivers/glide/fxdrv.h +++ b/src/mesa/drivers/glide/fxdrv.h @@ -286,6 +286,7 @@ typedef struct tfxTexInfo_t GLfloat sScale, tScale; + GrTexTable_t paltype; GuTexPalette palette; GLboolean fixedPalette; @@ -426,6 +427,7 @@ typedef void (*fx_point_func) (fxMesaContext, GrVertex *); struct tfxMesaContext { + GrTexTable_t glbPalType; GuTexPalette glbPalette; GLcontext *glCtx; /* the core Mesa context */ @@ -534,6 +536,7 @@ struct tfxMesaContext * from `glbHWConfig' when creating a new context... */ GrSstType type; + FxBool HavePalExt; /* PALETTE6666 */ FxBool HavePixExt; /* PIXEXT */ FxBool HaveTexFmt; /* TEXFMT */ FxBool HaveCmbExt; /* COMBINE */ @@ -577,6 +580,10 @@ extern void fxPrintTextureData(tfxTexInfo * ti); extern const struct gl_texture_format * fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, GLenum srcFormat, GLenum srcType ); +extern GLboolean fxDDIsCompressedFormat (GLcontext *ctx, GLenum internalFormat); +extern GLuint fxDDCompressedTextureSize (GLcontext *ctx, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format); extern void fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, @@ -584,7 +591,6 @@ extern void fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage); - extern void fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, @@ -593,6 +599,19 @@ extern void fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage); +extern void fxDDCompressedTexImage2D(GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +extern void fxDDCompressedTexSubImage2D(GLcontext *ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLint height, GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); extern void fxDDTexEnv(GLcontext *, GLenum, GLenum, const GLfloat *); extern void fxDDTexParam(GLcontext *, GLenum, struct gl_texture_object *, GLenum, const GLfloat *); diff --git a/src/mesa/drivers/glide/fxg.c b/src/mesa/drivers/glide/fxg.c index bb162c5808c..1ead397fddb 100644 --- a/src/mesa/drivers/glide/fxg.c +++ b/src/mesa/drivers/glide/fxg.c @@ -40,17 +40,25 @@ #define DEBUG_TRAP_internal #include "fxg.h" +/* texus.h */ +FX_ENTRY int FX_CALL txBitsPerPixel (GrTextureFormat_t format); +FX_ENTRY void FX_CALL txImgQuantize (char *dst, char *src, int w, int h, FxU32 format, FxU32 dither); +FX_ENTRY void FX_CALL txMipQuantize (TxMip *pxMip, TxMip *txMip, int fmt, FxU32 d, FxU32 comp); +FX_ENTRY void FX_CALL txPalToNcc (GuNccTable *ncc_table, const FxU32 *pal); +FX_ENTRY void FX_CALL txErrorSetCallback (TxErrorCallbackFnc_t fnc, TxErrorCallbackFnc_t *old_fnc); +/* texus.h */ + /****************************************************************************\ * logging * \****************************************************************************/ #if DEBUG_TRAP -#define TRAP_LOG trap_printf +#define TRAP_LOG trp_printf #ifdef __GNUC__ __attribute__ ((format(printf, 1, 2))) #endif /* __GNUC__ */ -int trap_printf (const char *format, ...) +int trp_printf (const char *format, ...) { va_list arg; int n; @@ -234,8 +242,10 @@ const char *TRP_BLEND (GrAlphaBlendFnc_t func) TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SRC_COLOR); /*TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_DST_COLOR); ==GR_BLEND_ONE_MINUS_SRC_COLOR*/ TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_DST_ALPHA); - TRAP_CASE_STRING(GR_BLEND_RESERVED_8); - TRAP_CASE_STRING(GR_BLEND_RESERVED_9); + TRAP_CASE_STRING(GR_BLEND_SAME_COLOR_EXT); + /*TRAP_CASE_STRING(GR_BLEND_RESERVED_8); ==GR_BLEND_SAME_COLOR_EXT*/ + TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SAME_COLOR_EXT); + /*TRAP_CASE_STRING(GR_BLEND_RESERVED_9); ==GR_BLEND_ONE_MINUS_SAME_COLOR_EXT*/ TRAP_CASE_STRING(GR_BLEND_RESERVED_A); TRAP_CASE_STRING(GR_BLEND_RESERVED_B); TRAP_CASE_STRING(GR_BLEND_RESERVED_C); @@ -243,8 +253,6 @@ 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; } } @@ -785,6 +793,25 @@ const char *TRP_TMU (GrChipID_t tmu) } } +const char *TRP_TXDITHER (FxU32 dither) +{ + switch (dither) { + TRAP_CASE_STRING(TX_DITHER_NONE); + TRAP_CASE_STRING(TX_DITHER_4x4); + TRAP_CASE_STRING(TX_DITHER_ERR); + TRAP_NODEFAULT; + } +} + +const char *TRP_TXCOMPRESS (FxU32 compress) +{ + switch (compress) { + TRAP_CASE_STRING(TX_COMPRESSION_STATISTICAL); + TRAP_CASE_STRING(TX_COMPRESSION_HEURISTIC); + TRAP_NODEFAULT; + } +} + /****************************************************************************\ @@ -801,6 +828,11 @@ void (FX_CALL *real_grChromaRangeExt) (GrColor_t color, GrColor_t range, GrChrom void (FX_CALL *real_grTexChromaModeExt) (GrChipID_t tmu, GrChromakeyMode_t mode); void (FX_CALL *real_grTexChromaRangeExt) (GrChipID_t tmu, GrColor_t min, GrColor_t max, GrTexChromakeyMode_t mode); +/* pointcast */ +void (FX_CALL *real_grTexDownloadTableExt) (GrChipID_t tmu, GrTexTable_t type, void *data); +void (FX_CALL *real_grTexDownloadTablePartialExt) (GrChipID_t tmu, GrTexTable_t type, void *data, int start, int end); +void (FX_CALL *real_grTexNCCTableExt) (GrChipID_t tmu, GrNCCTable_t table); + /* tbext */ void (FX_CALL *real_grTextureBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask); void (FX_CALL *real_grTextureAuxBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask); @@ -1857,6 +1889,41 @@ void FX_CALL trap_grTexChromaRangeExt (GrChipID_t tmu, assert(real_grTexChromaRangeExt); (*real_grTexChromaRangeExt)(tmu, min, max, mode); #undef FN_NAME +} + + /* pointcast */ +void FX_CALL trap_grTexDownloadTableExt (GrChipID_t tmu, + GrTexTable_t type, + void *data) +{ +#define FN_NAME "grTexDownloadTableExt" + TRAP_LOG("%s(%s, %s, %p)\n", FN_NAME, TRP_TMU(tmu), TRP_TABLE(type), data); + assert(real_grTexDownloadTableExt); + (*real_grTexDownloadTableExt)(tmu, type, data); +#undef FN_NAME +} + +void FX_CALL trap_grTexDownloadTablePartialExt (GrChipID_t tmu, + GrTexTable_t type, + void *data, + int start, + int end) +{ +#define FN_NAME "grTexDownloadTablePartialExt" + TRAP_LOG("%s(%s, %s, %p, %d, %d)\n", FN_NAME, TRP_TMU(tmu), TRP_TABLE(type), data, start, end); + assert(real_grTexDownloadTablePartialExt); + (*real_grTexDownloadTablePartialExt)(tmu, type, data, start, end); +#undef FN_NAME +} + +void FX_CALL trap_grTexNCCTableExt (GrChipID_t tmu, + GrNCCTable_t table) +{ +#define FN_NAME "grTexNCCTableExt" + TRAP_LOG("%s(%s, %s)\n", FN_NAME, TRP_TMU(tmu), TRP_NCC(table)); + assert(real_grTexNCCTableExt); + (*real_grTexNCCTableExt)(tmu, table); +#undef FN_NAME } /* tbext */ @@ -2089,10 +2156,94 @@ void FX_CALL trap_grTBufferWriteMaskExt (FxU32 tmask) (*real_grTBufferWriteMaskExt)(tmask); #undef FN_NAME } + +/* +** texus functions +*/ +int FX_CALL trap_txBitsPerPixel (GrTextureFormat_t format) +{ +#define FN_NAME "txBitsPerPixel" + int rv; + TRAP_LOG("%s(%s)\n", FN_NAME, TRP_TEXFMT(format)); + rv = txBitsPerPixel(format); + TRAP_LOG(GOT "%d\n", rv); + return rv; +#undef FN_NAME +} + +void FX_CALL trap_txImgQuantize (char *dst, + char *src, + int w, + int h, + FxU32 format, + FxU32 dither) +{ +#define FN_NAME "txImgQuantize" + TRAP_LOG("%s(%p, %p, %d, %d, %s, %s)\n", FN_NAME, dst, src, w, h, TRP_TEXFMT(format), TRP_TXDITHER(dither)); + txImgQuantize(dst, src, w, h, format, dither); +#undef FN_NAME +} + +void FX_CALL trap_txMipQuantize (TxMip *pxMip, + TxMip *txMip, + int fmt, + FxU32 d, + FxU32 comp) +{ +#define FN_NAME "txMipQuantize" + TRAP_LOG("%s(%p, %p, %s, %s, %s)\n", FN_NAME, (void *)pxMip, (void *)txMip, TRP_TEXFMT(fmt), TRP_TXDITHER(d), TRP_TXCOMPRESS(comp)); + txMipQuantize(pxMip, txMip, fmt, d, comp); +#undef FN_NAME +} + +void FX_CALL trap_txPalToNcc (GuNccTable *ncc_table, + const FxU32 *pal) +{ +#define FN_NAME "txPalToNcc" + TRAP_LOG("%s(%p, %p)\n", FN_NAME, (void *)ncc_table, (void *)pal); + txPalToNcc(ncc_table, pal); +#undef FN_NAME +} + +void FX_CALL trap_txErrorSetCallback (TxErrorCallbackFnc_t fnc, + TxErrorCallbackFnc_t *old_fnc) +{ +#define FN_NAME "txErrorSetCallback" + TRAP_LOG("%s(%p, %p)\n", FN_NAME, (void *)fnc, (void *)old_fnc); + txErrorSetCallback(fnc, old_fnc); +#undef FN_NAME +} #endif +/****************************************************************************\ +* housekeeping (fake pointers) +\****************************************************************************/ +void FX_CALL fake_grTexDownloadTableExt (GrChipID_t tmu, + GrTexTable_t type, + void *data) +{ + grTexDownloadTable(type, data); +} + +void FX_CALL fake_grTexDownloadTablePartialExt (GrChipID_t tmu, + GrTexTable_t type, + void *data, + int start, + int end) +{ + grTexDownloadTablePartial(type, data, start, end); +} + +void FX_CALL fake_grTexNCCTableExt (GrChipID_t tmu, + GrNCCTable_t table) +{ + grTexNCCTable(table); +} + + + /****************************************************************************\ * interface \****************************************************************************/ @@ -2100,8 +2251,10 @@ void tdfx_hook_glide (struct tdfx_glide *Glide) { #if DEBUG_TRAP #define GET_EXT_ADDR(name) *(GrProc *)&real_##name = grGetProcAddress(#name), Glide->name = trap_##name +#define GET_TXS_ADDR(name) Glide->name = trap_##name #else /* DEBUG_TRAP */ #define GET_EXT_ADDR(name) *(GrProc *)&Glide->name = grGetProcAddress(#name) +#define GET_TXS_ADDR(name) Glide->name = name #endif /* DEBUG_TRAP */ /* @@ -2113,6 +2266,10 @@ void tdfx_hook_glide (struct tdfx_glide *Glide) GET_EXT_ADDR(grChromaRangeExt); GET_EXT_ADDR(grTexChromaModeExt); GET_EXT_ADDR(grTexChromaRangeExt); + /* pointcast */ + GET_EXT_ADDR(grTexDownloadTableExt); + GET_EXT_ADDR(grTexDownloadTablePartialExt); + GET_EXT_ADDR(grTexNCCTableExt); /* tbext */ GET_EXT_ADDR(grTextureBufferExt); GET_EXT_ADDR(grTextureAuxBufferExt); @@ -2133,8 +2290,29 @@ void tdfx_hook_glide (struct tdfx_glide *Glide) GET_EXT_ADDR(grAlphaBlendFunctionExt); GET_EXT_ADDR(grTBufferWriteMaskExt); + /* + ** texus + */ + GET_TXS_ADDR(txBitsPerPixel); + GET_TXS_ADDR(txImgQuantize); + GET_TXS_ADDR(txMipQuantize); + GET_TXS_ADDR(txPalToNcc); + GET_TXS_ADDR(txErrorSetCallback); + + /* housekeeping: make sure the pointcast always point to something valid */ + if (grGetProcAddress("grTexDownloadTableExt") == NULL) { +#if DEBUG_TRAP + real_grTexDownloadTableExt = fake_grTexDownloadTableExt; + real_grTexDownloadTablePartialExt = fake_grTexDownloadTablePartialExt; + real_grTexNCCTableExt = fake_grTexNCCTableExt; +#else + Glide->grTexDownloadTableExt = fake_grTexDownloadTableExt; + Glide->grTexDownloadTablePartialExt = fake_grTexDownloadTablePartialExt; + Glide->grTexNCCTableExt = fake_grTexNCCTableExt; +#endif + } + #undef GET_EXT_ADDR } - #endif /* FX */ diff --git a/src/mesa/drivers/glide/fxg.h b/src/mesa/drivers/glide/fxg.h index 234e52aee8c..cae63cb69f2 100644 --- a/src/mesa/drivers/glide/fxg.h +++ b/src/mesa/drivers/glide/fxg.h @@ -307,6 +307,30 @@ void FX_CALL trap_guFogGenerateLinear (GrFog_t *fogtable, float nearZ, float far #endif /* DEBUG_TRAP_internal */ #endif /* DEBUG_TRAP */ + + +/* */ +#define TX_MAX_LEVEL 16 +typedef struct _TxMip { + int format; + int width; + int height; + int depth; + int size; + void *data[TX_MAX_LEVEL]; + FxU32 pal[256]; +} TxMip; +typedef void (*TxErrorCallbackFnc_t) (const char *string, FxBool fatal); +#define TX_DITHER_NONE 0x00000000 +#define TX_DITHER_4x4 0x00000001 +#define TX_DITHER_ERR 0x00000002 + +#define TX_COMPRESSION_STATISTICAL 0x00000000 +#define TX_COMPRESSION_HEURISTIC 0x00000010 +/* */ + + + struct tdfx_glide { /* ** glide extensions @@ -318,6 +342,11 @@ struct tdfx_glide { void (FX_CALL *grTexChromaModeExt) (GrChipID_t tmu, GrChromakeyMode_t mode); void (FX_CALL *grTexChromaRangeExt) (GrChipID_t tmu, GrColor_t min, GrColor_t max, GrTexChromakeyMode_t mode); + /* pointcast */ + void (FX_CALL *grTexDownloadTableExt) (GrChipID_t tmu, GrTexTable_t type, void *data); + void (FX_CALL *grTexDownloadTablePartialExt) (GrChipID_t tmu, GrTexTable_t type, void *data, int start, int end); + void (FX_CALL *grTexNCCTableExt) (GrChipID_t tmu, GrNCCTable_t table); + /* tbext */ void (FX_CALL *grTextureBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask); void (FX_CALL *grTextureAuxBufferExt) (GrChipID_t tmu, FxU32 startAddress, GrLOD_t thisLOD, GrLOD_t largeLOD, GrAspectRatio_t aspectRatio, GrTextureFormat_t format, FxU32 odd_even_mask); @@ -342,9 +371,11 @@ struct tdfx_glide { /* ** Texus2 functions */ - void (*txImgQuantize) (void *xxx_unknown_arguments); - void (*txImgDequantizeFXT1) (void *txMip, void *pxMip); - void (*txErrorSetCallback) (void *fnc); + int (FX_CALL *txBitsPerPixel) (GrTextureFormat_t format); + void (FX_CALL *txImgQuantize) (char *dst, char *src, int w, int h, FxU32 format, FxU32 dither); + void (FX_CALL *txMipQuantize) (TxMip *pxMip, TxMip *txMip, int fmt, FxU32 d, FxU32 comp); + void (FX_CALL *txPalToNcc) (GuNccTable *ncc_table, const FxU32 *pal); + void (FX_CALL *txErrorSetCallback) (TxErrorCallbackFnc_t fnc, TxErrorCallbackFnc_t *old_fnc); }; void tdfx_hook_glide (struct tdfx_glide *Glide); diff --git a/src/mesa/drivers/glide/fxglidew.c b/src/mesa/drivers/glide/fxglidew.c index 0e6ff6a5303..ff4454d9a8f 100644 --- a/src/mesa/drivers/glide/fxglidew.c +++ b/src/mesa/drivers/glide/fxglidew.c @@ -224,6 +224,7 @@ FX_grSstQueryHardware(GrHwConfiguration * config) } extension = grGetString(GR_EXTENSION); + config->SSTs[i].HavePalExt = (strstr(extension, " PALETTE6666 ") != NULL); config->SSTs[i].HavePixExt = (strstr(extension, " PIXEXT ") != NULL); config->SSTs[i].HaveTexFmt = (strstr(extension, " TEXFMT ") != NULL); config->SSTs[i].HaveCmbExt = (strstr(extension, " COMBINE ") != NULL); diff --git a/src/mesa/drivers/glide/fxglidew.h b/src/mesa/drivers/glide/fxglidew.h index 7f7bd692ee0..31a8fa3b02e 100644 --- a/src/mesa/drivers/glide/fxglidew.h +++ b/src/mesa/drivers/glide/fxglidew.h @@ -72,6 +72,7 @@ typedef struct { int numChips; /* Number of Voodoo chips */ GrTMUConfig_t tmuConfig[GLIDE_NUM_TMU]; /* Configuration of the Texelfx chips */ /* Glide3 extensions */ + FxBool HavePalExt; /* PALETTE6666 */ FxBool HavePixExt; /* PIXEXT */ FxBool HaveTexFmt; /* TEXFMT */ FxBool HaveCmbExt; /* COMBINE */ diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c index 40fd4a5f9cf..6e929257dbf 100644 --- a/src/mesa/drivers/glide/fxsetup.c +++ b/src/mesa/drivers/glide/fxsetup.c @@ -327,13 +327,23 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) } if (ti->LODblend && ti->whichTMU == FX_TMU_SPLIT) { + /* broadcast */ if ((ti->info.format == GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) { if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "%s: uploading texture palette\n", __FUNCTION__); } - grTexDownloadTable(GR_TEXTABLE_PALETTE, &(ti->palette)); + grTexDownloadTable(ti->paltype, &(ti->palette)); } +#if FX_TC_NCC + if ((ti->info.format == GR_TEXFMT_AYIQ_8422) || + (ti->info.format == GR_TEXFMT_YIQ_422)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading NCC table\n", __FUNCTION__); + } + grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette)); + } +#endif grTexClampMode(GR_TMU0, ti->sClamp, ti->tClamp); grTexClampMode(GR_TMU1, ti->sClamp, ti->tClamp); @@ -353,13 +363,23 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) else tmu = ti->whichTMU; + /* pointcast */ if ((ti->info.format == GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) { if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "%s: uploading texture palette\n", __FUNCTION__); } - grTexDownloadTable(GR_TEXTABLE_PALETTE, &(ti->palette)); + fxMesa->Glide.grTexDownloadTableExt(tmu, ti->paltype, &(ti->palette)); + } +#if FX_TC_NCC + if ((ti->info.format == GR_TEXFMT_AYIQ_8422) || + (ti->info.format == GR_TEXFMT_YIQ_422)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading NCC table\n", __FUNCTION__); + } + fxMesa->Glide.grTexDownloadTableExt(tmu, GR_TEXTABLE_NCC0, &(ti->palette)); } +#endif /* KW: The alternative is to do the download to the other tmu. If * we get to this point, I think it means we are thrashing the @@ -784,17 +804,40 @@ fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa, } if (!fxMesa->haveGlobalPaletteTexture) { - /* [dBorca] - * all TMUs share the same table. - * The next test shouldn't be TMU specific... - */ + /* pointcast */ if (ti0->info.format == GR_TEXFMT_P_8) { if (TDFX_DEBUG & VERBOSE_DRIVER) { - fprintf(stderr, "%s: uploading texture palette TMU0\n", __FUNCTION__); + fprintf(stderr, "%s: uploading texture palette for TMU0\n", __FUNCTION__); + } + fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, ti0->paltype, &(ti0->palette)); + } +#if 1 + else /* does anyone guess why is this here? :D */ +#endif + if (ti1->info.format == GR_TEXFMT_P_8) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading texture palette for TMU1\n", __FUNCTION__); } - grTexDownloadTable(GR_TEXTABLE_PALETTE, &(ti0->palette)); + fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, ti1->paltype, &(ti1->palette)); + } + } +#if FX_TC_NCC + /* pointcast */ + if ((ti0->info.format == GR_TEXFMT_AYIQ_8422) || + (ti0->info.format == GR_TEXFMT_YIQ_422)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading NCC0 table for TMU0\n", __FUNCTION__); } + fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, GR_TEXTABLE_NCC0, &(ti0->palette)); } + if ((ti1->info.format == GR_TEXFMT_AYIQ_8422) || + (ti1->info.format == GR_TEXFMT_YIQ_422)) { + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "%s: uploading NCC0 table for TMU1\n", __FUNCTION__); + } + fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, GR_TEXTABLE_NCC0, &(ti1->palette)); + } +#endif grTexSource(tmu0, ti0->tm[tmu0]->startAddr, GR_MIPMAPLEVELMASK_BOTH, &(ti0->info)); diff --git a/src/mesa/drivers/glide/fxtris.c b/src/mesa/drivers/glide/fxtris.c index d60b8740270..08ecc6dd81b 100644 --- a/src/mesa/drivers/glide/fxtris.c +++ b/src/mesa/drivers/glide/fxtris.c @@ -530,6 +530,7 @@ static void init_rast_tab( void ) /* Accelerate vertex buffer rendering when renderindex == 0 and * there is no clipping. */ +#define INIT(x) fxRenderPrimitive( ctx, x ) static void fx_render_vb_points( GLcontext *ctx, GLuint start, @@ -545,7 +546,7 @@ static void fx_render_vb_points( GLcontext *ctx, fprintf(stderr, "fx_render_vb_points\n"); } - fxRenderPrimitive(ctx, GL_POINTS); + INIT(GL_POINTS); /* Adjust point coords */ for (i = start; i < count; i++) { @@ -576,7 +577,7 @@ static void fx_render_vb_line_strip( GLcontext *ctx, fprintf(stderr, "fx_render_vb_line_strip\n"); } - fxRenderPrimitive(ctx, GL_LINE_STRIP); + INIT(GL_LINE_STRIP); /* adjust line coords */ for (i = start; i < count; i++) { @@ -609,7 +610,7 @@ static void fx_render_vb_line_loop( GLcontext *ctx, fprintf(stderr, "fx_render_vb_line_loop\n"); } - fxRenderPrimitive(ctx, GL_LINE_LOOP); + INIT(GL_LINE_LOOP); if (!(flags & PRIM_BEGIN)) { j++; @@ -649,7 +650,7 @@ static void fx_render_vb_lines( GLcontext *ctx, fprintf(stderr, "fx_render_vb_lines\n"); } - fxRenderPrimitive(ctx, GL_LINES); + INIT(GL_LINES); /* adjust line coords */ for (i = start; i < count; i++) { @@ -680,7 +681,7 @@ static void fx_render_vb_triangles( GLcontext *ctx, fprintf(stderr, "fx_render_vb_triangles\n"); } - fxRenderPrimitive(ctx, GL_TRIANGLES); + INIT(GL_TRIANGLES); #if 0 /* [dBorca] @@ -716,7 +717,7 @@ static void fx_render_vb_tri_strip( GLcontext *ctx, fprintf(stderr, "fx_render_vb_tri_strip\n"); } - fxRenderPrimitive(ctx, GL_TRIANGLE_STRIP); + INIT(GL_TRIANGLE_STRIP); if (flags & PRIM_PARITY) mode = GR_TRIANGLE_STRIP_CONTINUE; @@ -741,7 +742,7 @@ static void fx_render_vb_tri_fan( GLcontext *ctx, fprintf(stderr, "fx_render_vb_tri_fan\n"); } - fxRenderPrimitive(ctx, GL_TRIANGLE_FAN); + INIT(GL_TRIANGLE_FAN); grDrawVertexArrayContiguous( GR_TRIANGLE_FAN, count-start, fxVB + start, sizeof(GrVertex) ); @@ -761,7 +762,7 @@ static void fx_render_vb_quads( GLcontext *ctx, fprintf(stderr, "fx_render_vb_quads\n"); } - fxRenderPrimitive(ctx, GL_QUADS); + INIT(GL_QUADS); for (i = start ; i < count-3 ; i += 4 ) { #define VERT(x) (fxVB + (x)) @@ -784,7 +785,7 @@ static void fx_render_vb_quad_strip( GLcontext *ctx, fprintf(stderr, "fx_render_vb_quad_strip\n"); } - fxRenderPrimitive(ctx, GL_QUAD_STRIP); + INIT(GL_QUAD_STRIP); count -= (count-start)&1; @@ -805,7 +806,7 @@ static void fx_render_vb_poly( GLcontext *ctx, fprintf(stderr, "fx_render_vb_poly\n"); } - fxRenderPrimitive(ctx, GL_POLYGON); + INIT(GL_POLYGON); grDrawVertexArrayContiguous( GR_POLYGON, count-start, fxVB + start, sizeof(GrVertex)); @@ -836,6 +837,7 @@ static void (*fx_render_tab_verts[GL_POLYGON+2])(GLcontext *, fx_render_vb_poly, fx_render_vb_noop, }; +#undef INIT(x) /**********************************************************************/