diff options
Diffstat (limited to 'src/mesa/main/texstore.c')
-rw-r--r-- | src/mesa/main/texstore.c | 907 |
1 files changed, 42 insertions, 865 deletions
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index ef81dd654a9..d0529b13c3e 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -63,12 +63,8 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "texutil.h" - -/*** NEWTEXSTORE ***********************************************************/ - static const GLint ZERO = 1000, ONE = 1001; /** @@ -362,14 +358,14 @@ make_temp_float_image(GLcontext *ctx, GLuint dims, * \param srcPacking source image pixel packing * \return resulting image with format = textureBaseFormat and type = GLchan. */ -static GLchan * -make_temp_chan_image(GLcontext *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) +GLchan * +_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims, + GLenum logicalBaseFormat, + GLenum textureBaseFormat, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking) { GLuint transferOps = ctx->_ImageTransferState; const GLint components = _mesa_components_in_format(logicalBaseFormat); @@ -640,7 +636,7 @@ _mesa_texstore_rgba(GLcontext *ctx, GLuint dims, } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -859,7 +855,7 @@ _mesa_texstore_rgb565(STORE_PARAMS) } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -917,7 +913,7 @@ _mesa_texstore_rgba8888(STORE_PARAMS) } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -977,7 +973,7 @@ _mesa_texstore_argb8888(STORE_PARAMS) } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -1066,7 +1062,7 @@ _mesa_texstore_rgb888(STORE_PARAMS) } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -1142,7 +1138,7 @@ _mesa_texstore_argb4444(STORE_PARAMS) } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -1201,7 +1197,7 @@ _mesa_texstore_argb1555(STORE_PARAMS) } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -1260,7 +1256,7 @@ _mesa_texstore_al88(STORE_PARAMS) } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -1312,7 +1308,7 @@ _mesa_texstore_rgb332(STORE_PARAMS) } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -1370,7 +1366,7 @@ _mesa_texstore_a8(STORE_PARAMS) } else { /* general path */ - const GLchan *tempImage = make_temp_chan_image(ctx, dims, + const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, baseInternalFormat, dstFormat->BaseFormat, srcWidth, srcHeight, srcDepth, @@ -1635,688 +1631,6 @@ _mesa_texstore_rgba_float16(STORE_PARAMS) } -#if !NEWTEXSTORE /*****************************************************/ - - -/* - * Given an internal texture format enum or 1, 2, 3, 4 return the - * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE, - * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the - * number of components for the format. Return -1 if invalid enum. - */ -static GLint -components_in_intformat( GLint format ) -{ - switch (format) { - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - return 1; - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - return 1; - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - return 2; - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - return 1; - case 3: - case GL_RGB: - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - return 3; - case 4: - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - return 4; - case GL_COLOR_INDEX: - case GL_COLOR_INDEX1_EXT: - case GL_COLOR_INDEX2_EXT: - case GL_COLOR_INDEX4_EXT: - case GL_COLOR_INDEX8_EXT: - case GL_COLOR_INDEX12_EXT: - case GL_COLOR_INDEX16_EXT: - return 1; - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16_SGIX: - case GL_DEPTH_COMPONENT24_SGIX: - case GL_DEPTH_COMPONENT32_SGIX: - return 1; - case GL_YCBCR_MESA: - return 2; /* Y + (Cb or Cr) */ - default: - return -1; /* error */ - } -} - - -/* - * This function is used to transfer the user's image data into a texture - * image buffer. We handle both full texture images and subtexture images. - * We also take care of all image transfer operations here, including - * convolution, scale/bias, colortables, etc. - * - * The destination texel type is always GLchan. - * The destination texel format is one of the 6 basic types. - * - * A hardware driver may use this as a helper routine to unpack and - * apply pixel transfer ops into a temporary image buffer. Then, - * convert the temporary image into the special hardware format. - * - * \param - * dimensions - 1, 2, or 3 - * texDestFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA, - * GL_RGB or GL_RGBA (the destination format) - * texDestAddr - destination image address - * srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images - * dstXoffset, dstYoffset, dstZoffset - position to store the image within - * the destination 3D texture - * dstRowStride, dstImageStride - dest image strides in bytes - * srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc) - * srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc - * srcPacking - describes packing of incoming image. - * transferOps - mask of pixel transfer operations - */ -static void -transfer_teximage(GLcontext *ctx, GLuint dimensions, - GLenum texDestFormat, GLvoid *texDestAddr, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, - GLint dstRowStride, GLint dstImageStride, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking, - GLuint transferOps) -{ - GLint texComponents; - - ASSERT(ctx); - ASSERT(dimensions >= 1 && dimensions <= 3); - ASSERT(texDestFormat == GL_LUMINANCE || - texDestFormat == GL_INTENSITY || - texDestFormat == GL_LUMINANCE_ALPHA || - texDestFormat == GL_ALPHA || - texDestFormat == GL_RGB || - texDestFormat == GL_RGBA || - texDestFormat == GL_COLOR_INDEX || - texDestFormat == GL_DEPTH_COMPONENT); - ASSERT(texDestAddr); - ASSERT(srcWidth >= 0); - ASSERT(srcHeight >= 0); - ASSERT(srcDepth >= 0); - ASSERT(dstXoffset >= 0); - ASSERT(dstYoffset >= 0); - ASSERT(dstZoffset >= 0); - ASSERT(dstRowStride >= 0); - ASSERT(dstImageStride >= 0); - ASSERT(srcAddr); - ASSERT(srcPacking); - - texComponents = components_in_intformat(texDestFormat); - - /* try common 2D texture cases first */ - if (!transferOps && dimensions == 2 && srcType == CHAN_TYPE) { - - if (srcFormat == texDestFormat) { - /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA, - * GL_LUMINANCE_ALPHA, etc. texture formats. Use memcpy(). - */ - const GLchan *src = (const GLchan *) _mesa_image_address( - srcPacking, srcAddr, srcWidth, srcHeight, - srcFormat, srcType, 0, 0, 0); - const GLint srcRowStride = _mesa_image_row_stride(srcPacking, - srcWidth, srcFormat, srcType); - const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan); - GLchan *dst = (GLchan *) texDestAddr - + dstYoffset * (dstRowStride / sizeof(GLchan)) - + dstXoffset * texComponents; - if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) { - MEMCPY(dst, src, srcHeight * widthInBytes); - } - else { - GLint i; - for (i = 0; i < srcHeight; i++) { - MEMCPY(dst, src, widthInBytes); - src += (srcRowStride / sizeof(GLchan)); - dst += (dstRowStride / sizeof(GLchan)); - } - } - return; /* all done */ - } - else if (srcFormat == GL_RGBA && texDestFormat == GL_RGB) { - /* commonly used by Quake */ - const GLchan *src = (const GLchan *) _mesa_image_address( - srcPacking, srcAddr, srcWidth, srcHeight, - srcFormat, srcType, 0, 0, 0); - const GLint srcRowStride = _mesa_image_row_stride(srcPacking, - srcWidth, srcFormat, srcType); - GLchan *dst = (GLchan *) texDestAddr - + dstYoffset * (dstRowStride / sizeof(GLchan)) - + dstXoffset * texComponents; - GLint i, j; - for (i = 0; i < srcHeight; i++) { - const GLchan *s = src; - GLchan *d = dst; - for (j = 0; j < srcWidth; j++) { - *d++ = *s++; /*red*/ - *d++ = *s++; /*green*/ - *d++ = *s++; /*blue*/ - s++; /*alpha*/ - } - src += (srcRowStride / sizeof(GLchan)); - dst += (dstRowStride / sizeof(GLchan)); - } - return; /* all done */ - } - } - - /* - * General case solutions - */ - if (texDestFormat == GL_COLOR_INDEX) { - /* color index texture */ - const GLenum texType = CHAN_TYPE; - GLint img, row; - GLchan *dest = (GLchan *) texDestAddr - + dstZoffset * (dstImageStride / sizeof(GLchan)) - + dstYoffset * (dstRowStride / sizeof(GLchan)) - + dstXoffset * texComponents; - for (img = 0; img < srcDepth; img++) { - GLchan *destRow = dest; - for (row = 0; row < srcHeight; row++) { - const GLvoid *src = _mesa_image_address(srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); - _mesa_unpack_index_span(ctx, srcWidth, texType, destRow, - srcType, src, srcPacking, transferOps); - destRow += (dstRowStride / sizeof(GLchan)); - } - dest += dstImageStride; - } - } - else if (texDestFormat == GL_YCBCR_MESA) { - /* YCbCr texture */ - GLint img, row; - GLushort *dest = (GLushort *) texDestAddr - + dstZoffset * (dstImageStride / sizeof(GLushort)) - + dstYoffset * (dstRowStride / sizeof(GLushort)) - + dstXoffset * texComponents; - ASSERT(ctx->Extensions.MESA_ycbcr_texture); - for (img = 0; img < srcDepth; img++) { - GLushort *destRow = dest; - for (row = 0; row < srcHeight; row++) { - const GLvoid *srcRow = _mesa_image_address(srcPacking, - srcAddr, srcWidth, srcHeight, - srcFormat, srcType, img, row, 0); - MEMCPY(destRow, srcRow, srcWidth * sizeof(GLushort)); - destRow += (dstRowStride / sizeof(GLushort)); - } - dest += dstImageStride / sizeof(GLushort); - } - } - else if (texDestFormat == GL_DEPTH_COMPONENT) { - /* Depth texture (shadow maps) */ - GLint img, row; - GLubyte *dest = (GLubyte *) texDestAddr - + dstZoffset * dstImageStride - + dstYoffset * (dstRowStride / sizeof(GLchan)) - + dstXoffset * texComponents; - for (img = 0; img < srcDepth; img++) { - GLubyte *destRow = dest; - for (row = 0; row < srcHeight; row++) { - const GLvoid *src = _mesa_image_address(srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); - _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) destRow, - srcType, src, srcPacking); - destRow += (dstRowStride / sizeof(GLchan)); - } - dest += dstImageStride; - } - } - else { - /* regular, color texture */ - if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) || - (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) || - (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) { - /* - * Fill texture image with convolution - */ - GLint img, row; - GLint convWidth = srcWidth, convHeight = srcHeight; - GLfloat *tmpImage, *convImage; - tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat)); - if (!tmpImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - return; - } - convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat)); - if (!convImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - FREE(tmpImage); - return; - } - - for (img = 0; img < srcDepth; img++) { - const GLfloat *srcf; - GLfloat *dstf = tmpImage; - GLchan *dest; - - /* unpack and do transfer ops up to convolution */ - for (row = 0; row < srcHeight; row++) { - const GLvoid *src = _mesa_image_address(srcPacking, - srcAddr, srcWidth, srcHeight, - srcFormat, srcType, img, row, 0); - _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dstf, - srcFormat, srcType, src, srcPacking, - (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT); - dstf += srcWidth * 4; - } - - /* convolve */ - if (dimensions == 1) { - ASSERT(ctx->Pixel.Convolution1DEnabled); - _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage); - } - else { - if (ctx->Pixel.Convolution2DEnabled) { - _mesa_convolve_2d_image(ctx, &convWidth, &convHeight, - tmpImage, convImage); - } - else { - ASSERT(ctx->Pixel.Separable2DEnabled); - _mesa_convolve_sep_image(ctx, &convWidth, &convHeight, - tmpImage, convImage); - } - } - - /* packing and transfer ops after convolution */ - srcf = convImage; - dest = (GLchan *) texDestAddr - + (dstZoffset + img) * (dstImageStride / sizeof(GLchan)) - + dstYoffset * (dstRowStride / sizeof(GLchan)); - for (row = 0; row < convHeight; row++) { - _mesa_pack_rgba_span_float(ctx, convWidth, - (const GLfloat (*)[4]) srcf, - texDestFormat, CHAN_TYPE, - dest, &ctx->DefaultPacking, - transferOps - & IMAGE_POST_CONVOLUTION_BITS); - srcf += convWidth * 4; - dest += (dstRowStride / sizeof(GLchan)); - } - } - - FREE(convImage); - FREE(tmpImage); - } - else { - /* - * no convolution - */ - GLint img, row; - GLchan *dest = (GLchan *) texDestAddr - + dstZoffset * (dstImageStride / sizeof(GLchan)) - + dstYoffset * (dstRowStride / sizeof(GLchan)) - + dstXoffset * texComponents; - for (img = 0; img < srcDepth; img++) { - GLchan *destRow = dest; - for (row = 0; row < srcHeight; row++) { - const GLvoid *srcRow = _mesa_image_address(srcPacking, - srcAddr, srcWidth, srcHeight, - srcFormat, srcType, img, row, 0); - _mesa_unpack_color_span_chan(ctx, srcWidth, texDestFormat, - destRow, srcFormat, srcType, srcRow, - srcPacking, transferOps); - destRow += (dstRowStride / sizeof(GLchan)); - } - dest += dstImageStride / sizeof(GLchan); - } - } - } -} - - - -/* - * Transfer a texture image from user space to <destAddr> applying all - * needed image transfer operations and storing the result in the format - * specified by <dstFormat>. <dstFormat> may be any format from texformat.h. - * \param - * dimensions - 1, 2 or 3 - * baseInternalFormat - base format of the internal texture format - * specified by the user. This is very important, see below. - * dstFormat - destination image format - * dstAddr - destination address - * srcWidth, srcHeight, srcDepth - size of source iamge - * dstX/Y/Zoffset - as specified by glTexSubImage - * dstRowStride - stride between dest rows in bytes - * dstImageStride - stride between dest images in bytes - * srcFormat, srcType - incoming image format and data type - * srcAddr - source image address - * srcPacking - packing params of source image - * - * XXX this function is a bit more complicated than it should be. If - * _mesa_convert_texsubimage[123]d could handle any dest/source formats - * or if transfer_teximage() could store in any MESA_FORMAT_* format, we - * could simplify things here. - */ -void -_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, - GLenum baseInternalFormat, - const struct gl_texture_format *dstFormat, - GLvoid *dstAddr, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, - GLint dstRowStride, GLint dstImageStride, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) -{ - const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes; - const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes; - GLboolean makeTemp; - GLuint transferOps = ctx->_ImageTransferState; - GLboolean freeSourceData = GL_FALSE; - GLint postConvWidth = srcWidth, postConvHeight = srcHeight; - - assert(baseInternalFormat > 0); - ASSERT(baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_INTENSITY || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_YCBCR_MESA || - baseInternalFormat == GL_COLOR_INDEX || - baseInternalFormat == GL_DEPTH_COMPONENT); - - if (transferOps & IMAGE_CONVOLUTION_BIT) { - _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, - &postConvHeight); - } - - /* - * Consider this scenario: The user's source image is GL_RGB and the - * requested internal format is GL_LUMINANCE. Now suppose the device - * driver doesn't support GL_LUMINANCE and instead uses RGB16 as the - * texture format. In that case we still need to do an intermediate - * conversion to luminance format so that the incoming red channel gets - * replicated into the dest red, green and blue channels. The following - * code takes care of that. - */ - if (dstFormat->BaseFormat != baseInternalFormat) { - /* Allocate storage for temporary image in the baseInternalFormat */ - const GLint texelSize = _mesa_components_in_format(baseInternalFormat) - * sizeof(GLchan); - const GLint bytes = texelSize * postConvWidth * postConvHeight *srcDepth; - const GLint tmpRowStride = texelSize * postConvWidth; - const GLint tmpImgStride = texelSize * postConvWidth * postConvHeight; - GLvoid *tmpImage = MALLOC(bytes); - if (!tmpImage) - return; - transfer_teximage(ctx, dimensions, baseInternalFormat, tmpImage, - srcWidth, srcHeight, srcDepth, - 0, 0, 0, /* x/y/zoffset */ - tmpRowStride, tmpImgStride, - srcFormat, srcType, srcAddr, srcPacking, transferOps); - - /* this is our new source image */ - srcWidth = postConvWidth; - srcHeight = postConvHeight; - srcFormat = baseInternalFormat; - srcType = CHAN_TYPE; - srcAddr = tmpImage; - srcPacking = &ctx->DefaultPacking; - freeSourceData = GL_TRUE; - transferOps = 0; /* image transfer ops were completed */ - } - - /* Let the optimized tex conversion functions take a crack at the - * image conversion if the dest format is a h/w format. - */ - if (_mesa_is_hardware_tex_format(dstFormat)) { - if (transferOps) { - makeTemp = GL_TRUE; - } - else { - if (dimensions == 1) { - makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat, - dstXoffset, - srcWidth, - srcFormat, srcType, - srcPacking, srcAddr, - dstAddr); - } - else if (dimensions == 2) { - makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat, - dstXoffset, dstYoffset, - srcWidth, srcHeight, - dstRowStridePixels, - srcFormat, srcType, - srcPacking, srcAddr, - dstAddr); - } - else { - assert(dimensions == 3); - makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat, - dstXoffset, dstYoffset, dstZoffset, - srcWidth, srcHeight, srcDepth, - dstRowStridePixels, dstImageStridePixels, - srcFormat, srcType, - srcPacking, srcAddr, dstAddr); - } - if (!makeTemp) { - /* all done! */ - if (freeSourceData) - FREE((void *) srcAddr); - return; - } - } - } - else { - /* software texture format */ - makeTemp = GL_FALSE; - } - - if (makeTemp) { - GLint postConvWidth = srcWidth, postConvHeight = srcHeight; - GLenum tmpFormat; - GLuint tmpComps, tmpTexelSize; - GLint tmpRowStride, tmpImageStride; - GLubyte *tmpImage; - - if (transferOps & IMAGE_CONVOLUTION_BIT) { - _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, - &postConvHeight); - } - - tmpFormat = dstFormat->BaseFormat; - tmpComps = _mesa_components_in_format(tmpFormat); - tmpTexelSize = tmpComps * sizeof(GLchan); - tmpRowStride = postConvWidth * tmpTexelSize; - tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize; - tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight * - srcDepth * tmpTexelSize); - if (!tmpImage) { - if (freeSourceData) - FREE((void *) srcAddr); - return; - } - - transfer_teximage(ctx, dimensions, tmpFormat, tmpImage, - srcWidth, srcHeight, srcDepth, - 0, 0, 0, /* x/y/zoffset */ - tmpRowStride, tmpImageStride, - srcFormat, srcType, srcAddr, srcPacking, transferOps); - - if (freeSourceData) - FREE((void *) srcAddr); - - /* the temp image is our new source image */ - srcWidth = postConvWidth; - srcHeight = postConvHeight; - srcFormat = tmpFormat; - srcType = CHAN_TYPE; - srcAddr = tmpImage; - srcPacking = &ctx->DefaultPacking; - freeSourceData = GL_TRUE; - } - - if (_mesa_is_hardware_tex_format(dstFormat)) { - assert(makeTemp); - if (dimensions == 1) { - GLboolean b; - b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat, - dstXoffset, - srcWidth, - srcFormat, srcType, - srcPacking, srcAddr, - dstAddr); - assert(b); - (void) b; - } - else if (dimensions == 2) { - GLboolean b; - b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat, - dstXoffset, dstYoffset, - srcWidth, srcHeight, - dstRowStridePixels, - srcFormat, srcType, - srcPacking, srcAddr, - dstAddr); - assert(b); - (void) b; - } - else { - GLboolean b; - b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat, - dstXoffset, dstYoffset, dstZoffset, - srcWidth, srcHeight, srcDepth, - dstRowStridePixels, dstImageStridePixels, - srcFormat, srcType, - srcPacking, srcAddr, dstAddr); - assert(b); - (void) b; - } - } - else { - /* software format */ - assert(!makeTemp); - transfer_teximage(ctx, dimensions, dstFormat->BaseFormat, dstAddr, - srcWidth, srcHeight, srcDepth, - dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageStride, - srcFormat, srcType, srcAddr, srcPacking, transferOps); - } - - if (freeSourceData) - FREE((void *) srcAddr); /* the temp image */ -} - - - -/** - * Given a user's uncompressed texture image, this function takes care of - * pixel unpacking, pixel transfer, format conversion and compression. - */ -static void -transfer_compressed_teximage(GLcontext *ctx, GLuint dimensions, - GLsizei width, GLsizei height, GLsizei depth, - GLenum srcFormat, GLenum srcType, - const struct gl_pixelstore_attrib *unpacking, - const GLvoid *source, - const struct gl_texture_format *dstFormat, - GLubyte *dest, - GLint dstRowStride) -{ - GLchan *tempImage = NULL; - GLint srcRowStride; - GLenum baseFormat; - - ASSERT(dimensions == 2); - /* TexelBytes is zero if and only if it's a compressed format */ - ASSERT(dstFormat->TexelBytes == 0); - - baseFormat = dstFormat->BaseFormat; - - if (srcFormat != baseFormat || srcType != CHAN_TYPE || - ctx->_ImageTransferState != 0 || unpacking->SwapBytes) { - /* need to convert user's image to texImage->Format, GLchan */ - GLint comps = components_in_intformat(baseFormat); - GLint postConvWidth = width, postConvHeight = height; - - /* XXX convolution untested */ - if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { - _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, - &postConvHeight); - } - - tempImage = (GLchan*) MALLOC(width * height * comps * sizeof(GLchan)); - if (!tempImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } - transfer_teximage(ctx, dimensions, - baseFormat, /* dest format */ - tempImage, /* dst address */ - width, height, depth, /* src size */ - 0, 0, 0, /* x/y/zoffset */ - comps * width, /* dst row stride */ - comps * width * height, /* dst image stride */ - srcFormat, srcType, /* src format, type */ - source, unpacking, /* src and src packing */ - ctx->_ImageTransferState); - source = tempImage; - width = postConvWidth; - height = postConvHeight; - srcRowStride = width; - } - else { - if (unpacking->RowLength) - srcRowStride = unpacking->RowLength; - else - srcRowStride = width; - } - - _mesa_compress_teximage(ctx, width, height, baseFormat, - (const GLchan *) source, srcRowStride, - dstFormat, dest, dstRowStride); - if (tempImage) { - FREE(tempImage); - } -} - - -#endif /************************************************************/ - - - /** * Validate acces to a PBO for texture data. @@ -2414,7 +1728,6 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, if (!pixels) return; -#if NEWTEXSTORE { const GLint dstRowStride = 0, dstImageStride = 0; GLboolean success; @@ -2431,27 +1744,6 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, return; } } -#else - /* unpack image, apply transfer ops and store in texImage->Data */ - if (texImage->IsCompressed) { - GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, - width); - transfer_compressed_teximage(ctx, 1, width, 1, 1, - format, type, packing, - pixels, texImage->TexFormat, - (GLubyte *) texImage->Data, dstRowStride); - } - else { - _mesa_transfer_teximage(ctx, 1, - texImage->Format, /* base format */ - texImage->TexFormat, texImage->Data, - width, 1, 1, /* src size */ - 0, 0, 0, /* dstX/Y/Zoffset */ - 0, /* dstRowStride */ - 0, /* dstImageStride */ - format, type, pixels, packing); - } -#endif /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { @@ -2513,7 +1805,6 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, if (!pixels) return; -#if NEWTEXSTORE { GLint dstRowStride, dstImageStride = 0; GLboolean success; @@ -2536,27 +1827,6 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, return; } } -#else - /* unpack image, apply transfer ops and store in texImage->Data */ - if (texImage->IsCompressed) { - GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, - width); - transfer_compressed_teximage(ctx, 2, width, height, 1, - format, type, packing, - pixels, texImage->TexFormat, - (GLubyte *) texImage->Data, dstRowStride); - } - else { - _mesa_transfer_teximage(ctx, 2, - texImage->Format, - texImage->TexFormat, texImage->Data, - width, height, 1, /* src size */ - 0, 0, 0, /* dstX/Y/Zoffset */ - texImage->Width * texelBytes, /* dstRowStride */ - 0, /* dstImageStride */ - format, type, pixels, packing); - } -#endif /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { @@ -2610,7 +1880,6 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, return; /* unpack image, apply transfer ops and store in texImage->Data */ -#if NEWTEXSTORE { GLint dstRowStride, dstImageStride; GLboolean success; @@ -2635,26 +1904,6 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, return; } } -#else - if (texImage->IsCompressed) { - GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, - width); - transfer_compressed_teximage(ctx, 3, width, height, depth, - format, type, packing, - pixels, texImage->TexFormat, - (GLubyte *) texImage->Data, dstRowStride); - } - else { - _mesa_transfer_teximage(ctx, 3, - texImage->Format, - texImage->TexFormat, texImage->Data, - width, height, depth, /* src size */ - 0, 0, 0, /* dstX/Y/Zoffset */ - texImage->Width * texelBytes, /* dstRowStride */ - texImage->Width * texImage->Height * texelBytes, - format, type, pixels, packing); - } -#endif /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { @@ -2684,7 +1933,6 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, if (!pixels) return; -#if NEWTEXSTORE { const GLint dstRowStride = 0, dstImageStride = 0; GLboolean success; @@ -2701,33 +1949,6 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, return; } } -#else - if (texImage->IsCompressed) { - GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, - texImage->Width); - GLubyte *dest = _mesa_compressed_image_address(xoffset, 0, 0, - texImage->IntFormat, - texImage->Width, - (GLubyte*) texImage->Data); - transfer_compressed_teximage(ctx, 1, /* dimensions */ - width, 1, 1, /* size to replace */ - format, type, /* source format/type */ - packing, /* source packing */ - pixels, /* source data */ - texImage->TexFormat,/* dest format */ - dest, dstRowStride); - } - else { - _mesa_transfer_teximage(ctx, 1, - texImage->Format, - texImage->TexFormat, texImage->Data, - width, 1, 1, /* src size */ - xoffset, 0, 0, /* dest offsets */ - 0, /* dstRowStride */ - 0, /* dstImageStride */ - format, type, pixels, packing); - } -#endif /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { @@ -2757,7 +1978,6 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, if (!pixels) return; -#if NEWTEXSTORE { GLint dstRowStride = 0, dstImageStride = 0; GLboolean success; @@ -2781,35 +2001,6 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, return; } } -#else - - if (texImage->IsCompressed) { - GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, - texImage->Width); - GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, 0, - texImage->IntFormat, - texImage->Width, - (GLubyte*) texImage->Data); - transfer_compressed_teximage(ctx, 2, /* dimensions */ - width, height, 1, /* size to replace */ - format, type, /* source format/type */ - packing, /* source packing */ - pixels, /* source data */ - texImage->TexFormat,/* dest format */ - dest, dstRowStride); - } - else { - /* old path */ - _mesa_transfer_teximage(ctx, 2, - texImage->Format, - texImage->TexFormat, texImage->Data, - width, height, 1, /* src size */ - xoffset, yoffset, 0, /* dest offsets */ - texImage->Width *texImage->TexFormat->TexelBytes, - 0, /* dstImageStride */ - format, type, pixels, packing); - } -#endif /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { @@ -2838,7 +2029,6 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, if (!pixels) return; -#if NEWTEXSTORE { GLint dstRowStride, dstImageStride; GLboolean success; @@ -2864,34 +2054,7 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, return; } } -#else - if (texImage->IsCompressed) { - GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, - texImage->Width); - GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, zoffset, - texImage->IntFormat, - texImage->Width, - (GLubyte*) texImage->Data); - transfer_compressed_teximage(ctx, 3, /* dimensions */ - width, height, depth,/* size to replace */ - format, type, /* source format/type */ - packing, /* source packing */ - pixels, /* source data */ - texImage->TexFormat,/* dest format */ - dest, dstRowStride); - } - else { - const GLint texelBytes = texImage->TexFormat->TexelBytes; - _mesa_transfer_teximage(ctx, 3, - texImage->Format, - texImage->TexFormat, texImage->Data, - width, height, depth, /* src size */ - xoffset, yoffset, zoffset, /* dest offsets */ - texImage->Width * texelBytes, /* dst row stride */ - texImage->Width * texImage->Height * texelBytes, - format, type, pixels, packing); - } -#endif + /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { _mesa_generate_mipmap(ctx, target, @@ -2960,6 +2123,13 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, /* copy the data */ ASSERT(texImage->CompressedSize == (GLuint) imageSize); MEMCPY(texImage->Data, data, imageSize); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } } @@ -3043,6 +2213,13 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, dest += destRowStride; src += srcRowStride; } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } } @@ -4015,15 +3192,15 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, GLint dstRowStride = _mesa_compressed_row_stride(srcImage->IntFormat, dstWidth); ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA); - _mesa_compress_teximage(ctx, - dstWidth, dstHeight, /* size */ - srcFormat, /* source format */ - (const GLchan *) dstData, /* source buffer */ - dstWidth, /* source row stride */ - dstImage->TexFormat, /* dest format */ - (GLubyte*) dstImage->Data, /* dest buffer */ - dstRowStride ); /* dest row stride */ - + dstImage->TexFormat->StoreImage(ctx, 2, dstImage->Format, + dstImage->TexFormat, + dstImage->Data, + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, 0, /* strides */ + dstWidth, dstHeight, 1, /* size */ + srcFormat, CHAN_TYPE, + dstData, /* src data, actually */ + &ctx->DefaultPacking); /* swap src and dest pointers */ temp = (GLubyte *) srcData; srcData = dstData; |