diff options
-rw-r--r-- | src/mesa/drivers/glide/fxddtex.c | 265 |
1 files changed, 188 insertions, 77 deletions
diff --git a/src/mesa/drivers/glide/fxddtex.c b/src/mesa/drivers/glide/fxddtex.c index 4c498b59cc1..256c3894698 100644 --- a/src/mesa/drivers/glide/fxddtex.c +++ b/src/mesa/drivers/glide/fxddtex.c @@ -49,6 +49,56 @@ void +_mesa_halve2x2_teximage2d ( GLuint bytesPerPixel, + GLint srcWidth, GLint srcHeight, + const GLvoid *srcImage, GLvoid *dstImage ) +{ + GLint i, j, k; + const GLint dstWidth = srcWidth / 2; + const GLint dstHeight = srcHeight / 2; + const GLint srcRowStride = srcWidth * bytesPerPixel; + const GLubyte *src = srcImage; + GLubyte *dst = dstImage; + + /* no borders! can't halve 1x1! (stride > width * comp) not allowed */ + if (srcHeight == 1) { + for (i = 0; i < dstWidth; i++) { + for (k = 0; k < bytesPerPixel; k++) { + dst[0] = (src[0] + src[bytesPerPixel] + 1) / 2; + src++; + dst++; + } + src += bytesPerPixel; + } + } else if (srcWidth == 1) { + for (j = 0; j < dstHeight; j++) { + for (k = 0; k < bytesPerPixel; k++) { + dst[0] = (src[0] + src[srcRowStride] + 1) / 2; + src++; + dst++; + } + src += srcRowStride; + } + } else { + for (j = 0; j < dstHeight; j++) { + for (i = 0; i < dstWidth; i++) { + for (k = 0; k < bytesPerPixel; k++) { + dst[0] = (src[0] + + src[bytesPerPixel] + + src[srcRowStride] + + src[srcRowStride + bytesPerPixel] + 2) / 4; + src++; + dst++; + } + src += bytesPerPixel; + } + src += srcRowStride; + } + } +} + + +void fxPrintTextureData(tfxTexInfo * ti) { fprintf(stderr, "Texture Data:\n"); @@ -1339,79 +1389,109 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, return; } - if (mml->wScale != 1 || mml->hScale != 1) { - /* rescale image to overcome 1:8 aspect limitation */ - if (!adjust2DRatio(ctx, - 0, 0, - width, height, - format, type, pixels, - packing, - mml, - texImage, - texelBytes, - dstRowStride) - ) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } - } - else { - /* no rescaling needed */ - /* unpack image, apply transfer ops and store in texImage->Data */ - texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, - texImage->TexFormat, texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - 0, /* dstImageStride */ - width, height, 1, - format, type, pixels, packing); - } -#if FX_TC_NCC - if (fxMesa->HaveTexus2) { - GLenum texNCC = 0; - GLuint texSize = mml->width * mml->height; - if (internalFormat == GL_COMPRESSED_RGB) { - texNCC = GR_TEXFMT_YIQ_422; - } else if (internalFormat == GL_COMPRESSED_RGBA) { - texNCC = GR_TEXFMT_AYIQ_8422; - texSize <<= 1; - } - if (texNCC) { - TxMip txMip, pxMip; - GLubyte *tempImage = MESA_PBUFFER_ALLOC(texSize); - if (!tempImage) { + if (pixels != NULL) { + if (mml->wScale != 1 || mml->hScale != 1) { + /* rescale image to overcome 1:8 aspect limitation */ + if (!adjust2DRatio(ctx, + 0, 0, + width, height, + format, type, pixels, + packing, + mml, + texImage, + texelBytes, + dstRowStride) + ) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } - txMip.width = mml->width; - txMip.height = mml->height; - txMip.depth = 1; - txMip.data[0] = texImage->Data; - pxMip.data[0] = tempImage; - fxMesa->Glide.txMipQuantize(&pxMip, &txMip, texNCC, TX_DITHER_ERR, TX_COMPRESSION_HEURISTIC); - if (level == 0) { - fxMesa->Glide.txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal); + } + else { + /* no rescaling needed */ + /* unpack image, apply transfer ops and store in texImage->Data */ + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + texImage->TexFormat, texImage->Data, + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + 0, /* dstImageStride */ + width, height, 1, + format, type, pixels, packing); + } +#if FX_TC_NCC + if (fxMesa->HaveTexus2) { + GLenum texNCC = 0; + GLuint texSize = mml->width * mml->height; + if (internalFormat == GL_COMPRESSED_RGB) { + texNCC = GR_TEXFMT_YIQ_422; + } else if (internalFormat == GL_COMPRESSED_RGBA) { + texNCC = GR_TEXFMT_AYIQ_8422; + texSize <<= 1; + } + if (texNCC) { + TxMip txMip, pxMip; + GLubyte *tempImage = MESA_PBUFFER_ALLOC(texSize); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + txMip.width = mml->width; + txMip.height = mml->height; + txMip.depth = 1; + txMip.data[0] = texImage->Data; + pxMip.data[0] = tempImage; + fxMesa->Glide.txMipQuantize(&pxMip, &txMip, texNCC, TX_DITHER_ERR, TX_COMPRESSION_HEURISTIC); + if (level == 0) { + fxMesa->Glide.txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal); + } + MESA_PBUFFER_FREE(texImage->Data); + texImage->Data = tempImage; + mml->glideFormat = texNCC; } - MESA_PBUFFER_FREE(texImage->Data); - texImage->Data = tempImage; - mml->glideFormat = texNCC; } - } #endif + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + GLint mipWidth, mipHeight; + tfxMipMapLevel *mip; + struct gl_texture_image *mipImage; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); + + assert(!texImage->IsCompressed); + + while (level < texObj->MaxLevel && level < maxLevels - 1) { + mipWidth = width / 2; + if (!mipWidth) { + mipWidth = 1; + } + mipHeight = height / 2; + if (!mipHeight) { + mipHeight = 1; + } + if ((mipWidth == width) && (mipHeight == height)) { + break; + } + _mesa_TexImage2D(target, ++level, internalFormat, + mipWidth, mipHeight, border, + format, type, + NULL); + mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mip = FX_MIPMAP_DATA(mipImage); + _mesa_halve2x2_teximage2d(texelBytes, + mml->width, mml->height, + texImage->Data, mipImage->Data); + texImage = mipImage; + mml = mip; + width = mipWidth; + height = mipHeight; + } + } + } ti->info.format = mml->glideFormat; texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat); - /* [dBorca] take care of aspectratio */ -#if 0 - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - _mesa_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); - } -#endif - /* [dBorca] * Hack alert: unsure... */ @@ -1495,10 +1575,44 @@ fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, format, type, pixels, packing); } - /* [dBorca] - * Hack alert: unsure... - */ - if (0 && ti->validated && ti->isInTM) + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + GLint mipWidth, mipHeight; + tfxMipMapLevel *mip; + struct gl_texture_image *mipImage; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); + + assert(!texImage->IsCompressed); + + width = texImage->Width; + height = texImage->Height; + while (level < texObj->MaxLevel && level < maxLevels - 1) { + mipWidth = width / 2; + if (!mipWidth) { + mipWidth = 1; + } + mipHeight = height / 2; + if (!mipHeight) { + mipHeight = 1; + } + if ((mipWidth == width) && (mipHeight == height)) { + break; + } + ++level; + mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mip = FX_MIPMAP_DATA(mipImage); + _mesa_halve2x2_teximage2d(texelBytes, + mml->width, mml->height, + texImage->Data, mipImage->Data); + texImage = mipImage; + mml = mip; + width = mipWidth; + height = mipHeight; + } + } + + if (ti->validated && ti->isInTM && !texObj->GenerateMipmap) fxTMReloadMipMapLevel(fxMesa, texObj, level); else fxTexInvalidate(ctx, texObj); @@ -1613,15 +1727,10 @@ fxDDCompressedTexImage2D (GLcontext *ctx, GLenum target, ti->info.format = mml->glideFormat; texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat); - /* [dBorca] take care of aspectratio */ -#if 0 /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - _mesa_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); + assert(!texImage->IsCompressed); } -#endif /* [dBorca] * Hack alert: unsure... @@ -1693,10 +1802,12 @@ fxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target, texImage->Data); } - /* [dBorca] - * Hack alert: unsure... - */ - if (0 && ti->validated && ti->isInTM) + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + assert(!texImage->IsCompressed); + } + + if (ti->validated && ti->isInTM) fxTMReloadMipMapLevel(fxMesa, texObj, level); else fxTexInvalidate(ctx, texObj); |