From 5999c5b620236fb6a996cf56759aec31f01c126b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 8 May 2006 19:14:38 +0000 Subject: [PATCH] Fix a number of texture compression issues. Pass the MESA_FORMAT_* token to the _mesa_compressed_row_stride(), _mesa_compressed_texture_size() and _mesa_compressed_image_address() functions since we want to use the driver-chosen format, not the user's internalFormat hint. Consolidate code related to choosing the texture format in texstoree.c --- src/mesa/drivers/dri/tdfx/tdfx_tex.c | 38 ++++---- src/mesa/drivers/dri/unichrome/via_tex.c | 10 ++- src/mesa/main/texcompress.c | 70 +++++++-------- src/mesa/main/texcompress.h | 6 +- src/mesa/main/texcompress_s3tc.c | 64 +++++++++----- src/mesa/main/teximage.c | 13 ++- src/mesa/main/texstore.c | 106 +++++++++++++++-------- 7 files changed, 178 insertions(+), 129 deletions(-) diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c index fe40953a1b3..0be6a823a38 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c @@ -1258,6 +1258,7 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, tdfxTexInfo *ti; tdfxMipMapLevel *mml; GLint texelBytes, dstRowStride; + GLuint mesaFormat; /* printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n", @@ -1345,9 +1346,10 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, internalFormat, format, type); assert(texImage->TexFormat); - mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + mesaFormat = texImage->TexFormat->MesaFormat; + mml->glideFormat = fxGlideFormat(mesaFormat); ti->info.format = mml->glideFormat; - texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat); + texImage->FetchTexelc = fxFetchFunction(mesaFormat); texelBytes = texImage->TexFormat->TexelBytes; if (texImage->IsCompressed) { @@ -1355,8 +1357,8 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, mml->width, mml->height, 1, - internalFormat); - dstRowStride = _mesa_compressed_row_stride(internalFormat, mml->width); + mesaFormat); + dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width); texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize); } else { dstRowStride = mml->width * texelBytes; @@ -1475,7 +1477,7 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, texelBytes = texImage->TexFormat->TexelBytes; if (texImage->IsCompressed) { - dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, mml->width); + dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width); } else { dstRowStride = mml->width * texelBytes; } @@ -1602,6 +1604,7 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target, tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); tdfxTexInfo *ti; tdfxMipMapLevel *mml; + GLuint mesaFormat; if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) { fprintf(stderr, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n", @@ -1653,9 +1656,10 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target, /* Determine the appropriate Glide texel format, * given the user's internal texture format hint. */ - mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + mesaFormat = texImage->TexFormat->MesaFormat; + mml->glideFormat = fxGlideFormat(mesaFormat); ti->info.format = mml->glideFormat; - texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat); + texImage->FetchTexelc = fxFetchFunction(mesaFormat); /* allocate new storage for texture image, if needed */ if (!texImage->Data) { @@ -1663,7 +1667,7 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target, mml->width, mml->height, 1, - internalFormat); + mesaFormat); texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); @@ -1687,9 +1691,10 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target, * we replicate the data over the padded area. * For now, we take 2) + 3) but texelfetchers will be wrong! */ - GLuint srcRowStride = _mesa_compressed_row_stride(internalFormat, width); + const GLuint mesaFormat = texImage->TexFormat->MesaFormat; + GLuint srcRowStride = _mesa_compressed_row_stride(mesaFormat, width); - GLuint destRowStride = _mesa_compressed_row_stride(internalFormat, + GLuint destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width); _mesa_upscale_teximage2d(srcRowStride, (height+3) / 4, @@ -1728,6 +1733,7 @@ tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint destRowStride, srcRowStride; GLint i, rows; GLubyte *dest; + const GLuint mesaFormat = texImage->TexFormat->MesaFormat; if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) { fprintf(stderr, "tdfxCompressedTexSubImage2D: id=%d\n", texObj->Name); @@ -1738,12 +1744,11 @@ tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target, mml = TDFX_TEXIMAGE_DATA(texImage); assert(mml); - srcRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, width); + srcRowStride = _mesa_compressed_row_stride(mesaFormat, width); - destRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, - mml->width); + destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width); dest = _mesa_compressed_image_address(xoffset, yoffset, 0, - texImage->InternalFormat, + mesaFormat, mml->width, (GLubyte*) texImage->Data); @@ -1759,10 +1764,9 @@ tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target, * see fxDDCompressedTexImage2D for caveats */ if (mml->wScale != 1 || mml->hScale != 1) { - srcRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, texImage->Width); + srcRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width); - destRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, - mml->width); + destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width); _mesa_upscale_teximage2d(srcRowStride, texImage->Height / 4, destRowStride, mml->height / 4, 1, texImage->Data, destRowStride, diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c index 19b270955eb..0cbecd4146d 100644 --- a/src/mesa/drivers/dri/unichrome/via_tex.c +++ b/src/mesa/drivers/dri/unichrome/via_tex.c @@ -691,6 +691,14 @@ static void viaTexImage(GLcontext *ctx, } texelBytes = texImage->TexFormat->TexelBytes; + if (texelBytes == 0) { + /* compressed format */ + texImage->IsCompressed = GL_TRUE; + texImage->CompressedSize = + ctx->Driver.CompressedTextureSize(ctx, texImage->Width, + texImage->Height, texImage->Depth, + texImage->TexFormat->MesaFormat); + } /* Minimum pitch of 32 bytes */ if (postConvWidth * texelBytes < 32) { @@ -782,7 +790,7 @@ static void viaTexImage(GLcontext *ctx, GLint dstRowStride, dstImageStride = 0; GLboolean success; if (texImage->IsCompressed) { - dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,width); + dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); } else { dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes; diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index d18b1d0b418..c6c7c8adca0 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -101,23 +101,23 @@ _mesa_get_compressed_formats( GLcontext *ctx, GLint *formats ) * \param width texture width in texels. * \param height texture height in texels. * \param depth texture depth in texels. - * \param format - one of the specific compressed texture formats + * \param mesaFormat one of the MESA_FORMAT_* compressed formats * * \return size in bytes, or zero if bad format */ GLuint _mesa_compressed_texture_size( GLcontext *ctx, GLsizei width, GLsizei height, GLsizei depth, - GLenum format ) + GLuint mesaFormat ) { GLuint size; ASSERT(depth == 1); (void) depth; - switch (format) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: + switch (mesaFormat) { + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: /* round up width to next multiple of 8, height to next multiple of 4 */ width = (width + 7) & ~7; height = (height + 3) & ~3; @@ -129,10 +129,8 @@ _mesa_compressed_texture_size( GLcontext *ctx, if (size < 16) size = 16; return size; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_RGB_S3TC: - case GL_RGB4_S3TC: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: /* round up width, height to next multiple of 4 */ width = (width + 3) & ~3; height = (height + 3) & ~3; @@ -144,10 +142,8 @@ _mesa_compressed_texture_size( GLcontext *ctx, if (size < 8) size = 8; return size; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: /* round up width, height to next multiple of 4 */ width = (width + 3) & ~3; height = (height + 3) & ~3; @@ -160,7 +156,7 @@ _mesa_compressed_texture_size( GLcontext *ctx, size = 16; return size; default: - _mesa_problem(ctx, "bad texformat in compressed_texture_size"); + _mesa_problem(ctx, "bad mesaFormat in _mesa_compressed_texture_size"); return 0; } } @@ -169,33 +165,30 @@ _mesa_compressed_texture_size( GLcontext *ctx, /* * Compute the bytes per row in a compressed texture image. * We use this for computing the destination address for sub-texture updates. - * \param format one of the specific texture compression formats + * \param mesaFormat one of the MESA_FORMAT_* compressed formats * \param width image width in pixels * \return stride, in bytes, between rows for compressed image */ GLint -_mesa_compressed_row_stride(GLenum format, GLsizei width) +_mesa_compressed_row_stride(GLuint mesaFormat, GLsizei width) { GLint stride; - switch (format) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: + switch (mesaFormat) { + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: stride = ((width + 7) / 8) * 16; /* 16 bytes per 8x4 tile */ break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_RGB_S3TC: - case GL_RGB4_S3TC: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: stride = ((width + 3) / 4) * 8; /* 8 bytes per 4x4 tile */ break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: stride = ((width + 3) / 4) * 16; /* 16 bytes per 4x4 tile */ break; default: + _mesa_problem(NULL, "bad mesaFormat in _mesa_compressed_row_stride"); return 0; } @@ -214,7 +207,7 @@ _mesa_compressed_row_stride(GLenum format, GLsizei width) */ GLubyte * _mesa_compressed_image_address(GLint col, GLint row, GLint img, - GLenum format, + GLuint mesaFormat, GLsizei width, const GLubyte *image) { GLubyte *addr; @@ -229,25 +222,22 @@ _mesa_compressed_image_address(GLint col, GLint row, GLint img, * offset = Z * (((width + X - 1) / X) * (row / Y) + col / X); */ - switch (format) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: + switch (mesaFormat) { + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: addr = (GLubyte *) image + 16 * (((width + 7) / 8) * (row / 4) + col / 8); break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_RGB_S3TC: - case GL_RGB4_S3TC: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: addr = (GLubyte *) image + 8 * (((width + 3) / 4) * (row / 4) + col / 4); break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: addr = (GLubyte *) image + 16 * (((width + 3) / 4) * (row / 4) + col / 4); break; default: - return NULL; + _mesa_problem(NULL, "bad mesaFormat in _mesa_compressed_image_address"); + addr = NULL; } return addr; diff --git a/src/mesa/main/texcompress.h b/src/mesa/main/texcompress.h index 50074145469..637c6a80c3e 100644 --- a/src/mesa/main/texcompress.h +++ b/src/mesa/main/texcompress.h @@ -34,15 +34,15 @@ _mesa_get_compressed_formats( GLcontext *ctx, GLint *formats ); extern GLuint _mesa_compressed_texture_size( GLcontext *ctx, GLsizei width, GLsizei height, GLsizei depth, - GLenum format ); + GLuint mesaFormat ); extern GLint -_mesa_compressed_row_stride(GLenum format, GLsizei width); +_mesa_compressed_row_stride(GLuint mesaFormat, GLsizei width); extern GLubyte * _mesa_compressed_image_address(GLint col, GLint row, GLint img, - GLenum format, + GLuint mesaFormat, GLsizei width, const GLubyte *image); diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index 5a6685e0f33..c572e19e498 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -172,11 +172,13 @@ texstore_rgb_dxt1(STORE_PARAMS) } dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0, - GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + dstFormat->MesaFormat, texWidth, (GLubyte *) dstAddr); if (ext_tx_compress_dxtn) { - (*ext_tx_compress_dxtn)(3, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, dst, dstRowStride); + (*ext_tx_compress_dxtn)(3, srcWidth, srcHeight, pixels, + GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + dst, dstRowStride); } else { _mesa_problem(ctx, "external dxt library not available"); @@ -232,10 +234,12 @@ texstore_rgba_dxt1(STORE_PARAMS) } dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0, - GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + dstFormat->MesaFormat, texWidth, (GLubyte *) dstAddr); if (ext_tx_compress_dxtn) { - (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dst, dstRowStride); + (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + dst, dstRowStride); } else { _mesa_problem(ctx, "external dxt library not available"); @@ -290,10 +294,12 @@ texstore_rgba_dxt3(STORE_PARAMS) } dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0, - GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, + dstFormat->MesaFormat, texWidth, (GLubyte *) dstAddr); if (ext_tx_compress_dxtn) { - (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, dst, dstRowStride); + (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, + GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, + dst, dstRowStride); } else { _mesa_problem(ctx, "external dxt library not available"); @@ -348,10 +354,12 @@ texstore_rgba_dxt5(STORE_PARAMS) } dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0, - GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, + dstFormat->MesaFormat, texWidth, (GLubyte *) dstAddr); if (ext_tx_compress_dxtn) { - (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, dst, dstRowStride); + (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, + GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, + dst, dstRowStride); } else { _mesa_problem(ctx, "external dxt library not available"); @@ -368,12 +376,14 @@ static void fetch_texel_2d_rgb_dxt1( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - (void) k; - if (fetch_ext_rgb_dxt1) { - ASSERT (sizeof(GLchan) == sizeof(GLubyte)); - (*fetch_ext_rgb_dxt1)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel); - } - else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); + (void) k; + if (fetch_ext_rgb_dxt1) { + ASSERT (sizeof(GLchan) == sizeof(GLubyte)); + fetch_ext_rgb_dxt1(texImage->RowStride, + (GLubyte *)(texImage)->Data, i, j, texel); + } + else + _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); } @@ -397,9 +407,11 @@ fetch_texel_2d_rgba_dxt1( const struct gl_texture_image *texImage, { (void) k; if (fetch_ext_rgba_dxt1) { - (*fetch_ext_rgba_dxt1)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel); - } - else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); + fetch_ext_rgba_dxt1(texImage->RowStride, + (GLubyte *)(texImage)->Data, i, j, texel); + } + else + _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); } @@ -423,10 +435,12 @@ fetch_texel_2d_rgba_dxt3( const struct gl_texture_image *texImage, { (void) k; if (fetch_ext_rgba_dxt3) { - ASSERT (sizeof(GLchan) == sizeof(GLubyte)); - (*fetch_ext_rgba_dxt3)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel); - } - else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); + ASSERT (sizeof(GLchan) == sizeof(GLubyte)); + fetch_ext_rgba_dxt3(texImage->RowStride, (GLubyte *)(texImage)->Data, + i, j, texel); + } + else + _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); } @@ -450,9 +464,11 @@ fetch_texel_2d_rgba_dxt5( const struct gl_texture_image *texImage, { (void) k; if (fetch_ext_rgba_dxt5) { - (*fetch_ext_rgba_dxt5)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel); - } - else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); + fetch_ext_rgba_dxt5(texImage->RowStride, (GLubyte *)(texImage)->Data, + i, j, texel); + } + else + _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); } diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index ff1d51d7d09..4b9b1b8728d 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1113,12 +1113,8 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target, else img->DepthLog2 = logbase2(img->Depth2); img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); - img->IsCompressed = is_compressed_format(ctx, internalFormat); - if (img->IsCompressed) - img->CompressedSize = ctx->Driver.CompressedTextureSize(ctx, width, - height, depth, internalFormat); - else - img->CompressedSize = 0; + img->IsCompressed = GL_FALSE; + img->CompressedSize = 0; if ((width == 1 || _mesa_bitcount(img->Width2) == 1) && (height == 1 || _mesa_bitcount(img->Height2) == 1) && @@ -2844,7 +2840,7 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize) { - GLint expectedSize, maxLevels = 0, maxTextureSize; + GLint /**expectedSize,**/ maxLevels = 0, maxTextureSize; if (dimensions == 1) { /* 1D compressed textures not allowed */ @@ -2913,10 +2909,13 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions, if (level < 0 || level >= maxLevels) return GL_INVALID_VALUE; +#if 0 + /* XXX need to renable this code someday! */ expectedSize = ctx->Driver.CompressedTextureSize(ctx, width, height, depth, internalFormat); if (expectedSize != imageSize) return GL_INVALID_VALUE; +#endif return GL_NO_ERROR; } diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 2b614e90d33..c373d2f95ea 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -2367,6 +2367,48 @@ set_fetch_functions(struct gl_texture_image *texImage, GLuint dims) } +/** + * Choose the actual storage format for a new texture image. + * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function. + * Also set some other texImage fields related to texture compression, etc. + * \param ctx rendering context + * \param texImage the gl_texture_image + * \param dims texture dimensions (1, 2 or 3) + * \param format the user-specified format parameter + * \param type the user-specified type parameter + * \param internalFormat the user-specified internal format hint + */ +static void +choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage, + GLuint dims, + GLenum format, GLenum type, GLint internalFormat) +{ + assert(ctx->Driver.ChooseTextureFormat); + + texImage->TexFormat + = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type); + + assert(texImage->TexFormat); + + set_fetch_functions(texImage, dims); + + if (texImage->TexFormat->TexelBytes == 0) { + /* must be a compressed format */ + texImage->IsCompressed = GL_TRUE; + texImage->CompressedSize = + ctx->Driver.CompressedTextureSize(ctx, texImage->Width, + texImage->Height, texImage->Depth, + texImage->TexFormat->MesaFormat); + } + else { + /* non-compressed format */ + texImage->IsCompressed = GL_FALSE; + texImage->CompressedSize = 0; + } +} + + + /* * This is the software fallback for Driver.TexImage1D() * and Driver.CopyTexImage1D(). @@ -2389,12 +2431,7 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } - /* choose the texture format */ - assert(ctx->Driver.ChooseTextureFormat); - texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, - format, type); - assert(texImage->TexFormat); - set_fetch_functions(texImage, 1); + choose_texture_format(ctx, texImage, 1, format, type, internalFormat); /* allocate memory */ if (texImage->IsCompressed) @@ -2474,12 +2511,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, &postConvHeight); } - /* choose the texture format */ - assert(ctx->Driver.ChooseTextureFormat); - texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, - internalFormat, format, type); - assert(texImage->TexFormat); - set_fetch_functions(texImage, 2); + choose_texture_format(ctx, texImage, 2, format, type, internalFormat); texelBytes = texImage->TexFormat->TexelBytes; @@ -2507,7 +2539,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, GLboolean success; if (texImage->IsCompressed) { dstRowStride - = _mesa_compressed_row_stride(texImage->InternalFormat,width); + = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); } else { dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes; @@ -2554,12 +2586,7 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, GLint texelBytes, sizeInBytes; (void) border; - /* choose the texture format */ - assert(ctx->Driver.ChooseTextureFormat); - texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, - internalFormat, format, type); - assert(texImage->TexFormat); - set_fetch_functions(texImage, 3); + choose_texture_format(ctx, texImage, 3, format, type, internalFormat); texelBytes = texImage->TexFormat->TexelBytes; @@ -2587,7 +2614,7 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, GLboolean success; if (texImage->IsCompressed) { dstRowStride - = _mesa_compressed_row_stride(texImage->InternalFormat,width); + = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); dstImageStride = 0; } else { @@ -2687,7 +2714,7 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, GLint dstRowStride = 0, dstImageStride = 0; GLboolean success; if (texImage->IsCompressed) { - dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, + dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width); } else { @@ -2740,7 +2767,7 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, GLint dstRowStride, dstImageStride; GLboolean success; if (texImage->IsCompressed) { - dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, + dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width); dstImageStride = 0; /* XXX fix */ } @@ -2818,12 +2845,7 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, ASSERT(texImage->Depth == 1); ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */ - /* choose the texture format */ - assert(ctx->Driver.ChooseTextureFormat); - texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, - internalFormat, 0, 0); - assert(texImage->TexFormat); - set_fetch_functions(texImage, 2); + choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat); /* allocate storage */ texImage->Data = _mesa_alloc_texmemory(imageSize); @@ -2891,7 +2913,7 @@ _mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - /* this space intentionally left blank */ + /* there are no compressed 1D texture formats yet */ (void) ctx; (void) target; (void) level; (void) xoffset; (void) width; @@ -2919,6 +2941,8 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, GLint i, rows; GLubyte *dest; const GLubyte *src; + const GLuint mesaFormat = texImage->TexFormat->MesaFormat; + (void) format; /* these should have been caught sooner */ @@ -2933,11 +2957,10 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, if (!data) return; - srcRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, width); + srcRowStride = _mesa_compressed_row_stride(mesaFormat, width); src = (const GLubyte *) data; - destRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, - texImage->Width); + destRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width); dest = _mesa_compressed_image_address(xoffset, yoffset, 0, texImage->InternalFormat, texImage->Width, @@ -2976,7 +2999,7 @@ _mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - /* this space intentionally left blank */ + /* there are no compressed 3D texture formats yet */ (void) ctx; (void) target; (void) level; (void) xoffset; (void) yoffset; (void) zoffset; @@ -3733,7 +3756,7 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border, } -/* +/** * For GL_SGIX_generate_mipmap: * Generate a complete set of mipmaps from texObj's base-level image. * Stop at texObj's MaxLevel or when we get to the 1x1 texture. @@ -3876,6 +3899,16 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, dstImage->TexFormat = srcImage->TexFormat; dstImage->FetchTexelc = srcImage->FetchTexelc; dstImage->FetchTexelf = srcImage->FetchTexelf; + dstImage->IsCompressed = srcImage->IsCompressed; + if (dstImage->IsCompressed) { + dstImage->CompressedSize + = ctx->Driver.CompressedTextureSize(ctx, dstImage->Width, + dstImage->Height, + dstImage->Depth, + dstImage->TexFormat->MesaFormat); + ASSERT(dstImage->CompressedSize > 0); + } + ASSERT(dstImage->TexFormat); ASSERT(dstImage->FetchTexelc); ASSERT(dstImage->FetchTexelf); @@ -3884,7 +3917,6 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, * Setup src and dest data pointers. */ if (dstImage->IsCompressed) { - ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/ dstImage->Data = _mesa_alloc_texmemory(dstImage->CompressedSize); if (!dstImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); @@ -3895,7 +3927,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, ASSERT(dstData); } else { - bytesPerTexel = srcImage->TexFormat->TexelBytes; + bytesPerTexel = dstImage->TexFormat->TexelBytes; ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0); dstImage->Data = _mesa_alloc_texmemory(dstWidth * dstHeight * dstDepth * bytesPerTexel); @@ -3945,7 +3977,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, /* compress image from dstData into dstImage->Data */ const GLenum srcFormat = convertFormat->BaseFormat; GLint dstRowStride - = _mesa_compressed_row_stride(srcImage->InternalFormat, dstWidth); + = _mesa_compressed_row_stride(dstImage->TexFormat->MesaFormat, dstWidth); ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA); dstImage->TexFormat->StoreImage(ctx, 2, dstImage->_BaseFormat, dstImage->TexFormat, -- 2.30.2