diff options
Diffstat (limited to 'src/mesa/main/texstore.c')
-rw-r--r-- | src/mesa/main/texstore.c | 246 |
1 files changed, 188 insertions, 58 deletions
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index f5f94bbf1a..89677c519e 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -58,7 +58,9 @@ #include "image.h" #include "macros.h" #include "mipmap.h" +#include "pack.h" #include "imports.h" +#include "pack.h" #include "texcompress.h" #include "texcompress_fxt1.h" #include "texcompress_s3tc.h" @@ -313,9 +315,9 @@ make_temp_float_image(struct gl_context *ctx, GLuint dims, GLint srcWidth, GLint srcHeight, GLint srcDepth, GLenum srcFormat, GLenum srcType, const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) + const struct gl_pixelstore_attrib *srcPacking, + GLbitfield transferOps) { - GLuint transferOps = ctx->_ImageTransferState; GLfloat *tempImage; const GLint components = _mesa_components_in_format(logicalBaseFormat); const GLint srcStride = @@ -417,6 +419,115 @@ make_temp_float_image(struct gl_context *ctx, GLuint dims, /** + * Make temporary image with uint pixel values. Used for unsigned + * integer-valued textures. + */ +static GLuint * +make_temp_uint_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 *tempImage; + const GLint components = _mesa_components_in_format(logicalBaseFormat); + const GLint srcStride = + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); + GLuint *dst; + GLint img, row; + + ASSERT(dims >= 1 && dims <= 3); + + ASSERT(logicalBaseFormat == GL_RGBA || + logicalBaseFormat == GL_RGB || + logicalBaseFormat == GL_RG || + logicalBaseFormat == GL_RED || + logicalBaseFormat == GL_LUMINANCE_ALPHA || + logicalBaseFormat == GL_LUMINANCE || + logicalBaseFormat == GL_INTENSITY || + logicalBaseFormat == GL_ALPHA); + + ASSERT(textureBaseFormat == GL_RGBA || + textureBaseFormat == GL_RGB || + textureBaseFormat == GL_RG || + textureBaseFormat == GL_RED || + textureBaseFormat == GL_LUMINANCE_ALPHA || + textureBaseFormat == GL_LUMINANCE || + textureBaseFormat == GL_ALPHA); + + tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth + * components * sizeof(GLuint)); + if (!tempImage) + return NULL; + + dst = tempImage; + for (img = 0; img < srcDepth; 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++) { + _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat, + dst, srcFormat, srcType, src, + srcPacking); + dst += srcWidth * components; + src += srcStride; + } + } + + if (logicalBaseFormat != textureBaseFormat) { + /* more work */ + GLint texComponents = _mesa_components_in_format(textureBaseFormat); + GLint logComponents = _mesa_components_in_format(logicalBaseFormat); + GLuint *newImage; + GLint i, n; + GLubyte map[6]; + + /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ + ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || + textureBaseFormat == GL_LUMINANCE_ALPHA); + + /* The actual texture format should have at least as many components + * as the logical texture format. + */ + ASSERT(texComponents >= logComponents); + + newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth + * texComponents * sizeof(GLuint)); + if (!newImage) { + free(tempImage); + return NULL; + } + + compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); + + n = srcWidth * srcHeight * srcDepth; + for (i = 0; i < n; i++) { + GLint k; + for (k = 0; k < texComponents; k++) { + GLint j = map[k]; + if (j == ZERO) + newImage[i * texComponents + k] = 0.0F; + else if (j == ONE) + newImage[i * texComponents + k] = 1.0F; + else + newImage[i * texComponents + k] = tempImage[i * logComponents + j]; + } + } + + free(tempImage); + tempImage = newImage; + } + + return tempImage; +} + + + +/** * Make a temporary (color) texture image with GLchan components. * Apply all needed pixel unpacking and pixel transfer operations. * Note that there are both logicalBaseFormat and textureBaseFormat parameters. @@ -2083,7 +2194,8 @@ _mesa_texstore_unorm1616(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *src = tempImage; GLint img, row, col; if (!tempImage) @@ -2157,7 +2269,8 @@ _mesa_texstore_r16(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *src = tempImage; GLint img, row, col; if (!tempImage) @@ -2214,7 +2327,8 @@ _mesa_texstore_rgba_16(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *src = tempImage; GLint img, row, col; if (!tempImage) @@ -2280,7 +2394,8 @@ _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *src = tempImage; const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2; GLint img, row, col; @@ -2661,7 +2776,8 @@ _mesa_texstore_signed_r8(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *srcRow = tempImage; GLint img, row, col; if (!tempImage) @@ -2705,7 +2821,8 @@ _mesa_texstore_signed_rg88(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *srcRow = tempImage; GLint img, row, col; if (!tempImage) @@ -2749,7 +2866,8 @@ _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *srcRow = tempImage; GLint img, row, col; if (!tempImage) @@ -2861,7 +2979,8 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *srcRow = tempImage; GLint img, row, col; if (!tempImage) @@ -3169,7 +3288,8 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *srcRow = tempImage; GLint bytesPerRow; GLint img, row; @@ -3238,7 +3358,8 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, + ctx->_ImageTransferState); const GLfloat *src = tempImage; GLint img, row; if (!tempImage) @@ -3282,8 +3403,10 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(texelBytes == components * sizeof(GLbyte)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && + /* 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 */ @@ -3301,7 +3424,7 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, 0x0); const GLfloat *src = tempImage; GLint img, row; if (!tempImage) @@ -3345,10 +3468,12 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(texelBytes == components * sizeof(GLshort)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && + /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply + * to integer formats. + */ + if (!srcPacking->SwapBytes && baseInternalFormat == srcFormat && - srcType == GL_INT) { + srcType == GL_SHORT) { /* simple memcpy path */ memcpy_texture(ctx, dims, dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, @@ -3364,7 +3489,7 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, 0x0); const GLfloat *src = tempImage; GLint img, row; if (!tempImage) @@ -3408,8 +3533,10 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(texelBytes == components * sizeof(GLint)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && + /* 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 */ @@ -3427,7 +3554,7 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS) baseFormat, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, - srcPacking); + srcPacking, 0x0); const GLfloat *src = tempImage; GLint img, row; if (!tempImage) @@ -3471,8 +3598,10 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(texelBytes == components * sizeof(GLubyte)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && + /* 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 */ @@ -3485,13 +3614,11 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) } else { /* general path */ - const GLfloat *tempImage = make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - 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; if (!tempImage) return GL_FALSE; @@ -3504,7 +3631,7 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) GLubyte *dstTexel = (GLubyte *) dstRow; GLint i; for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLubyte) src[i]; + dstTexel[i] = (GLubyte) CLAMP(src[i], 0, 0xff); } dstRow += dstRowStride; src += srcWidth * components; @@ -3534,8 +3661,10 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(texelBytes == components * sizeof(GLushort)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && + /* 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 */ @@ -3548,13 +3677,11 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) } else { /* general path */ - const GLfloat *tempImage = make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - 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; if (!tempImage) return GL_FALSE; @@ -3567,7 +3694,7 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) GLushort *dstTexel = (GLushort *) dstRow; GLint i; for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLushort) src[i]; + dstTexel[i] = (GLushort) CLAMP(src[i], 0, 0xffff); } dstRow += dstRowStride; src += srcWidth * components; @@ -3597,8 +3724,10 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(texelBytes == components * sizeof(GLuint)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && + /* 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 */ @@ -3611,13 +3740,11 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) } else { /* general path */ - const GLfloat *tempImage = make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - 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; if (!tempImage) return GL_FALSE; @@ -3630,7 +3757,7 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) GLuint *dstTexel = (GLuint *) dstRow; GLint i; for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLuint) src[i]; + dstTexel[i] = src[i]; } dstRow += dstRowStride; src += srcWidth * components; @@ -3953,14 +4080,14 @@ _mesa_validate_pbo_teximage(struct gl_context *ctx, GLuint dimensions, } if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth, format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access"); + _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)"); return NULL; } buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, GL_READ_ONLY_ARB, unpack->BufferObj); if (!buf) { - _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped"); + _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped)"); return NULL; } @@ -3990,7 +4117,7 @@ _mesa_validate_pbo_compressed_teximage(struct gl_context *ctx, if ((const GLubyte *) pixels + imageSize > ((const GLubyte *) 0) + packing->BufferObj->Size) { /* out of bounds read! */ - _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access"); + _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)"); return NULL; } @@ -4321,7 +4448,8 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level, * Fallback for Driver.CompressedTexImage1D() */ void -_mesa_store_compressed_teximage1d(struct gl_context *ctx, GLenum target, GLint level, +_mesa_store_compressed_teximage1d(struct gl_context *ctx, + GLenum target, GLint level, GLint internalFormat, GLint width, GLint border, GLsizei imageSize, const GLvoid *data, @@ -4344,7 +4472,8 @@ _mesa_store_compressed_teximage1d(struct gl_context *ctx, GLenum target, GLint l * Fallback for Driver.CompressedTexImage2D() */ void -_mesa_store_compressed_teximage2d(struct gl_context *ctx, GLenum target, GLint level, +_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, @@ -4388,7 +4517,8 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx, GLenum target, GLint l * Fallback for Driver.CompressedTexImage3D() */ void -_mesa_store_compressed_teximage3d(struct gl_context *ctx, GLenum target, GLint level, +_mesa_store_compressed_teximage3d(struct gl_context *ctx, + GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint depth, GLint border, |