X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexstore.c;h=9b66ad50b96f697bbe9c03cc3128c333a9031ad1;hb=5314afa27aa8d9260ed0b0a42a6d6050313953da;hp=c4aeaa8f16d3a2f1e54c877e9fd450b37b966813;hpb=1da28fa959e80610ebc9b7a28bfb83e3cad3aee4;p=mesa.git diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index c4aeaa8f16d..9b66ad50b96 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.5 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * Copyright (c) 2008-2009 VMware, Inc. @@ -18,9 +17,10 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ /* @@ -37,9 +37,8 @@ * However, most device drivers will be able to use the fallback functions * in this file. That is, most drivers will have the following bit of * code: - * ctx->Driver.TexImage1D = _mesa_store_teximage1d; - * ctx->Driver.TexImage2D = _mesa_store_teximage2d; - * ctx->Driver.TexImage3D = _mesa_store_teximage3d; + * ctx->Driver.TexImage = _mesa_store_teximage; + * ctx->Driver.TexSubImage = _mesa_store_texsubimage; * etc... * * Texture image processing is actually kind of complicated. We have to do: @@ -55,10 +54,10 @@ #include "glheader.h" #include "bufferobj.h" #include "colormac.h" +#include "format_pack.h" #include "image.h" #include "macros.h" #include "mipmap.h" -#include "mfeatures.h" #include "mtypes.h" #include "pack.h" #include "pbo.h" @@ -67,9 +66,11 @@ #include "texcompress_fxt1.h" #include "texcompress_rgtc.h" #include "texcompress_s3tc.h" +#include "texcompress_etc.h" #include "teximage.h" #include "texstore.h" #include "enums.h" +#include "glformats.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" @@ -340,7 +341,6 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims, logicalBaseFormat == GL_LUMINANCE || logicalBaseFormat == GL_ALPHA || logicalBaseFormat == GL_INTENSITY || - logicalBaseFormat == GL_COLOR_INDEX || logicalBaseFormat == GL_DEPTH_COMPONENT); ASSERT(textureBaseFormat == GL_RGBA || @@ -351,10 +351,9 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims, textureBaseFormat == GL_LUMINANCE || textureBaseFormat == GL_ALPHA || textureBaseFormat == GL_INTENSITY || - textureBaseFormat == GL_COLOR_INDEX || textureBaseFormat == GL_DEPTH_COMPONENT); - tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth + tempImage = malloc(srcWidth * srcHeight * srcDepth * components * sizeof(GLfloat)); if (!tempImage) return NULL; @@ -392,7 +391,7 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims, */ ASSERT(texComponents >= logComponents); - newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth + newImage = malloc(srcWidth * srcHeight * srcDepth * texComponents * sizeof(GLfloat)); if (!newImage) { free(tempImage); @@ -460,9 +459,10 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims, textureBaseFormat == GL_RED || textureBaseFormat == GL_LUMINANCE_ALPHA || textureBaseFormat == GL_LUMINANCE || + textureBaseFormat == GL_INTENSITY || textureBaseFormat == GL_ALPHA); - tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth + tempImage = malloc(srcWidth * srcHeight * srcDepth * components * sizeof(GLuint)); if (!tempImage) return NULL; @@ -500,7 +500,7 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims, */ ASSERT(texComponents >= logComponents); - newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth + newImage = malloc(srcWidth * srcHeight * srcDepth * texComponents * sizeof(GLuint)); if (!newImage) { free(tempImage); @@ -515,9 +515,9 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims, for (k = 0; k < texComponents; k++) { GLint j = map[k]; if (j == ZERO) - newImage[i * texComponents + k] = 0.0F; + newImage[i * texComponents + k] = 0; else if (j == ONE) - newImage[i * texComponents + k] = 1.0F; + newImage[i * texComponents + k] = 1; else newImage[i * texComponents + k] = tempImage[i * logComponents + j]; } @@ -533,7 +533,7 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims, /** - * Make a temporary (color) texture image with GLchan components. + * Make a temporary (color) texture image with GLubyte components. * Apply all needed pixel unpacking and pixel transfer operations. * Note that there are both logicalBaseFormat and textureBaseFormat parameters. * Suppose the user specifies GL_LUMINANCE as the internal texture format @@ -553,21 +553,21 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims, * \param srcType source image type * \param srcAddr source image address * \param srcPacking source image pixel packing - * \return resulting image with format = textureBaseFormat and type = GLchan. + * \return resulting image with format = textureBaseFormat and type = GLubyte. */ -GLchan * -_mesa_make_temp_chan_image(struct gl_context *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) +GLubyte * +_mesa_make_temp_ubyte_image(struct gl_context *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); GLint img, row; - GLchan *tempImage, *dst; + GLubyte *tempImage, *dst; ASSERT(dims >= 1 && dims <= 3); @@ -590,8 +590,8 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims, textureBaseFormat == GL_INTENSITY); /* unpack and transfer the source image */ - tempImage = (GLchan *) malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLchan)); + tempImage = malloc(srcWidth * srcHeight * srcDepth + * components * sizeof(GLubyte)); if (!tempImage) { return NULL; } @@ -606,9 +606,9 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims, srcFormat, srcType, img, 0, 0); for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst, - srcFormat, srcType, src, srcPacking, - transferOps); + _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst, + srcFormat, srcType, src, srcPacking, + transferOps); dst += srcWidth * components; src += srcStride; } @@ -618,7 +618,7 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims, /* one more conversion step */ GLint texComponents = _mesa_components_in_format(textureBaseFormat); GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLchan *newImage; + GLubyte *newImage; GLint i, n; GLubyte map[6]; @@ -631,8 +631,8 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims, */ ASSERT(texComponents >= logComponents); - newImage = (GLchan *) malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLchan)); + newImage = malloc(srcWidth * srcHeight * srcDepth + * texComponents * sizeof(GLubyte)); if (!newImage) { free(tempImage); return NULL; @@ -648,7 +648,7 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims, if (j == ZERO) newImage[i * texComponents + k] = 0; else if (j == ONE) - newImage[i * texComponents + k] = CHAN_MAX; + newImage[i * texComponents + k] = 255; else newImage[i * texComponents + k] = tempImage[i * logComponents + j]; } @@ -851,10 +851,8 @@ _mesa_swizzle_ubyte_image(struct gl_context *ctx, const GLubyte *rgba2dst, GLuint dstComponents, - GLvoid *dstAddr, - GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, GLint dstRowStride, - const GLuint *dstImageOffsets, + GLubyte **dstSlices, GLint srcWidth, GLint srcHeight, GLint srcDepth, const GLvoid *srcAddr, @@ -897,9 +895,7 @@ _mesa_swizzle_ubyte_image(struct gl_context *ctx, srcRowStride == srcWidth * srcComponents && dimensions < 3) { /* 1 and 2D images only */ - GLubyte *dstImage = (GLubyte *) dstAddr - + dstYoffset * dstRowStride - + dstXoffset * dstComponents; + GLubyte *dstImage = dstSlices[0]; swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map, srcWidth * srcHeight); } @@ -907,10 +903,7 @@ _mesa_swizzle_ubyte_image(struct gl_context *ctx, GLint img, row; for (img = 0; img < srcDepth; img++) { const GLubyte *srcRow = srcImage; - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * dstComponents - + dstYoffset * dstRowStride - + dstXoffset * dstComponents; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth); dstRow += dstRowStride; @@ -931,10 +924,8 @@ static void memcpy_texture(struct gl_context *ctx, GLuint dimensions, gl_format dstFormat, - GLvoid *dstAddr, - GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, GLint dstRowStride, - const GLuint *dstImageOffsets, + GLubyte **dstSlices, GLint srcWidth, GLint srcHeight, GLint srcDepth, GLenum srcFormat, GLenum srcType, const GLvoid *srcAddr, @@ -949,58 +940,69 @@ memcpy_texture(struct gl_context *ctx, const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLint bytesPerRow = srcWidth * texelBytes; -#if 0 - /* XXX update/re-enable for dstImageOffsets array */ - const GLint bytesPerImage = srcHeight * bytesPerRow; - const GLint bytesPerTexture = srcDepth * bytesPerImage; - GLubyte *dstImage = (GLubyte *) dstAddr - + dstZoffset * dstImageStride - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - if (dstRowStride == srcRowStride && - dstRowStride == bytesPerRow && - ((dstImageStride == srcImageStride && - dstImageStride == bytesPerImage) || - (srcDepth == 1))) { - /* one big memcpy */ - ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture); + dstRowStride == bytesPerRow) { + /* memcpy image by image */ + GLint img; + for (img = 0; img < srcDepth; img++) { + GLubyte *dstImage = dstSlices[img]; + memcpy(dstImage, srcImage, bytesPerRow * srcHeight); + srcImage += srcImageStride; + } } - else - { + else { + /* memcpy row by row */ GLint img, row; for (img = 0; img < srcDepth; img++) { const GLubyte *srcRow = srcImage; - GLubyte *dstRow = dstImage; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { - ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow); + memcpy(dstRow, srcRow, bytesPerRow); dstRow += dstRowStride; srcRow += srcRowStride; } srcImage += srcImageStride; - dstImage += dstImageStride; } } -#endif +} - GLint img, row; + +/** + * General-case function for storing a color texture images with + * components that can be represented with ubytes. Example destination + * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565. + */ +static GLboolean +store_ubyte_texture(TEXSTORE_PARAMS) +{ + const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte); + GLubyte *tempImage, *src; + GLint img; + + tempImage = _mesa_make_temp_ubyte_image(ctx, dims, + baseInternalFormat, + GL_RGBA, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); + if (!tempImage) + return GL_FALSE; + + src = tempImage; for (img = 0; img < srcDepth; img++) { - const GLubyte *srcRow = srcImage; - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow); - dstRow += dstRowStride; - srcRow += srcRowStride; - } - srcImage += srcImageStride; + _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight, + src, srcRowStride, + dstSlices[img], dstRowStride); + src += srcHeight * srcRowStride; } + free(tempImage); + + return GL_TRUE; } + /** * Store a 32-bit integer or float depth component texture image. */ @@ -1008,35 +1010,22 @@ static GLboolean _mesa_texstore_z32(TEXSTORE_PARAMS) { const GLuint depthScale = 0xffffffff; - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum dstType = _mesa_get_format_datatype(dstFormat); + GLenum dstType; (void) dims; ASSERT(dstFormat == MESA_FORMAT_Z32 || dstFormat == MESA_FORMAT_Z32_FLOAT); - ASSERT(texelBytes == sizeof(GLuint)); + ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint)); - if (ctx->Pixel.DepthScale == 1.0f && - ctx->Pixel.DepthBias == 0.0f && - !srcPacking->SwapBytes && - baseInternalFormat == GL_DEPTH_COMPONENT && - srcFormat == GL_DEPTH_COMPONENT && - srcType == dstType) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + if (dstFormat == MESA_FORMAT_Z32) + dstType = GL_UNSIGNED_INT; + else + dstType = GL_FLOAT; + + { /* general path */ GLint img, row; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { const GLvoid *src = _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); @@ -1058,7 +1047,6 @@ static GLboolean _mesa_texstore_x8_z24(TEXSTORE_PARAMS) { const GLuint depthScale = 0xffffff; - const GLuint texelBytes = 4; (void) dims; ASSERT(dstFormat == MESA_FORMAT_X8_Z24); @@ -1067,10 +1055,7 @@ _mesa_texstore_x8_z24(TEXSTORE_PARAMS) /* general path */ GLint img, row; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { const GLvoid *src = _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); @@ -1092,7 +1077,6 @@ static GLboolean _mesa_texstore_z24_x8(TEXSTORE_PARAMS) { const GLuint depthScale = 0xffffff; - const GLuint texelBytes = 4; (void) dims; ASSERT(dstFormat == MESA_FORMAT_Z24_X8); @@ -1101,10 +1085,7 @@ _mesa_texstore_z24_x8(TEXSTORE_PARAMS) /* general path */ GLint img, row; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { const GLvoid *src = _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); @@ -1130,33 +1111,15 @@ static GLboolean _mesa_texstore_z16(TEXSTORE_PARAMS) { const GLuint depthScale = 0xffff; - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); (void) dims; ASSERT(dstFormat == MESA_FORMAT_Z16); - ASSERT(texelBytes == sizeof(GLushort)); + ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort)); - if (ctx->Pixel.DepthScale == 1.0f && - ctx->Pixel.DepthBias == 0.0f && - !srcPacking->SwapBytes && - baseInternalFormat == GL_DEPTH_COMPONENT && - srcFormat == GL_DEPTH_COMPONENT && - srcType == GL_UNSIGNED_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ GLint img, row; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { const GLvoid *src = _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); @@ -1178,42 +1141,23 @@ _mesa_texstore_z16(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgb565(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - ASSERT(dstFormat == MESA_FORMAT_RGB565 || dstFormat == MESA_FORMAT_RGB565_REV); - ASSERT(texelBytes == 2); + ASSERT(_mesa_get_format_bytes(dstFormat) == 2); if (!ctx->_ImageTransferState && !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_RGB565 && baseInternalFormat == GL_RGB && srcFormat == GL_RGB && - srcType == GL_UNSIGNED_SHORT_5_6_5) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGB && - srcFormat == GL_RGB && - srcType == GL_UNSIGNED_BYTE && - dims == 2) { + srcType == GL_UNSIGNED_BYTE && + dims == 2) { /* do optimized tex store */ const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); const GLubyte *src = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0); - GLubyte *dst = (GLubyte *) dstAddr - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dst = dstSlices[0]; GLint row, col; for (row = 0; row < srcHeight; row++) { const GLubyte *srcUB = (const GLubyte *) src; @@ -1236,45 +1180,10 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS) } } else { - /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - /* check for byteswapped format */ - if (dstFormat == MESA_FORMAT_RGB565) { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 3; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 3; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); + return store_ubyte_texture(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); } return GL_TRUE; } @@ -1287,58 +1196,28 @@ static GLboolean _mesa_texstore_rgba8888(TEXSTORE_PARAMS) { const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_RGBA8888 || - dstFormat == MESA_FORMAT_RGBA8888_REV); - ASSERT(texelBytes == 4); + dstFormat == MESA_FORMAT_RGBA8888_REV || + dstFormat == MESA_FORMAT_RGBX8888 || + dstFormat == MESA_FORMAT_RGBX8888_REV); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_RGBA8888 && - baseInternalFormat == GL_RGBA && - ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || - (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian))) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_RGBA8888_REV && - baseInternalFormat == GL_RGBA && - ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || - (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian))) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - (srcType == GL_UNSIGNED_BYTE || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { + (srcType == GL_UNSIGNED_BYTE || + srcType == GL_UNSIGNED_INT_8_8_8_8 || + srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && + can_swizzle(baseInternalFormat) && + can_swizzle(srcFormat)) { GLubyte dstmap[4]; /* dstmap - how to swizzle from RGBA to dst format: */ - if ((littleEndian && dstFormat == MESA_FORMAT_RGBA8888) || - (!littleEndian && dstFormat == MESA_FORMAT_RGBA8888_REV)) { + if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 || + dstFormat == MESA_FORMAT_RGBX8888)) || + (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV || + dstFormat == MESA_FORMAT_RGBX8888_REV))) { dstmap[3] = 0; dstmap[2] = 1; dstmap[1] = 2; @@ -1356,52 +1235,15 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS) srcType, baseInternalFormat, dstmap, 4, - dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcAddr, srcPacking); } else { - /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - if (dstFormat == MESA_FORMAT_RGBA8888) { - for (col = 0; col < srcWidth; col++) { - dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]), - CHAN_TO_UBYTE(src[ACOMP]) ); - src += 4; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]), - CHAN_TO_UBYTE(src[ACOMP]) ); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); + return store_ubyte_texture(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); } return GL_TRUE; } @@ -1411,65 +1253,28 @@ static GLboolean _mesa_texstore_argb8888(TEXSTORE_PARAMS) { const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = GL_RGBA; ASSERT(dstFormat == MESA_FORMAT_ARGB8888 || dstFormat == MESA_FORMAT_ARGB8888_REV || dstFormat == MESA_FORMAT_XRGB8888 || dstFormat == MESA_FORMAT_XRGB8888_REV ); - ASSERT(texelBytes == 4); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); if (!ctx->_ImageTransferState && !srcPacking->SwapBytes && (dstFormat == MESA_FORMAT_ARGB8888 || dstFormat == MESA_FORMAT_XRGB8888) && - baseInternalFormat == GL_RGBA && - srcFormat == GL_BGRA && - ((srcType == GL_UNSIGNED_BYTE && littleEndian) || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { - /* simple memcpy path (little endian) */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - (dstFormat == MESA_FORMAT_ARGB8888_REV || - dstFormat == MESA_FORMAT_XRGB8888_REV) && - baseInternalFormat == GL_RGBA && - srcFormat == GL_BGRA && - ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || - srcType == GL_UNSIGNED_INT_8_8_8_8)) { - /* simple memcpy path (big endian) */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - (dstFormat == MESA_FORMAT_ARGB8888 || - dstFormat == MESA_FORMAT_XRGB8888) && - srcFormat == GL_RGB && - (baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB) && - srcType == GL_UNSIGNED_BYTE) { + srcFormat == GL_RGB && + (baseInternalFormat == GL_RGBA || + baseInternalFormat == GL_RGB) && + srcType == GL_UNSIGNED_BYTE) { int img, row, col; for (img = 0; img < srcDepth; img++) { const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLuint *d4 = (GLuint *) dstRow; for (col = 0; col < srcWidth; col++) { @@ -1483,6 +1288,32 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) } } } + else if (!ctx->_ImageTransferState && + !srcPacking->SwapBytes && + dstFormat == MESA_FORMAT_ARGB8888 && + srcFormat == GL_LUMINANCE_ALPHA && + baseInternalFormat == GL_RGBA && + srcType == GL_UNSIGNED_BYTE) { + /* special case of storing LA -> ARGB8888 */ + int img, row, col; + const GLint srcRowStride = + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); + for (img = 0; img < srcDepth; img++) { + const GLubyte *srcRow = (const GLubyte *) + _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, + srcHeight, srcFormat, srcType, img, 0, 0); + GLubyte *dstRow = dstSlices[img]; + for (row = 0; row < srcHeight; row++) { + GLuint *d4 = (GLuint *) dstRow; + for (col = 0; col < srcWidth; col++) { + GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1]; + d4[col] = PACK_COLOR_8888(a, l, l, l); + } + dstRow += dstRowStride; + srcRow += srcRowStride; + } + } + } else if (!ctx->_ImageTransferState && !srcPacking->SwapBytes && dstFormat == MESA_FORMAT_ARGB8888 && @@ -1502,10 +1333,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLuint *d4 = (GLuint *) dstRow; for (col = 0; col < srcWidth; col++) { @@ -1555,62 +1383,16 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) srcType, baseInternalFormat, dstmap, 4, - dstAddr, dstXoffset, dstYoffset, dstZoffset, dstRowStride, - dstImageOffsets, + dstSlices, srcWidth, srcHeight, srcDepth, srcAddr, srcPacking); } else { - /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - if (dstFormat == MESA_FORMAT_ARGB8888) { - for (col = 0; col < srcWidth; col++) { - dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]), - CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 4; - } - } - else if (dstFormat == MESA_FORMAT_XRGB8888) { - for (col = 0; col < srcWidth; col++) { - dstUI[col] = PACK_COLOR_8888( 0xff, - CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 4; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]), - CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); + return store_ubyte_texture(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); } return GL_TRUE; } @@ -1619,31 +1401,13 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgb888(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - ASSERT(dstFormat == MESA_FORMAT_RGB888); - ASSERT(texelBytes == 3); + ASSERT(_mesa_get_format_bytes(dstFormat) == 3); if (!ctx->_ImageTransferState && !srcPacking->SwapBytes && - baseInternalFormat == GL_RGB && - srcFormat == GL_BGR && - srcType == GL_UNSIGNED_BYTE && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { + srcFormat == GL_RGBA && + srcType == GL_UNSIGNED_BYTE) { /* extract RGB from RGBA */ GLint img, row, col; for (img = 0; img < srcDepth; img++) { @@ -1651,10 +1415,7 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS) _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { for (col = 0; col < srcWidth; col++) { dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP]; @@ -1685,58 +1446,15 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS) srcType, baseInternalFormat, dstmap, 3, - dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcAddr, srcPacking); } else { - /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src = (const GLchan *) tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { -#if 0 - if (littleEndian) { - for (col = 0; col < srcWidth; col++) { - dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]); - dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]); - dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]); - srcUB += 3; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dstRow[col * 3 + 0] = srcUB[BCOMP]; - dstRow[col * 3 + 1] = srcUB[GCOMP]; - dstRow[col * 3 + 2] = srcUB[RCOMP]; - srcUB += 3; - } - } -#else - for (col = 0; col < srcWidth; col++) { - dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]); - dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]); - dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]); - src += 3; - } -#endif - dstRow += dstRowStride; - } - } - free((void *) tempImage); + return store_ubyte_texture(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); } return GL_TRUE; } @@ -1745,31 +1463,13 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_bgr888(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - ASSERT(dstFormat == MESA_FORMAT_BGR888); - ASSERT(texelBytes == 3); + ASSERT(_mesa_get_format_bytes(dstFormat) == 3); if (!ctx->_ImageTransferState && !srcPacking->SwapBytes && - baseInternalFormat == GL_RGB && - srcFormat == GL_RGB && - srcType == GL_UNSIGNED_BYTE && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { + srcFormat == GL_RGBA && + srcType == GL_UNSIGNED_BYTE) { /* extract BGR from RGBA */ int img, row, col; for (img = 0; img < srcDepth; img++) { @@ -1777,10 +1477,7 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS) _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { for (col = 0; col < srcWidth; col++) { dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP]; @@ -1811,36 +1508,61 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS) srcType, baseInternalFormat, dstmap, 3, - dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcAddr, srcPacking); } else { + return store_ubyte_texture(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + } + return GL_TRUE; +} + + +static GLboolean +_mesa_texstore_argb2101010(TEXSTORE_PARAMS) +{ + ASSERT(dstFormat == MESA_FORMAT_ARGB2101010 || + dstFormat == MESA_FORMAT_XRGB2101010_UNORM); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); + + { /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, + /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0 + * if the internal format is RGB. */ + const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, - baseFormat, + GL_RGBA, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src = (const GLchan *) tempImage; + srcPacking, + ctx->_ImageTransferState); + const GLfloat *src = tempImage; GLint img, row, col; if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]); - dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]); - dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]); - src += 3; + GLubyte *dstRow = dstSlices[img]; + if (baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB) { + for (row = 0; row < srcHeight; row++) { + GLuint *dstUI = (GLuint *) dstRow; + for (col = 0; col < srcWidth; col++) { + GLushort a,r,g,b; + + UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); + UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); + dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b); + src += 4; + } + dstRow += dstRowStride; } - dstRow += dstRowStride; + } else { + ASSERT(0); } } free((void *) tempImage); @@ -1849,317 +1571,37 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS) } +/** + * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats. + */ static GLboolean -_mesa_texstore_argb4444(TEXSTORE_PARAMS) +_mesa_texstore_unorm44(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_ARGB4444 || - dstFormat == MESA_FORMAT_ARGB4444_REV); - ASSERT(texelBytes == 2); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_ARGB4444 && - baseInternalFormat == GL_RGBA && - srcFormat == GL_BGRA && - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - if (dstFormat == MESA_FORMAT_ARGB4444) { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]), - CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 4; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]), - CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_rgba5551(TEXSTORE_PARAMS) -{ - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_RGBA5551); - ASSERT(texelBytes == 2); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_RGBA5551 && - baseInternalFormat == GL_RGBA && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_SHORT_5_5_5_1) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src =tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]), - CHAN_TO_UBYTE(src[ACOMP]) ); - src += 4; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_argb1555(TEXSTORE_PARAMS) -{ - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_ARGB1555 || - dstFormat == MESA_FORMAT_ARGB1555_REV); - ASSERT(texelBytes == 2); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_ARGB1555 && - baseInternalFormat == GL_RGBA && - srcFormat == GL_BGRA && - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src =tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - if (dstFormat == MESA_FORMAT_ARGB1555) { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]), - CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 4; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]), - CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_argb2101010(TEXSTORE_PARAMS) -{ - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_ARGB2101010); - ASSERT(texelBytes == 4); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_ARGB2101010 && - srcFormat == GL_BGRA && - srcType == GL_UNSIGNED_INT_2_10_10_10_REV && - baseInternalFormat == GL_RGBA) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - if (baseInternalFormat == GL_RGBA) { - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b); - src += 4; - } - dstRow += dstRowStride; - } - } else if (baseInternalFormat == GL_RGB) { - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort r,g,b; - - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - dstUI[col] = PACK_COLOR_2101010_US(0xffff, r, g, b); - src += 4; - } - dstRow += dstRowStride; - } - } else { - ASSERT(0); - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats. - */ -static GLboolean -_mesa_texstore_unorm44(TEXSTORE_PARAMS) -{ - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_AL44); - ASSERT(texelBytes == 1); + ASSERT(_mesa_get_format_bytes(dstFormat) == 1); { /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, + const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, baseInternalFormat, baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); - const GLchan *src = tempImage; + const GLubyte *src = tempImage; GLint img, row, col; if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLubyte *dstUS = (GLubyte *) dstRow; for (col = 0; col < srcWidth; col++) { /* src[0] is luminance, src[1] is alpha */ - dstUS[col] = PACK_COLOR_44( CHAN_TO_UBYTE(src[1]), - CHAN_TO_UBYTE(src[0]) ); + dstUS[col] = PACK_COLOR_44( src[1], + src[0] ); src += 2; } dstRow += dstRowStride; @@ -2178,37 +1620,19 @@ static GLboolean _mesa_texstore_unorm88(TEXSTORE_PARAMS) { const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV || - dstFormat == MESA_FORMAT_RG88 || - dstFormat == MESA_FORMAT_RG88_REV); - ASSERT(texelBytes == 2); + dstFormat == MESA_FORMAT_GR88 || + dstFormat == MESA_FORMAT_RG88); + ASSERT(_mesa_get_format_bytes(dstFormat) == 2); if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - ((dstFormat == MESA_FORMAT_AL88 && - baseInternalFormat == GL_LUMINANCE_ALPHA && - srcFormat == GL_LUMINANCE_ALPHA) || - (dstFormat == MESA_FORMAT_RG88 && - baseInternalFormat == srcFormat)) && + littleEndian && srcType == GL_UNSIGNED_BYTE && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - littleEndian && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { + can_swizzle(baseInternalFormat) && + can_swizzle(srcFormat)) { GLubyte dstmap[4]; /* dstmap - how to swizzle from RGBA to dst format: @@ -2225,8 +1649,8 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS) } } else { - if ((littleEndian && dstFormat == MESA_FORMAT_RG88) || - (!littleEndian && dstFormat == MESA_FORMAT_RG88_REV)) { + if ((littleEndian && dstFormat == MESA_FORMAT_GR88) || + (!littleEndian && dstFormat == MESA_FORMAT_RG88)) { dstmap[0] = 0; dstmap[1] = 1; } @@ -2243,44 +1667,40 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS) srcType, baseInternalFormat, dstmap, 2, - dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcAddr, srcPacking); } else { /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, + const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, baseInternalFormat, baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); - const GLchan *src = tempImage; + const GLubyte *src = tempImage; GLint img, row, col; if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLushort *dstUS = (GLushort *) dstRow; if (dstFormat == MESA_FORMAT_AL88 || - dstFormat == MESA_FORMAT_RG88) { + dstFormat == MESA_FORMAT_GR88) { for (col = 0; col < srcWidth; col++) { - /* src[0] is luminance, src[1] is alpha */ - dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]), - CHAN_TO_UBYTE(src[0]) ); + /* src[0] is luminance (or R), src[1] is alpha (or G) */ + dstUS[col] = PACK_COLOR_88( src[1], + src[0] ); src += 2; } } else { for (col = 0; col < srcWidth; col++) { - /* src[0] is luminance, src[1] is alpha */ - dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]), - CHAN_TO_UBYTE(src[0]) ); + /* src[0] is luminance (or R), src[1] is alpha (or G) */ + dstUS[col] = PACK_COLOR_88_REV( src[1], + src[0] ); src += 2; } } @@ -2299,34 +1719,15 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_unorm1616(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_AL1616 || dstFormat == MESA_FORMAT_AL1616_REV || - dstFormat == MESA_FORMAT_RG1616 || - dstFormat == MESA_FORMAT_RG1616_REV); - ASSERT(texelBytes == 4); + dstFormat == MESA_FORMAT_GR1616 || + dstFormat == MESA_FORMAT_RG1616); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - ((dstFormat == MESA_FORMAT_AL1616 && - baseInternalFormat == GL_LUMINANCE_ALPHA && - srcFormat == GL_LUMINANCE_ALPHA) || - (dstFormat == MESA_FORMAT_RG1616 && - baseInternalFormat == srcFormat)) && - srcType == GL_UNSIGNED_SHORT && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2340,14 +1741,11 @@ _mesa_texstore_unorm1616(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLuint *dstUI = (GLuint *) dstRow; if (dstFormat == MESA_FORMAT_AL1616 || - dstFormat == MESA_FORMAT_RG1616) { + dstFormat == MESA_FORMAT_GR1616) { for (col = 0; col < srcWidth; col++) { GLushort l, a; @@ -2380,30 +1778,15 @@ _mesa_texstore_unorm1616(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_unorm16(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_R16 || dstFormat == MESA_FORMAT_A16 || dstFormat == MESA_FORMAT_L16 || dstFormat == MESA_FORMAT_I16); - ASSERT(texelBytes == 2); + ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_SHORT && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2417,10 +1800,7 @@ _mesa_texstore_unorm16(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLushort *dstUS = (GLushort *) dstRow; for (col = 0; col < srcWidth; col++) { @@ -2442,43 +1822,29 @@ _mesa_texstore_unorm16(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgba_16(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + ASSERT(dstFormat == MESA_FORMAT_RGBA_16 || + dstFormat == MESA_FORMAT_XBGR16161616_UNORM); + ASSERT(_mesa_get_format_bytes(dstFormat) == 8); - ASSERT(dstFormat == MESA_FORMAT_RGBA_16); - ASSERT(texelBytes == 8); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGBA && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ + /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0 + * if the internal format is RGB. */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, - baseFormat, + GL_RGBA, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking, ctx->_ImageTransferState); const GLfloat *src = tempImage; GLint img, row, col; + if (!tempImage) return GL_FALSE; + for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLushort *dstUS = (GLushort *) dstRow; for (col = 0; col < srcWidth; col++) { @@ -2506,27 +1872,13 @@ _mesa_texstore_rgba_16(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGB_16 || - dstFormat == MESA_FORMAT_SIGNED_RGBA_16); + dstFormat == MESA_FORMAT_SIGNED_RGBA_16 || + dstFormat == MESA_FORMAT_XBGR16161616_SNORM); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGBA && - dstFormat == MESA_FORMAT_SIGNED_RGBA_16 && - srcFormat == GL_RGBA && - srcType == GL_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2546,10 +1898,7 @@ _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) * 3 or 4 components/pixel here. */ for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLshort *dstRowS = (GLshort *) dstRow; if (dstFormat == MESA_FORMAT_SIGNED_RGBA_16) { @@ -2563,7 +1912,22 @@ _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) } dstRow += dstRowStride; src += 4 * srcWidth; - } else { + } + else if (dstFormat == MESA_FORMAT_XBGR16161616_SNORM) { + for (col = 0; col < srcWidth; col++) { + GLuint c; + + for (c = 0; c < 3; c++) { + GLshort p; + UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]); + dstRowS[col * comps + c] = p; + } + dstRowS[col * comps + 3] = 32767; + } + dstRow += dstRowStride; + src += 3 * srcWidth; + } + else { for (col = 0; col < srcWidth; col++) { GLuint c; for (c = 0; c < comps; c++) { @@ -2583,91 +1947,24 @@ _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) } +/** + * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8. + */ static GLboolean -_mesa_texstore_rgb332(TEXSTORE_PARAMS) +_mesa_texstore_unorm8(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - ASSERT(dstFormat == MESA_FORMAT_RGB332); - ASSERT(texelBytes == 1); + ASSERT(dstFormat == MESA_FORMAT_A8 || + dstFormat == MESA_FORMAT_L8 || + dstFormat == MESA_FORMAT_I8 || + dstFormat == MESA_FORMAT_R8); + ASSERT(_mesa_get_format_bytes(dstFormat) == 1); if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGB && - srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLchan *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]), - CHAN_TO_UBYTE(src[GCOMP]), - CHAN_TO_UBYTE(src[BCOMP]) ); - src += 3; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8. - */ -static GLboolean -_mesa_texstore_unorm8(TEXSTORE_PARAMS) -{ - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_A8 || - dstFormat == MESA_FORMAT_L8 || - dstFormat == MESA_FORMAT_I8 || - dstFormat == MESA_FORMAT_R8); - ASSERT(texelBytes == 1); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { + srcType == GL_UNSIGNED_BYTE && + can_swizzle(baseInternalFormat) && + can_swizzle(srcFormat)) { GLubyte dstmap[4]; /* dstmap - how to swizzle from RGBA to dst format: @@ -2687,31 +1984,27 @@ _mesa_texstore_unorm8(TEXSTORE_PARAMS) srcType, baseInternalFormat, dstmap, 1, - dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcAddr, srcPacking); } else { /* general path */ - const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, + const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, baseInternalFormat, baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); - const GLchan *src = tempImage; + const GLubyte *src = tempImage; GLint img, row, col; if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { for (col = 0; col < srcWidth; col++) { - dstRow[col] = CHAN_TO_UBYTE(src[col]); + dstRow[col] = src[col]; } dstRow += dstRowStride; src += srcWidth; @@ -2724,50 +2017,6 @@ _mesa_texstore_unorm8(TEXSTORE_PARAMS) -static GLboolean -_mesa_texstore_ci8(TEXSTORE_PARAMS) -{ - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - - (void) dims; (void) baseInternalFormat; - ASSERT(dstFormat == MESA_FORMAT_CI8); - ASSERT(texelBytes == 1); - ASSERT(baseInternalFormat == GL_COLOR_INDEX); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_COLOR_INDEX && - srcType == GL_UNSIGNED_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - /* general path */ - GLint img, row; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - const GLvoid *src = _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); - _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow, - srcType, src, srcPacking, - ctx->_ImageTransferState); - dstRow += dstRowStride; - } - } - } - return GL_TRUE; -} - - /** * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. */ @@ -2775,13 +2024,12 @@ static GLboolean _mesa_texstore_ycbcr(TEXSTORE_PARAMS) { const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); (void) ctx; (void) dims; (void) baseInternalFormat; ASSERT((dstFormat == MESA_FORMAT_YCBCR) || (dstFormat == MESA_FORMAT_YCBCR_REV)); - ASSERT(texelBytes == 2); + ASSERT(_mesa_get_format_bytes(dstFormat) == 2); ASSERT(ctx->Extensions.MESA_ycbcr_texture); ASSERT(srcFormat == GL_YCBCR_MESA); ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) || @@ -2790,9 +2038,8 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS) /* always just memcpy since no pixel transfer ops apply */ memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, + dstFormat, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); @@ -2804,10 +2051,7 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS) !littleEndian) { GLint img, row; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { _mesa_swap2((GLushort *) dstRow, srcWidth); dstRow += dstRowStride; @@ -2830,17 +2074,7 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS) (srcFormat == GL_DUDV_ATI)); ASSERT(baseInternalFormat == GL_DUDV_ATI); - if (!srcPacking->SwapBytes && srcType == GL_BYTE && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (srcType == GL_BYTE) { + if (srcType == GL_BYTE) { GLubyte dstmap[4]; /* dstmap - how to swizzle from RGBA to dst format: @@ -2861,8 +2095,7 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS) GL_UNSIGNED_BYTE, /* hack */ GL_LUMINANCE_ALPHA, /* hack */ dstmap, 2, - dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcAddr, srcPacking); } @@ -2874,7 +2107,7 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS) GLbyte *tempImage, *dst, *src; GLint row; - tempImage = (GLbyte *) malloc(srcWidth * srcHeight * srcDepth + tempImage = malloc(srcWidth * srcHeight * srcDepth * components * sizeof(GLbyte)); if (!tempImage) return GL_FALSE; @@ -2894,9 +2127,7 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS) } src = tempImage; - dst = (GLbyte *) dstAddr - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + dst = (GLbyte *) dstSlices[0]; for (row = 0; row < srcHeight; row++) { memcpy(dst, src, srcWidth * texelBytes); dst += dstRowStride; @@ -2914,28 +2145,15 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_snorm8(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_A8 || dstFormat == MESA_FORMAT_SIGNED_L8 || dstFormat == MESA_FORMAT_SIGNED_I8 || dstFormat == MESA_FORMAT_SIGNED_R8); - ASSERT(texelBytes == 1); + ASSERT(_mesa_get_format_bytes(dstFormat) == 1); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2949,10 +2167,7 @@ _mesa_texstore_snorm8(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLbyte *dstRow = (GLbyte *) dstSlices[img]; for (row = 0; row < srcHeight; row++) { for (col = 0; col < srcWidth; col++) { dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]); @@ -2973,28 +2188,13 @@ _mesa_texstore_snorm8(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_snorm88(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 || dstFormat == MESA_FORMAT_SIGNED_RG88_REV); - ASSERT(texelBytes == 2); + ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_BYTE && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3008,10 +2208,7 @@ _mesa_texstore_snorm88(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLbyte *dstRow = (GLbyte *) dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLbyte *dst = dstRow; for (col = 0; col < srcWidth; col++) { @@ -3032,30 +2229,15 @@ _mesa_texstore_snorm88(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_snorm16(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_R16 || dstFormat == MESA_FORMAT_SIGNED_A16 || dstFormat == MESA_FORMAT_SIGNED_L16 || dstFormat == MESA_FORMAT_SIGNED_I16); - ASSERT(texelBytes == 2); + ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_SHORT && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3069,10 +2251,7 @@ _mesa_texstore_snorm16(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLshort *dstUS = (GLshort *) dstRow; for (col = 0; col < srcWidth; col++) { @@ -3096,28 +2275,13 @@ _mesa_texstore_snorm16(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_snorm1616(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 || dstFormat == MESA_FORMAT_SIGNED_GR1616); - ASSERT(texelBytes == 4); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_SHORT && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3131,10 +2295,7 @@ _mesa_texstore_snorm1616(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLshort *dst = (GLshort *) dstRow; for (col = 0; col < srcWidth; col++) { @@ -3156,16 +2317,17 @@ _mesa_texstore_snorm1616(TEXSTORE_PARAMS) } /** - * Store a texture in MESA_FORMAT_SIGNED_RGBX8888. + * Store a texture in MESA_FORMAT_SIGNED_RGBX8888 or + * MESA_FORMAT_XBGR8888_SNORM. */ static GLboolean _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888); - ASSERT(texelBytes == 4); + ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888 || + dstFormat == MESA_FORMAT_XBGR8888_SNORM); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); { /* general path */ @@ -3181,19 +2343,28 @@ _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLbyte *dstRow = (GLbyte *) dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLbyte *dst = dstRow; - for (col = 0; col < srcWidth; col++) { - dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); - dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); - dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); - dst[0] = 127; - srcRow += 3; - dst += 4; + if (dstFormat == MESA_FORMAT_SIGNED_RGBX8888) { + for (col = 0; col < srcWidth; col++) { + dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); + dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); + dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); + dst[0] = 127; + srcRow += 3; + dst += 4; + } + } + else { + for (col = 0; col < srcWidth; col++) { + dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); + dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); + dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); + dst[3] = 127; + srcRow += 3; + dst += 4; + } } dstRow += dstRowStride; } @@ -3212,43 +2383,13 @@ _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 || dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV); - ASSERT(texelBytes == 4); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_SIGNED_RGBA8888 && - baseInternalFormat == GL_RGBA && - ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) || - (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV && - baseInternalFormat == GL_RGBA && - ((srcFormat == GL_RGBA && srcType == GL_BYTE && littleEndian) || - (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3262,10 +2403,7 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLbyte *dstRow = (GLbyte *) dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLbyte *dst = dstRow; if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) { @@ -3314,33 +2452,26 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) srcFormat == GL_STENCIL_INDEX); ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT); - if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f && - ctx->Pixel.DepthBias == 0.0f && - !srcPacking->SwapBytes) { - /* simple path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (srcFormat == GL_DEPTH_COMPONENT || - srcFormat == GL_STENCIL_INDEX) { + if (srcFormat == GL_DEPTH_COMPONENT || + srcFormat == GL_STENCIL_INDEX) { + GLuint *depth = malloc(srcWidth * sizeof(GLuint)); + GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte)); + + if (!depth || !stencil) { + free(depth); + free(stencil); + return GL_FALSE; + } + /* In case we only upload depth we need to preserve the stencil */ for (img = 0; img < srcDepth; img++) { - GLuint *dstRow = (GLuint *) dstAddr - + dstImageOffsets[dstZoffset + img] - + dstYoffset * dstRowStride / sizeof(GLuint) - + dstXoffset; + GLuint *dstRow = (GLuint *) dstSlices[img]; const GLubyte *src = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); for (row = 0; row < srcHeight; row++) { - GLuint depth[MAX_WIDTH]; - GLubyte stencil[MAX_WIDTH]; GLint i; GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; @@ -3378,6 +2509,9 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) dstRow += dstRowStride / sizeof(GLuint); } } + + free(depth); + free(stencil); } return GL_TRUE; } @@ -3393,6 +2527,8 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS) const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLint img, row; + GLuint *depth; + GLubyte *stencil; ASSERT(dstFormat == MESA_FORMAT_S8_Z24); ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || @@ -3401,19 +2537,23 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS) ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT); + depth = malloc(srcWidth * sizeof(GLuint)); + stencil = malloc(srcWidth * sizeof(GLubyte)); + + if (!depth || !stencil) { + free(depth); + free(stencil); + return GL_FALSE; + } + for (img = 0; img < srcDepth; img++) { - GLuint *dstRow = (GLuint *) dstAddr - + dstImageOffsets[dstZoffset + img] - + dstYoffset * dstRowStride / sizeof(GLuint) - + dstXoffset; + GLuint *dstRow = (GLuint *) dstSlices[img]; const GLubyte *src = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); for (row = 0; row < srcHeight; row++) { - GLuint depth[MAX_WIDTH]; - GLubyte stencil[MAX_WIDTH]; GLint i; GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; @@ -3452,6 +2592,10 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS) dstRow += dstRowStride / sizeof(GLuint); } } + + free(depth); + free(stencil); + return GL_TRUE; } @@ -3465,35 +2609,23 @@ _mesa_texstore_s8(TEXSTORE_PARAMS) ASSERT(dstFormat == MESA_FORMAT_S8); ASSERT(srcFormat == GL_STENCIL_INDEX); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLint img, row; - + GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte)); + + if (!stencil) + return GL_FALSE; + for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] - + dstYoffset * dstRowStride / sizeof(GLuint) - + dstXoffset; + GLubyte *dstRow = dstSlices[img]; const GLubyte *src = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); for (row = 0; row < srcHeight; row++) { - GLubyte stencil[MAX_WIDTH]; GLint i; /* get the 8-bit stencil values */ @@ -3511,6 +2643,7 @@ _mesa_texstore_s8(TEXSTORE_PARAMS) } } + free(stencil); } return GL_TRUE; @@ -3529,9 +2662,14 @@ _mesa_texstore_s8(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - const GLint components = _mesa_components_in_format(baseFormat); + GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + GLint components = _mesa_components_in_format(baseFormat); + + /* this forces alpha to 1 in _mesa_make_temp_float_image */ + if (dstFormat == MESA_FORMAT_XBGR32323232_FLOAT) { + baseFormat = GL_RGBA; + components = 4; + } ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 || dstFormat == MESA_FORMAT_RGB_FLOAT32 || @@ -3540,7 +2678,8 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 || dstFormat == MESA_FORMAT_INTENSITY_FLOAT32 || dstFormat == MESA_FORMAT_R_FLOAT32 || - dstFormat == MESA_FORMAT_RG_FLOAT32); + dstFormat == MESA_FORMAT_RG_FLOAT32 || + dstFormat == MESA_FORMAT_XBGR32323232_FLOAT); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || baseInternalFormat == GL_ALPHA || @@ -3549,22 +2688,9 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY || baseInternalFormat == GL_RED || baseInternalFormat == GL_RG); - ASSERT(texelBytes == components * sizeof(GLfloat)); + ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - baseInternalFormat == baseFormat && - srcType == GL_FLOAT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3580,10 +2706,7 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) return GL_FALSE; bytesPerRow = srcWidth * components * sizeof(GLfloat); for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { memcpy(dstRow, srcRow, bytesPerRow); dstRow += dstRowStride; @@ -3604,9 +2727,14 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - const GLint components = _mesa_components_in_format(baseFormat); + GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + GLint components = _mesa_components_in_format(baseFormat); + + /* this forces alpha to 1 in _mesa_make_temp_float_image */ + if (dstFormat == MESA_FORMAT_XBGR16161616_FLOAT) { + baseFormat = GL_RGBA; + components = 4; + } ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 || dstFormat == MESA_FORMAT_RGB_FLOAT16 || @@ -3615,7 +2743,8 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 || dstFormat == MESA_FORMAT_INTENSITY_FLOAT16 || dstFormat == MESA_FORMAT_R_FLOAT16 || - dstFormat == MESA_FORMAT_RG_FLOAT16); + dstFormat == MESA_FORMAT_RG_FLOAT16 || + dstFormat == MESA_FORMAT_XBGR16161616_FLOAT); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || baseInternalFormat == GL_ALPHA || @@ -3624,22 +2753,9 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY || baseInternalFormat == GL_RED || baseInternalFormat == GL_RG); - ASSERT(texelBytes == components * sizeof(GLhalfARB)); + ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - baseInternalFormat == baseFormat && - srcType == GL_HALF_FLOAT_ARB) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3653,10 +2769,7 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLhalfARB *dstTexel = (GLhalfARB *) dstRow; GLint i; @@ -3678,55 +2791,61 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgba_int8(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - const GLint components = _mesa_components_in_format(baseFormat); + GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + GLint components = _mesa_components_in_format(baseFormat); + + /* this forces alpha to 1 in make_temp_uint_image */ + if (dstFormat == MESA_FORMAT_XBGR8888_SINT) { + baseFormat = GL_RGBA; + components = 4; + } - ASSERT(dstFormat == MESA_FORMAT_RGBA_INT8); + ASSERT(dstFormat == MESA_FORMAT_R_INT8 || + dstFormat == MESA_FORMAT_RG_INT8 || + dstFormat == MESA_FORMAT_RGB_INT8 || + dstFormat == MESA_FORMAT_RGBA_INT8 || + dstFormat == MESA_FORMAT_ALPHA_INT8 || + dstFormat == MESA_FORMAT_INTENSITY_INT8 || + dstFormat == MESA_FORMAT_LUMINANCE_INT8 || + dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8 || + dstFormat == MESA_FORMAT_XBGR8888_SINT); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || baseInternalFormat == GL_INTENSITY); - ASSERT(texelBytes == components * sizeof(GLbyte)); + ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, 0x0); - const GLfloat *src = tempImage; + const GLuint *tempImage = make_temp_uint_image(ctx, dims, + baseInternalFormat, + baseFormat, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, + srcAddr, + srcPacking); + const GLuint *src = tempImage; GLint img, row; + GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLbyte *dstTexel = (GLbyte *) dstRow; GLint i; - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLbyte) src[i]; + if (is_unsigned) { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f); + } + } else { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f); + } } dstRow += dstRowStride; src += srcWidth * components; @@ -3743,55 +2862,61 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgba_int16(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - const GLint components = _mesa_components_in_format(baseFormat); + GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + GLint components = _mesa_components_in_format(baseFormat); + + /* this forces alpha to 1 in make_temp_uint_image */ + if (dstFormat == MESA_FORMAT_XBGR16161616_SINT) { + baseFormat = GL_RGBA; + components = 4; + } - ASSERT(dstFormat == MESA_FORMAT_RGBA_INT16); + ASSERT(dstFormat == MESA_FORMAT_R_INT16 || + dstFormat == MESA_FORMAT_RG_INT16 || + dstFormat == MESA_FORMAT_RGB_INT16 || + dstFormat == MESA_FORMAT_RGBA_INT16 || + dstFormat == MESA_FORMAT_ALPHA_INT16 || + dstFormat == MESA_FORMAT_LUMINANCE_INT16 || + dstFormat == MESA_FORMAT_INTENSITY_INT16 || + dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16 || + dstFormat == MESA_FORMAT_XBGR16161616_SINT); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || baseInternalFormat == GL_INTENSITY); - ASSERT(texelBytes == components * sizeof(GLshort)); + ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, 0x0); - const GLfloat *src = tempImage; + const GLuint *tempImage = make_temp_uint_image(ctx, dims, + baseInternalFormat, + baseFormat, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, + srcAddr, + srcPacking); + const GLuint *src = tempImage; GLint img, row; + GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLshort *dstTexel = (GLshort *) dstRow; GLint i; - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLint) src[i]; + if (is_unsigned) { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff); + } + } else { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff); + } } dstRow += dstRowStride; src += srcWidth * components; @@ -3808,55 +2933,61 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgba_int32(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - const GLint components = _mesa_components_in_format(baseFormat); + GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + GLint components = _mesa_components_in_format(baseFormat); + + /* this forces alpha to 1 in make_temp_uint_image */ + if (dstFormat == MESA_FORMAT_XBGR32323232_SINT) { + baseFormat = GL_RGBA; + components = 4; + } - ASSERT(dstFormat == MESA_FORMAT_RGBA_INT32); + ASSERT(dstFormat == MESA_FORMAT_R_INT32 || + dstFormat == MESA_FORMAT_RG_INT32 || + dstFormat == MESA_FORMAT_RGB_INT32 || + dstFormat == MESA_FORMAT_RGBA_INT32 || + dstFormat == MESA_FORMAT_ALPHA_INT32 || + dstFormat == MESA_FORMAT_INTENSITY_INT32 || + dstFormat == MESA_FORMAT_LUMINANCE_INT32 || + dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32 || + dstFormat == MESA_FORMAT_XBGR32323232_SINT); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || baseInternalFormat == GL_INTENSITY); - ASSERT(texelBytes == components * sizeof(GLint)); + ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_INT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, 0x0); - const GLfloat *src = tempImage; + const GLuint *tempImage = make_temp_uint_image(ctx, dims, + baseInternalFormat, + baseFormat, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, + srcAddr, + srcPacking); + const GLuint *src = tempImage; GLint img, row; + GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLint *dstTexel = (GLint *) dstRow; GLint i; - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLint) src[i]; + if (is_unsigned) { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff); + } + } else { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLint) src[i]; + } } dstRow += dstRowStride; src += srcWidth * components; @@ -3873,34 +3004,35 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - const GLint components = _mesa_components_in_format(baseFormat); + GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + GLint components = _mesa_components_in_format(baseFormat); + + /* this forces alpha to 1 in make_temp_uint_image */ + if (dstFormat == MESA_FORMAT_XBGR8888_UINT) { + baseFormat = GL_RGBA; + components = 4; + } - ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT8); + ASSERT(dstFormat == MESA_FORMAT_R_UINT8 || + dstFormat == MESA_FORMAT_RG_UINT8 || + dstFormat == MESA_FORMAT_RGB_UINT8 || + dstFormat == MESA_FORMAT_RGBA_UINT8 || + dstFormat == MESA_FORMAT_ALPHA_UINT8 || + dstFormat == MESA_FORMAT_INTENSITY_UINT8 || + dstFormat == MESA_FORMAT_LUMINANCE_UINT8 || + dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8 || + dstFormat == MESA_FORMAT_XBGR8888_UINT); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || baseInternalFormat == GL_INTENSITY); - ASSERT(texelBytes == components * sizeof(GLubyte)); + ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, @@ -3908,18 +3040,22 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) srcFormat, srcType, srcAddr, srcPacking); const GLuint *src = tempImage; GLint img, row; + GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLubyte *dstTexel = (GLubyte *) dstRow; GLint i; - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLubyte) CLAMP(src[i], 0, 0xff); + if (is_unsigned) { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLubyte) MIN2(src[i], 0xff); + } + } else { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff); + } } dstRow += dstRowStride; src += srcWidth * components; @@ -3936,34 +3072,35 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - const GLint components = _mesa_components_in_format(baseFormat); + GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + GLint components = _mesa_components_in_format(baseFormat); + + /* this forces alpha to 1 in make_temp_uint_image */ + if (dstFormat == MESA_FORMAT_XBGR16161616_UINT) { + baseFormat = GL_RGBA; + components = 4; + } - ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT16); + ASSERT(dstFormat == MESA_FORMAT_R_UINT16 || + dstFormat == MESA_FORMAT_RG_UINT16 || + dstFormat == MESA_FORMAT_RGB_UINT16 || + dstFormat == MESA_FORMAT_RGBA_UINT16 || + dstFormat == MESA_FORMAT_ALPHA_UINT16 || + dstFormat == MESA_FORMAT_INTENSITY_UINT16 || + dstFormat == MESA_FORMAT_LUMINANCE_UINT16 || + dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16 || + dstFormat == MESA_FORMAT_XBGR16161616_UINT); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || baseInternalFormat == GL_INTENSITY); - ASSERT(texelBytes == components * sizeof(GLushort)); + ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, @@ -3971,18 +3108,22 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) srcFormat, srcType, srcAddr, srcPacking); const GLuint *src = tempImage; GLint img, row; + GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLushort *dstTexel = (GLushort *) dstRow; GLint i; - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLushort) CLAMP(src[i], 0, 0xffff); + if (is_unsigned) { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLushort) MIN2(src[i], 0xffff); + } + } else { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff); + } } dstRow += dstRowStride; src += srcWidth * components; @@ -3999,54 +3140,59 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) { - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - const GLint components = _mesa_components_in_format(baseFormat); + GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + GLint components = _mesa_components_in_format(baseFormat); + + /* this forces alpha to 1 in make_temp_uint_image */ + if (dstFormat == MESA_FORMAT_XBGR32323232_UINT) { + baseFormat = GL_RGBA; + components = 4; + } - ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT32); + ASSERT(dstFormat == MESA_FORMAT_R_UINT32 || + dstFormat == MESA_FORMAT_RG_UINT32 || + dstFormat == MESA_FORMAT_RGB_UINT32 || + dstFormat == MESA_FORMAT_RGBA_UINT32 || + dstFormat == MESA_FORMAT_ALPHA_UINT32 || + dstFormat == MESA_FORMAT_INTENSITY_UINT32 || + dstFormat == MESA_FORMAT_LUMINANCE_UINT32 || + dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32 || + dstFormat == MESA_FORMAT_XBGR32323232_UINT); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || baseInternalFormat == GL_INTENSITY); - ASSERT(texelBytes == components * sizeof(GLuint)); + ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_INT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); const GLuint *src = tempImage; + GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); GLint img, row; if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLuint *dstTexel = (GLuint *) dstRow; GLint i; - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = src[i]; - } + if (is_unsigned) { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = src[i]; + } + } else { + for (i = 0; i < srcWidth * components; i++) { + dstTexel[i] = MAX2((GLint) src[i], 0); + } + } dstRow += dstRowStride; src += srcWidth * components; } @@ -4058,9 +3204,6 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) } - - -#if FEATURE_EXT_texture_sRGB static GLboolean _mesa_texstore_srgb8(TEXSTORE_PARAMS) { @@ -4073,9 +3216,8 @@ _mesa_texstore_srgb8(TEXSTORE_PARAMS) newDstFormat = MESA_FORMAT_RGB888; k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat, - newDstFormat, dstAddr, - dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + newDstFormat, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); @@ -4089,14 +3231,24 @@ _mesa_texstore_srgba8(TEXSTORE_PARAMS) gl_format newDstFormat; GLboolean k; - ASSERT(dstFormat == MESA_FORMAT_SRGBA8); + ASSERT(dstFormat == MESA_FORMAT_SRGBA8 || + dstFormat == MESA_FORMAT_XBGR8888_SRGB); /* reuse normal rgba texstore code */ - newDstFormat = MESA_FORMAT_RGBA8888; + if (dstFormat == MESA_FORMAT_SRGBA8) { + newDstFormat = MESA_FORMAT_RGBA8888; + } + else if (dstFormat == MESA_FORMAT_XBGR8888_SRGB) { + newDstFormat = MESA_FORMAT_RGBX8888_REV; + } + else { + ASSERT(0); + return GL_TRUE; + } + k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat, - newDstFormat, dstAddr, - dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + newDstFormat, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); @@ -4116,9 +3268,8 @@ _mesa_texstore_sargb8(TEXSTORE_PARAMS) newDstFormat = MESA_FORMAT_ARGB8888; k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat, - newDstFormat, dstAddr, - dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + newDstFormat, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); @@ -4138,12 +3289,11 @@ _mesa_texstore_sl8(TEXSTORE_PARAMS) /* _mesa_textore_a8 handles luminance8 too */ k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat, - newDstFormat, dstAddr, - dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); + newDstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, + srcAddr, srcPacking); return k; } @@ -4160,26 +3310,14 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS) newDstFormat = MESA_FORMAT_AL88; k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat, - newDstFormat, dstAddr, - dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, + newDstFormat, + dstRowStride, dstSlices, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); return k; } -#else - -/* these are used only in texstore_funcs[] below */ -#define _mesa_texstore_srgb8 NULL -#define _mesa_texstore_srgba8 NULL -#define _mesa_texstore_sargb8 NULL -#define _mesa_texstore_sl8 NULL -#define _mesa_texstore_sla8 NULL - -#endif /* FEATURE_EXT_texture_sRGB */ - static GLboolean _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS) { @@ -4188,19 +3326,7 @@ _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS) ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT); ASSERT(baseInternalFormat == GL_RGB); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGB && - srcType == GL_UNSIGNED_INT_5_9_9_9_REV) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -4214,10 +3340,7 @@ _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * 4 - + dstYoffset * dstRowStride - + dstXoffset * 4; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLuint *dstUI = (GLuint*)dstRow; for (col = 0; col < srcWidth; col++) { @@ -4241,19 +3364,7 @@ _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS) ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT); ASSERT(baseInternalFormat == GL_RGB); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGB && - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -4267,10 +3378,7 @@ _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * 4 - + dstYoffset * dstRowStride - + dstXoffset * 4; + GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { GLuint *dstUI = (GLuint*)dstRow; for (col = 0; col < srcWidth; col++) { @@ -4297,20 +3405,8 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) ASSERT(srcFormat != GL_DEPTH_STENCIL || srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - if (srcFormat == GL_DEPTH_STENCIL && - ctx->Pixel.DepthScale == 1.0f && - ctx->Pixel.DepthBias == 0.0f && - !srcPacking->SwapBytes) { - /* simple path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (srcFormat == GL_DEPTH_COMPONENT || - srcFormat == GL_STENCIL_INDEX) { + if (srcFormat == GL_DEPTH_COMPONENT || + srcFormat == GL_STENCIL_INDEX) { GLint img, row; const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) @@ -4318,10 +3414,7 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) /* In case we only upload depth we need to preserve the stencil */ for (img = 0; img < srcDepth; img++) { - uint64_t *dstRow = (uint64_t *) dstAddr - + dstImageOffsets[dstZoffset + img] - + dstYoffset * dstRowStride / sizeof(uint64_t) - + dstXoffset; + uint64_t *dstRow = (uint64_t *) dstSlices[img]; const uint64_t *src = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, @@ -4336,7 +3429,7 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) _mesa_unpack_depth_span(ctx, srcWidth, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ dstRow, /* dst addr */ - 1.0f, srcType, src, srcPacking); + ~0U, srcType, src, srcPacking); if (srcFormat != GL_DEPTH_COMPONENT) _mesa_unpack_stencil_span(ctx, srcWidth, @@ -4353,145 +3446,117 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) return GL_TRUE; } +static GLboolean +_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS) +{ + const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); -/** - * Table mapping MESA_FORMAT_* to _mesa_texstore_*() - * XXX this is somewhat temporary. - */ -static const struct { - gl_format Name; - StoreTexImageFunc Store; + ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); + + { + /* general path */ + const GLuint *tempImage = make_temp_uint_image(ctx, dims, + baseInternalFormat, + baseFormat, + srcWidth, srcHeight, + srcDepth, srcFormat, + srcType, srcAddr, + srcPacking); + const GLuint *src = tempImage; + GLint img, row, col; + GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); + if (!tempImage) + return GL_FALSE; + for (img = 0; img < srcDepth; img++) { + GLubyte *dstRow = dstSlices[img]; + + for (row = 0; row < srcHeight; row++) { + GLuint *dstUI = (GLuint *) dstRow; + if (is_unsigned) { + for (col = 0; col < srcWidth; col++) { + GLushort a,r,g,b; + r = MIN2(src[RCOMP], 0x3ff); + g = MIN2(src[GCOMP], 0x3ff); + b = MIN2(src[BCOMP], 0x3ff); + a = MIN2(src[ACOMP], 0x003); + dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); + src += 4; + } + } else { + for (col = 0; col < srcWidth; col++) { + GLushort a,r,g,b; + r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); + g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); + b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); + a = CLAMP((GLint) src[ACOMP], 0, 0x003); + dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); + src += 4; + } + } + dstRow += dstRowStride; + } + } + free((void *) tempImage); + } + return GL_TRUE; } -texstore_funcs[MESA_FORMAT_COUNT] = + +static GLboolean +_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) { - { MESA_FORMAT_NONE, NULL }, - { MESA_FORMAT_RGBA8888, _mesa_texstore_rgba8888 }, - { MESA_FORMAT_RGBA8888_REV, _mesa_texstore_rgba8888 }, - { MESA_FORMAT_ARGB8888, _mesa_texstore_argb8888 }, - { MESA_FORMAT_ARGB8888_REV, _mesa_texstore_argb8888 }, - { MESA_FORMAT_XRGB8888, _mesa_texstore_argb8888 }, - { MESA_FORMAT_XRGB8888_REV, _mesa_texstore_argb8888 }, - { MESA_FORMAT_RGB888, _mesa_texstore_rgb888 }, - { MESA_FORMAT_BGR888, _mesa_texstore_bgr888 }, - { MESA_FORMAT_RGB565, _mesa_texstore_rgb565 }, - { MESA_FORMAT_RGB565_REV, _mesa_texstore_rgb565 }, - { MESA_FORMAT_ARGB4444, _mesa_texstore_argb4444 }, - { MESA_FORMAT_ARGB4444_REV, _mesa_texstore_argb4444 }, - { MESA_FORMAT_RGBA5551, _mesa_texstore_rgba5551 }, - { MESA_FORMAT_ARGB1555, _mesa_texstore_argb1555 }, - { MESA_FORMAT_ARGB1555_REV, _mesa_texstore_argb1555 }, - { MESA_FORMAT_AL44, _mesa_texstore_unorm44 }, - { MESA_FORMAT_AL88, _mesa_texstore_unorm88 }, - { MESA_FORMAT_AL88_REV, _mesa_texstore_unorm88 }, - { MESA_FORMAT_AL1616, _mesa_texstore_unorm1616 }, - { MESA_FORMAT_AL1616_REV, _mesa_texstore_unorm1616 }, - { MESA_FORMAT_RGB332, _mesa_texstore_rgb332 }, - { MESA_FORMAT_A8, _mesa_texstore_unorm8 }, - { MESA_FORMAT_A16, _mesa_texstore_unorm16 }, - { MESA_FORMAT_L8, _mesa_texstore_unorm8 }, - { MESA_FORMAT_L16, _mesa_texstore_unorm16 }, - { MESA_FORMAT_I8, _mesa_texstore_unorm8 }, - { MESA_FORMAT_I16, _mesa_texstore_unorm16 }, - { MESA_FORMAT_CI8, _mesa_texstore_ci8 }, - { MESA_FORMAT_YCBCR, _mesa_texstore_ycbcr }, - { MESA_FORMAT_YCBCR_REV, _mesa_texstore_ycbcr }, - { MESA_FORMAT_R8, _mesa_texstore_unorm8 }, - { MESA_FORMAT_RG88, _mesa_texstore_unorm88 }, - { MESA_FORMAT_RG88_REV, _mesa_texstore_unorm88 }, - { MESA_FORMAT_R16, _mesa_texstore_unorm16 }, - { MESA_FORMAT_RG1616, _mesa_texstore_unorm1616 }, - { MESA_FORMAT_RG1616_REV, _mesa_texstore_unorm1616 }, - { MESA_FORMAT_ARGB2101010, _mesa_texstore_argb2101010 }, - { MESA_FORMAT_Z24_S8, _mesa_texstore_z24_s8 }, - { MESA_FORMAT_S8_Z24, _mesa_texstore_s8_z24 }, - { MESA_FORMAT_Z16, _mesa_texstore_z16 }, - { MESA_FORMAT_X8_Z24, _mesa_texstore_x8_z24 }, - { MESA_FORMAT_Z24_X8, _mesa_texstore_z24_x8 }, - { MESA_FORMAT_Z32, _mesa_texstore_z32 }, - { MESA_FORMAT_S8, _mesa_texstore_s8 }, - { MESA_FORMAT_SRGB8, _mesa_texstore_srgb8 }, - { MESA_FORMAT_SRGBA8, _mesa_texstore_srgba8 }, - { MESA_FORMAT_SARGB8, _mesa_texstore_sargb8 }, - { MESA_FORMAT_SL8, _mesa_texstore_sl8 }, - { MESA_FORMAT_SLA8, _mesa_texstore_sla8 }, - { MESA_FORMAT_SRGB_DXT1, _mesa_texstore_rgb_dxt1 }, - { MESA_FORMAT_SRGBA_DXT1, _mesa_texstore_rgba_dxt1 }, - { MESA_FORMAT_SRGBA_DXT3, _mesa_texstore_rgba_dxt3 }, - { MESA_FORMAT_SRGBA_DXT5, _mesa_texstore_rgba_dxt5 }, - { MESA_FORMAT_RGB_FXT1, _mesa_texstore_rgb_fxt1 }, - { MESA_FORMAT_RGBA_FXT1, _mesa_texstore_rgba_fxt1 }, - { MESA_FORMAT_RGB_DXT1, _mesa_texstore_rgb_dxt1 }, - { MESA_FORMAT_RGBA_DXT1, _mesa_texstore_rgba_dxt1 }, - { MESA_FORMAT_RGBA_DXT3, _mesa_texstore_rgba_dxt3 }, - { MESA_FORMAT_RGBA_DXT5, _mesa_texstore_rgba_dxt5 }, - { MESA_FORMAT_RGBA_FLOAT32, _mesa_texstore_rgba_float32 }, - { MESA_FORMAT_RGBA_FLOAT16, _mesa_texstore_rgba_float16 }, - { MESA_FORMAT_RGB_FLOAT32, _mesa_texstore_rgba_float32 }, - { MESA_FORMAT_RGB_FLOAT16, _mesa_texstore_rgba_float16 }, - { MESA_FORMAT_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 }, - { MESA_FORMAT_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 }, - { MESA_FORMAT_LUMINANCE_FLOAT32, _mesa_texstore_rgba_float32 }, - { MESA_FORMAT_LUMINANCE_FLOAT16, _mesa_texstore_rgba_float16 }, - { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 }, - { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 }, - { MESA_FORMAT_INTENSITY_FLOAT32, _mesa_texstore_rgba_float32 }, - { MESA_FORMAT_INTENSITY_FLOAT16, _mesa_texstore_rgba_float16 }, - { MESA_FORMAT_R_FLOAT32, _mesa_texstore_rgba_float32 }, - { MESA_FORMAT_R_FLOAT16, _mesa_texstore_rgba_float16 }, - { MESA_FORMAT_RG_FLOAT32, _mesa_texstore_rgba_float32 }, - { MESA_FORMAT_RG_FLOAT16, _mesa_texstore_rgba_float16 }, - - { MESA_FORMAT_RGBA_INT8, _mesa_texstore_rgba_int8 }, - { MESA_FORMAT_RGBA_INT16, _mesa_texstore_rgba_int16 }, - { MESA_FORMAT_RGBA_INT32, _mesa_texstore_rgba_int32 }, - { MESA_FORMAT_RGBA_UINT8, _mesa_texstore_rgba_uint8 }, - { MESA_FORMAT_RGBA_UINT16, _mesa_texstore_rgba_uint16 }, - { MESA_FORMAT_RGBA_UINT32, _mesa_texstore_rgba_uint32 }, - - { MESA_FORMAT_DUDV8, _mesa_texstore_dudv8 }, - - { MESA_FORMAT_SIGNED_R8, _mesa_texstore_snorm8 }, - { MESA_FORMAT_SIGNED_RG88_REV, _mesa_texstore_snorm88 }, - { MESA_FORMAT_SIGNED_RGBX8888, _mesa_texstore_signed_rgbx8888 }, - - { MESA_FORMAT_SIGNED_RGBA8888, _mesa_texstore_signed_rgba8888 }, - { MESA_FORMAT_SIGNED_RGBA8888_REV, _mesa_texstore_signed_rgba8888 }, - - { MESA_FORMAT_SIGNED_R16, _mesa_texstore_snorm16 }, - { MESA_FORMAT_SIGNED_GR1616, _mesa_texstore_snorm1616 }, - { MESA_FORMAT_SIGNED_RGB_16, _mesa_texstore_signed_rgba_16 }, - { MESA_FORMAT_SIGNED_RGBA_16, _mesa_texstore_signed_rgba_16 }, - { MESA_FORMAT_RGBA_16, _mesa_texstore_rgba_16 }, - - { MESA_FORMAT_RED_RGTC1, _mesa_texstore_red_rgtc1 }, - { MESA_FORMAT_SIGNED_RED_RGTC1, _mesa_texstore_signed_red_rgtc1 }, - { MESA_FORMAT_RG_RGTC2, _mesa_texstore_rg_rgtc2 }, - { MESA_FORMAT_SIGNED_RG_RGTC2, _mesa_texstore_signed_rg_rgtc2 }, - - /* Re-use the R/RG texstore functions. - * The code is generic enough to handle LATC too. */ - { MESA_FORMAT_L_LATC1, _mesa_texstore_red_rgtc1 }, - { MESA_FORMAT_SIGNED_L_LATC1, _mesa_texstore_signed_red_rgtc1 }, - { MESA_FORMAT_LA_LATC2, _mesa_texstore_rg_rgtc2 }, - { MESA_FORMAT_SIGNED_LA_LATC2, _mesa_texstore_signed_rg_rgtc2 }, - - { MESA_FORMAT_SIGNED_A8, _mesa_texstore_snorm8 }, - { MESA_FORMAT_SIGNED_L8, _mesa_texstore_snorm8 }, - { MESA_FORMAT_SIGNED_AL88, _mesa_texstore_snorm88 }, - { MESA_FORMAT_SIGNED_I8, _mesa_texstore_snorm8 }, - - { MESA_FORMAT_SIGNED_A16, _mesa_texstore_snorm16 }, - { MESA_FORMAT_SIGNED_L16, _mesa_texstore_snorm16 }, - { MESA_FORMAT_SIGNED_AL1616, _mesa_texstore_snorm1616 }, - { MESA_FORMAT_SIGNED_I16, _mesa_texstore_snorm16 }, - - { MESA_FORMAT_RGB9_E5_FLOAT, _mesa_texstore_rgb9_e5 }, - { MESA_FORMAT_R11_G11_B10_FLOAT, _mesa_texstore_r11_g11_b10f }, - - { MESA_FORMAT_Z32_FLOAT, _mesa_texstore_z32 }, - { MESA_FORMAT_Z32_FLOAT_X24S8, _mesa_texstore_z32f_x24s8 }, -}; + const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); + + { + /* general path */ + const GLuint *tempImage = make_temp_uint_image(ctx, dims, + baseInternalFormat, + baseFormat, + srcWidth, srcHeight, + srcDepth, srcFormat, + srcType, srcAddr, + srcPacking); + const GLuint *src = tempImage; + GLint img, row, col; + GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); + if (!tempImage) + return GL_FALSE; + for (img = 0; img < srcDepth; img++) { + GLubyte *dstRow = dstSlices[img]; + + for (row = 0; row < srcHeight; row++) { + GLuint *dstUI = (GLuint *) dstRow; + if (is_unsigned) { + for (col = 0; col < srcWidth; col++) { + GLushort a,r,g,b; + r = MIN2(src[RCOMP], 0x3ff); + g = MIN2(src[GCOMP], 0x3ff); + b = MIN2(src[BCOMP], 0x3ff); + a = MIN2(src[ACOMP], 0x003); + dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); + src += 4; + } + } else { + for (col = 0; col < srcWidth; col++) { + GLushort a,r,g,b; + r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); + g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); + b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); + a = CLAMP((GLint) src[ACOMP], 0, 0x003); + dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); + src += 4; + } + } + dstRow += dstRowStride; + } + } + free((void *) tempImage); + } + return GL_TRUE; +} static GLboolean _mesa_texstore_null(TEXSTORE_PARAMS) @@ -4499,9 +3564,7 @@ _mesa_texstore_null(TEXSTORE_PARAMS) (void) ctx; (void) dims; (void) baseInternalFormat; (void) dstFormat; - (void) dstAddr; - (void) dstXoffset; (void) dstYoffset; (void) dstZoffset; - (void) dstRowStride; (void) dstImageOffsets; + (void) dstRowStride; (void) dstSlices, (void) srcWidth; (void) srcHeight; (void) srcDepth; (void) srcFormat; (void) srcType; (void) srcAddr; @@ -4519,535 +3582,611 @@ _mesa_texstore_null(TEXSTORE_PARAMS) static StoreTexImageFunc _mesa_get_texstore_func(gl_format format) { -#ifdef DEBUG - GLuint i; - for (i = 0; i < MESA_FORMAT_COUNT; i++) { - ASSERT(texstore_funcs[i].Name == i); + static StoreTexImageFunc table[MESA_FORMAT_COUNT]; + static GLboolean initialized = GL_FALSE; + + if (!initialized) { + table[MESA_FORMAT_NONE] = _mesa_texstore_null; + + table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888; + table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888; + table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888; + table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888; + table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888; + table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888; + table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888; + table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888; + table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888; + table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888; + table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565; + table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565; + table[MESA_FORMAT_ARGB4444] = store_ubyte_texture; + table[MESA_FORMAT_ARGB4444_REV] = store_ubyte_texture; + table[MESA_FORMAT_RGBA5551] = store_ubyte_texture; + table[MESA_FORMAT_ARGB1555] = store_ubyte_texture; + table[MESA_FORMAT_ARGB1555_REV] = store_ubyte_texture; + table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44; + table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88; + table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88; + table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616; + table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616; + table[MESA_FORMAT_RGB332] = store_ubyte_texture; + table[MESA_FORMAT_A8] = _mesa_texstore_unorm8; + table[MESA_FORMAT_A16] = _mesa_texstore_unorm16; + table[MESA_FORMAT_L8] = _mesa_texstore_unorm8; + table[MESA_FORMAT_L16] = _mesa_texstore_unorm16; + table[MESA_FORMAT_I8] = _mesa_texstore_unorm8; + table[MESA_FORMAT_I16] = _mesa_texstore_unorm16; + table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr; + table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr; + table[MESA_FORMAT_R8] = _mesa_texstore_unorm8; + table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88; + table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88; + table[MESA_FORMAT_R16] = _mesa_texstore_unorm16; + table[MESA_FORMAT_GR1616] = _mesa_texstore_unorm1616; + table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616; + table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010; + table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8; + table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24; + table[MESA_FORMAT_Z16] = _mesa_texstore_z16; + table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24; + table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8; + table[MESA_FORMAT_Z32] = _mesa_texstore_z32; + table[MESA_FORMAT_S8] = _mesa_texstore_s8; + table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8; + table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8; + table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8; + table[MESA_FORMAT_SL8] = _mesa_texstore_sl8; + table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8; + table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1; + table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1; + table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3; + table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5; + table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1; + table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1; + table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1; + table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1; + table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3; + table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5; + table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32; + table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16; + table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32; + table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16; + table[MESA_FORMAT_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32; + table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16; + table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32; + table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16; + table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32; + table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16; + table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32; + table[MESA_FORMAT_INTENSITY_FLOAT16] = _mesa_texstore_rgba_float16; + table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32; + table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16; + table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32; + table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16; + table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8; + table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8; + table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88; + table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888; + table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888; + table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888; + table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16; + table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616; + table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16; + table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16; + table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16; + table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1; + table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1; + table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2; + table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2; + table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1; + table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1; + table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2; + table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2; + table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8; + table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8; + table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8; + table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac; + table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac; + table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac; + table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac; + table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac; + table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac; + table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] = + _mesa_texstore_etc2_rgb8_punchthrough_alpha1; + table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] = + _mesa_texstore_etc2_srgb8_punchthrough_alpha1; + table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8; + table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8; + table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88; + table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8; + table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16; + table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16; + table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616; + table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16; + table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5; + table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f; + table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32; + table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8; + + table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8; + table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16; + table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32; + table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8; + table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16; + table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32; + + table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8; + table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16; + table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32; + table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8; + table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16; + table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32; + + table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8; + table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16; + table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32; + table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8; + table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16; + table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32; + + table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8; + table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16; + table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32; + table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8; + table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16; + table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32; + + table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8; + table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8; + table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8; + table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8; + table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16; + table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16; + table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16; + table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16; + table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32; + table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32; + table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32; + table[MESA_FORMAT_RGBA_INT32] = _mesa_texstore_rgba_int32; + + table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8; + table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8; + table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8; + table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8; + table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16; + table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16; + table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16; + table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16; + table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32; + table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32; + table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32; + table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32; + + table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint; + table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint; + + table[MESA_FORMAT_XRGB4444_UNORM] = store_ubyte_texture; + table[MESA_FORMAT_XRGB1555_UNORM] = store_ubyte_texture; + table[MESA_FORMAT_XBGR8888_SNORM] = _mesa_texstore_signed_rgbx8888; + table[MESA_FORMAT_XBGR8888_SRGB] = _mesa_texstore_srgba8; + table[MESA_FORMAT_XBGR8888_UINT] = _mesa_texstore_rgba_uint8; + table[MESA_FORMAT_XBGR8888_SINT] = _mesa_texstore_rgba_int8; + table[MESA_FORMAT_XRGB2101010_UNORM] = _mesa_texstore_argb2101010; + table[MESA_FORMAT_XBGR16161616_UNORM] = _mesa_texstore_rgba_16; + table[MESA_FORMAT_XBGR16161616_SNORM] = _mesa_texstore_signed_rgba_16; + table[MESA_FORMAT_XBGR16161616_FLOAT] = _mesa_texstore_rgba_float16; + table[MESA_FORMAT_XBGR16161616_UINT] = _mesa_texstore_rgba_uint16; + table[MESA_FORMAT_XBGR16161616_SINT] = _mesa_texstore_rgba_int16; + table[MESA_FORMAT_XBGR32323232_FLOAT] = _mesa_texstore_rgba_float32; + table[MESA_FORMAT_XBGR32323232_UINT] = _mesa_texstore_rgba_uint32; + table[MESA_FORMAT_XBGR32323232_SINT] = _mesa_texstore_rgba_int32; + + initialized = GL_TRUE; } -#endif - ASSERT(texstore_funcs[format].Name == format); - if (texstore_funcs[format].Store) - return texstore_funcs[format].Store; - else - return _mesa_texstore_null; + ASSERT(table[format]); + return table[format]; } -/** - * Store user data into texture memory. - * Called via glTex[Sub]Image1/2/3D() - */ GLboolean -_mesa_texstore(TEXSTORE_PARAMS) +_mesa_texstore_needs_transfer_ops(struct gl_context *ctx, + GLenum baseInternalFormat, + gl_format dstFormat) { - StoreTexImageFunc storeImage; - GLboolean success; + GLenum dstType; - storeImage = _mesa_get_texstore_func(dstFormat); + /* There are different rules depending on the base format. */ + switch (baseInternalFormat) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + return ctx->Pixel.DepthScale != 1.0f || + ctx->Pixel.DepthBias != 0.0f; - success = storeImage(ctx, dims, baseInternalFormat, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, dstImageOffsets, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - return success; -} - - -/** Return texture size in bytes */ -static GLuint -texture_size(const struct gl_texture_image *texImage) -{ - GLuint sz = _mesa_format_image_size(texImage->TexFormat, texImage->Width, - texImage->Height, texImage->Depth); - return sz; -} + case GL_STENCIL_INDEX: + return GL_FALSE; + default: + /* Color formats. + * Pixel transfer ops (scale, bias, table lookup) do not apply + * to integer formats. + */ + dstType = _mesa_get_format_datatype(dstFormat); -/** Return row stride in bytes */ -static GLuint -texture_row_stride(const struct gl_texture_image *texImage) -{ - GLuint stride = _mesa_format_row_stride(texImage->TexFormat, - texImage->Width); - return stride; + return dstType != GL_INT && dstType != GL_UNSIGNED_INT && + ctx->_ImageTransferState; + } } - -/** - * This is the software fallback for Driver.TexImage1D(). - * \sa _mesa_store_teximage2d() - */ -void -_mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +GLboolean +_mesa_texstore_can_use_memcpy(struct gl_context *ctx, + GLenum baseInternalFormat, gl_format dstFormat, + GLenum srcFormat, GLenum srcType, + const struct gl_pixelstore_attrib *srcPacking) { - GLuint sizeInBytes; - (void) border; - - /* allocate memory */ - sizeInBytes = texture_size(texImage); - texImage->Data = _mesa_alloc_texmemory(sizeInBytes); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - return; + if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) { + return GL_FALSE; } - pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, - pixels, packing, "glTexImage1D"); - if (!pixels) { - /* Note: we check for a NULL image pointer here, _after_ we allocated - * memory for the texture. That's what the GL spec calls for. - */ - return; + /* The base internal format and the base Mesa format must match. */ + if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) { + return GL_FALSE; } - else { - const GLint dstRowStride = 0; - GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, 1, 1, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - } + + /* The Mesa format must match the input format and type. */ + if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, + srcPacking->SwapBytes)) { + return GL_FALSE; } - _mesa_unmap_teximage_pbo(ctx, packing); + return GL_TRUE; } - -/** - * This is the software fallback for Driver.TexImage2D(). - * - * This function is oriented toward storing images in main memory, rather - * than VRAM. Device driver's can easily plug in their own replacement. - */ -void -_mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +static GLboolean +_mesa_texstore_memcpy(TEXSTORE_PARAMS) { - GLuint sizeInBytes; - (void) border; - - /* allocate memory */ - sizeInBytes = texture_size(texImage); - texImage->Data = _mesa_alloc_texmemory(sizeInBytes); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } - - pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type, - pixels, packing, "glTexImage2D"); - if (!pixels) { - /* Note: we check for a NULL image pointer here, _after_ we allocated - * memory for the texture. That's what the GL spec calls for. - */ - return; - } - else { - GLint dstRowStride = texture_row_stride(texImage); - GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, 1, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - } + if (!_mesa_texstore_can_use_memcpy(ctx, baseInternalFormat, dstFormat, + srcFormat, srcType, srcPacking)) { + return GL_FALSE; } - _mesa_unmap_teximage_pbo(ctx, packing); + memcpy_texture(ctx, dims, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, srcFormat, srcType, + srcAddr, srcPacking); + return GL_TRUE; } - /** - * This is the software fallback for Driver.TexImage3D(). - * \sa _mesa_store_teximage2d() + * Store user data into texture memory. + * Called via glTex[Sub]Image1/2/3D() */ -void -_mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +GLboolean +_mesa_texstore(TEXSTORE_PARAMS) { - GLuint sizeInBytes; - (void) border; - - /* allocate memory */ - sizeInBytes = texture_size(texImage); - texImage->Data = _mesa_alloc_texmemory(sizeInBytes); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - return; - } + StoreTexImageFunc storeImage; + GLboolean success; - pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, - type, pixels, packing, "glTexImage3D"); - if (!pixels) { - /* Note: we check for a NULL image pointer here, _after_ we allocated - * memory for the texture. That's what the GL spec calls for. - */ - return; - } - else { - GLint dstRowStride = texture_row_stride(texImage); - GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - } + if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking)) { + return GL_TRUE; } - _mesa_unmap_teximage_pbo(ctx, packing); -} - + storeImage = _mesa_get_texstore_func(dstFormat); + success = storeImage(ctx, dims, baseInternalFormat, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + return success; +} -/* - * This is the software fallback for Driver.TexSubImage1D() - * and Driver.CopyTexSubImage1D(). +/** + * Normally, we'll only _write_ texel data to a texture when we map it. + * But if the user is providing depth or stencil values and the texture + * image is a combined depth/stencil format, we'll actually read from + * the texture buffer too (in order to insert the depth or stencil values. + * \param userFormat the user-provided image format + * \param texFormat the destination texture format */ -void -_mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level, - GLint xoffset, GLint width, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +static GLbitfield +get_read_write_mode(GLenum userFormat, gl_format texFormat) { - /* get pointer to src pixels (may be in a pbo which we'll map here) */ - pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, - pixels, packing, "glTexSubImage1D"); - if (!pixels) - return; - - { - const GLint dstRowStride = 0; - GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - xoffset, 0, 0, /* offsets */ - dstRowStride, - texImage->ImageOffsets, - width, 1, 1, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); - } - } - - _mesa_unmap_teximage_pbo(ctx, packing); + if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT) + && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL) + return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; + else + return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT; } - /** - * This is the software fallback for Driver.TexSubImage2D() - * and Driver.CopyTexSubImage2D(). + * Helper function for storing 1D, 2D, 3D whole and subimages into texture + * memory. + * The source of the image data may be user memory or a PBO. In the later + * case, we'll map the PBO, copy from it, then unmap it. */ -void -_mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint width, GLint height, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +static void +store_texsubimage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + const char *caller) + { + const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat); + const GLenum target = texImage->TexObject->Target; + GLboolean success = GL_FALSE; + GLuint dims, slice, numSlices = 1, sliceOffset = 0; + GLint srcImageStride = 0; + const GLubyte *src; + + assert(xoffset + width <= texImage->Width); + assert(yoffset + height <= texImage->Height); + assert(zoffset + depth <= texImage->Depth); + + switch (target) { + case GL_TEXTURE_1D: + dims = 1; + break; + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_3D: + dims = 3; + break; + default: + dims = 2; + } + /* get pointer to src pixels (may be in a pbo which we'll map here) */ - pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type, - pixels, packing, "glTexSubImage2D"); - if (!pixels) + src = (const GLubyte *) + _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, + format, type, pixels, packing, caller); + if (!src) return; - { - GLint dstRowStride = texture_row_stride(texImage); - GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - xoffset, yoffset, 0, - dstRowStride, - texImage->ImageOffsets, - width, height, 1, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); + /* compute slice info (and do some sanity checks) */ + switch (target) { + case GL_TEXTURE_2D: + case GL_TEXTURE_RECTANGLE: + case GL_TEXTURE_CUBE_MAP: + /* one image slice, nothing special needs to be done */ + break; + case GL_TEXTURE_1D: + assert(height == 1); + assert(depth == 1); + assert(yoffset == 0); + assert(zoffset == 0); + break; + case GL_TEXTURE_1D_ARRAY: + assert(depth == 1); + assert(zoffset == 0); + numSlices = height; + sliceOffset = yoffset; + height = 1; + yoffset = 0; + srcImageStride = _mesa_image_row_stride(packing, width, format, type); + break; + case GL_TEXTURE_2D_ARRAY: + numSlices = depth; + sliceOffset = zoffset; + depth = 1; + zoffset = 0; + srcImageStride = _mesa_image_image_stride(packing, width, height, + format, type); + break; + case GL_TEXTURE_3D: + /* we'll store 3D images as a series of slices */ + numSlices = depth; + sliceOffset = zoffset; + srcImageStride = _mesa_image_image_stride(packing, width, height, + format, type); + break; + case GL_TEXTURE_CUBE_MAP_ARRAY: + numSlices = depth; + sliceOffset = zoffset; + srcImageStride = _mesa_image_image_stride(packing, width, height, + format, type); + break; + default: + _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target); + return; + } + + assert(numSlices == 1 || srcImageStride != 0); + + for (slice = 0; slice < numSlices; slice++) { + GLubyte *dstMap; + GLint dstRowStride; + + ctx->Driver.MapTextureImage(ctx, texImage, + slice + sliceOffset, + xoffset, yoffset, width, height, + mapMode, &dstMap, &dstRowStride); + if (dstMap) { + /* Note: we're only storing a 2D (or 1D) slice at a time but we need + * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is + * used for 3D images. + */ + success = _mesa_texstore(ctx, dims, texImage->_BaseFormat, + texImage->TexFormat, + dstRowStride, + &dstMap, + width, height, 1, /* w, h, d */ + format, type, src, packing); + + ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset); } + + src += srcImageStride; + + if (!success) + break; } + if (!success) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); + _mesa_unmap_teximage_pbo(ctx, packing); } -/* - * This is the software fallback for Driver.TexSubImage3D(). - * and Driver.CopyTexSubImage3D(). + +/** + * Fallback code for ctx->Driver.TexImage(). + * Basically, allocate storage for the texture image, then copy the + * user's image into it. */ void -_mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint width, GLint height, GLint depth, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +_mesa_store_teximage(struct gl_context *ctx, + GLuint dims, + struct gl_texture_image *texImage, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing) { - /* get pointer to src pixels (may be in a pbo which we'll map here) */ - pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, - type, pixels, packing, - "glTexSubImage3D"); - if (!pixels) + assert(dims == 1 || dims == 2 || dims == 3); + + if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) return; - { - GLint dstRowStride = texture_row_stride(texImage); - GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - xoffset, yoffset, zoffset, - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D"); - } + /* allocate storage for texture data */ + if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); + return; } - _mesa_unmap_teximage_pbo(ctx, packing); + store_texsubimage(ctx, texImage, + 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth, + format, type, pixels, packing, "glTexImage"); } /* - * Fallback for Driver.CompressedTexImage1D() + * Fallback for Driver.TexSubImage(). */ void -_mesa_store_compressed_teximage1d(struct gl_context *ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +_mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing) { - /* this space intentionally left blank */ - (void) ctx; - (void) target; (void) level; - (void) internalFormat; - (void) width; (void) border; - (void) imageSize; (void) data; - (void) texObj; - (void) texImage; + store_texsubimage(ctx, texImage, + xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels, packing, "glTexSubImage"); } - /** - * Fallback for Driver.CompressedTexImage2D() + * Fallback for Driver.CompressedTexImage() */ void -_mesa_store_compressed_teximage2d(struct gl_context *ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +_mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *texImage, + GLsizei imageSize, const GLvoid *data) { - (void) width; (void) height; (void) border; + /* only 2D and 3D compressed images are supported at this time */ + if (dims == 1) { + _mesa_problem(ctx, "Unexpected glCompressedTexImage1D call"); + return; + } - /* This is pretty simple, basically just do a memcpy without worrying - * about the usual image unpacking or image transfer operations. + /* This is pretty simple, because unlike the general texstore path we don't + * have to worry about the usual image unpacking or image transfer + * operations. */ - ASSERT(texObj); ASSERT(texImage); ASSERT(texImage->Width > 0); ASSERT(texImage->Height > 0); - ASSERT(texImage->Depth == 1); - ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */ + ASSERT(texImage->Depth > 0); - /* allocate storage */ - texImage->Data = _mesa_alloc_texmemory(imageSize); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); + /* allocate storage for texture data */ + if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims); return; } - data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, - &ctx->Unpack, - "glCompressedTexImage2D"); - if (!data) - return; - - /* copy the data */ - memcpy(texImage->Data, data, imageSize); - - _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); + _mesa_store_compressed_texsubimage(ctx, dims, texImage, + 0, 0, 0, + texImage->Width, texImage->Height, texImage->Depth, + texImage->TexFormat, + imageSize, data); } - -/* - * Fallback for Driver.CompressedTexImage3D() - */ -void -_mesa_store_compressed_teximage3d(struct gl_context *ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - /* this space intentionally left blank */ - (void) ctx; - (void) target; (void) level; - (void) internalFormat; - (void) width; (void) height; (void) depth; - (void) border; - (void) imageSize; (void) data; - (void) texObj; - (void) texImage; -} - - - /** - * Fallback for Driver.CompressedTexSubImage1D() + * Fallback for Driver.CompressedTexSubImage() */ void -_mesa_store_compressed_texsubimage1d(struct gl_context *ctx, GLenum target, - GLint level, - GLint xoffset, GLsizei width, - GLenum format, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +_mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, + GLsizei imageSize, const GLvoid *data) { - /* there are no compressed 1D texture formats yet */ - (void) ctx; - (void) target; (void) level; - (void) xoffset; (void) width; - (void) format; - (void) imageSize; (void) data; - (void) texObj; - (void) texImage; -} - - -/** - * Fallback for Driver.CompressedTexSubImage2D() - */ -void -_mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target, - GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - GLint bytesPerRow, destRowStride, srcRowStride; + GLint bytesPerRow, dstRowStride, srcRowStride; GLint i, rows; - GLubyte *dest; + GLubyte *dstMap; const GLubyte *src; const gl_format texFormat = texImage->TexFormat; - const GLint destWidth = texImage->Width; GLuint bw, bh; + GLuint slice; - _mesa_get_format_block_size(texFormat, &bw, &bh); - - (void) level; - (void) format; + if (dims == 1) { + _mesa_problem(ctx, "Unexpected 1D compressed texsubimage call"); + return; + } - /* these should have been caught sooner */ - ASSERT((width % bw) == 0 || width == 2 || width == 1); - ASSERT((height % bh) == 0 || height == 2 || height == 1); - ASSERT((xoffset % bw) == 0); - ASSERT((yoffset % bh) == 0); + _mesa_get_format_block_size(texFormat, &bw, &bh); /* get pointer to src pixels (may be in a pbo which we'll map here) */ - data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, + data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data, &ctx->Unpack, - "glCompressedTexSubImage2D"); + "glCompressedTexSubImage"); if (!data) return; srcRowStride = _mesa_format_row_stride(texFormat, width); src = (const GLubyte *) data; - destRowStride = _mesa_format_row_stride(texFormat, destWidth); - dest = _mesa_compressed_image_address(xoffset, yoffset, 0, - texFormat, destWidth, - (GLubyte *) texImage->Data); - - bytesPerRow = srcRowStride; /* bytes per row of blocks */ - rows = height / bh; /* rows in blocks */ + for (slice = 0; slice < depth; slice++) { + /* Map dest texture buffer */ + ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset, + xoffset, yoffset, width, height, + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT, + &dstMap, &dstRowStride); + + if (dstMap) { + bytesPerRow = srcRowStride; /* bytes per row of blocks */ + rows = (height + bh - 1) / bh; /* rows in blocks */ + + /* copy rows of blocks */ + for (i = 0; i < rows; i++) { + memcpy(dstMap, src, bytesPerRow); + dstMap += dstRowStride; + src += srcRowStride; + } - /* copy rows of blocks */ - for (i = 0; i < rows; i++) { - memcpy(dest, src, bytesPerRow); - dest += destRowStride; - src += srcRowStride; + ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset); + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD", + dims); + } } _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); } - - -/** - * Fallback for Driver.CompressedTexSubImage3D() - */ -void -_mesa_store_compressed_texsubimage3d(struct gl_context *ctx, GLenum target, - GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - /* there are no compressed 3D texture formats yet */ - (void) ctx; - (void) target; (void) level; - (void) xoffset; (void) yoffset; (void) zoffset; - (void) width; (void) height; (void) depth; - (void) format; - (void) imageSize; (void) data; - (void) texObj; - (void) texImage; -}