diff options
Diffstat (limited to 'src/mesa/main/texstore.c')
-rw-r--r-- | src/mesa/main/texstore.c | 297 |
1 files changed, 214 insertions, 83 deletions
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 0fd6a2daae..6360ca15f8 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.3 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (c) 2008 VMware, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -1536,10 +1537,10 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) for (row = 0; row < srcHeight; row++) { GLuint *d4 = (GLuint *) dstRow; for (col = 0; col < srcWidth; col++) { - d4[col] = ((0xff << 24) | - (srcRow[col * 3 + RCOMP] << 16) | - (srcRow[col * 3 + GCOMP] << 8) | - (srcRow[col * 3 + BCOMP] << 0)); + d4[col] = PACK_COLOR_8888(0xff, + srcRow[col * 3 + RCOMP], + srcRow[col * 3 + GCOMP], + srcRow[col * 3 + BCOMP]); } dstRow += dstRowStride; srcRow += srcRowStride; @@ -1551,8 +1552,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) dstFormat == &_mesa_texformat_argb8888 && srcFormat == GL_RGBA && baseInternalFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE && - littleEndian) { + srcType == GL_UNSIGNED_BYTE) { /* same as above case, but src data has alpha too */ GLint img, row, col; /* For some reason, streaming copies to write-combined regions @@ -1573,39 +1573,10 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) for (row = 0; row < srcHeight; row++) { GLuint *d4 = (GLuint *) dstRow; for (col = 0; col < srcWidth; col++) { - d4[col] = ((srcRow[col * 4 + ACOMP] << 24) | - (srcRow[col * 4 + RCOMP] << 16) | - (srcRow[col * 4 + GCOMP] << 8) | - (srcRow[col * 4 + BCOMP] << 0)); - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == &_mesa_texformat_argb8888 && - srcFormat == GL_RGBA && - baseInternalFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { - - GLint 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] * dstFormat->TexelBytes - + dstYoffset * dstRowStride - + dstXoffset * dstFormat->TexelBytes; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col * 4 + 0] = srcRow[col * 4 + BCOMP]; - dstRow[col * 4 + 1] = srcRow[col * 4 + GCOMP]; - dstRow[col * 4 + 2] = srcRow[col * 4 + RCOMP]; - dstRow[col * 4 + 3] = srcRow[col * 4 + ACOMP]; + d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP], + srcRow[col * 4 + RCOMP], + srcRow[col * 4 + GCOMP], + srcRow[col * 4 + BCOMP]); } dstRow += dstRowStride; srcRow += srcRowStride; @@ -1928,6 +1899,60 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS) return GL_TRUE; } +GLboolean +_mesa_texstore_rgba4444(TEXSTORE_PARAMS) +{ + ASSERT(dstFormat == &_mesa_texformat_rgba4444); + ASSERT(dstFormat->TexelBytes == 2); + + if (!ctx->_ImageTransferState && + !srcPacking->SwapBytes && + dstFormat == &_mesa_texformat_rgba4444 && + baseInternalFormat == GL_RGBA && + srcFormat == GL_RGBA && + srcType == GL_UNSIGNED_SHORT_4_4_4_4){ + /* 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, + dstFormat->BaseFormat, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); + const GLchan *src = tempImage; + GLint img, row, col; + if (!tempImage) + return GL_FALSE; + _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); + for (img = 0; img < srcDepth; img++) { + GLubyte *dstRow = (GLubyte *) dstAddr + + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes + + dstYoffset * dstRowStride + + dstXoffset * dstFormat->TexelBytes; + for (row = 0; row < srcHeight; row++) { + GLushort *dstUS = (GLushort *) dstRow; + for (col = 0; col < srcWidth; col++) { + dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[RCOMP]), + CHAN_TO_UBYTE(src[GCOMP]), + CHAN_TO_UBYTE(src[BCOMP]), + CHAN_TO_UBYTE(src[ACOMP]) ); + src += 4; + } + dstRow += dstRowStride; + } + } + _mesa_free((void *) tempImage); + } + return GL_TRUE; +} GLboolean _mesa_texstore_argb4444(TEXSTORE_PARAMS) @@ -1996,7 +2021,60 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS) return GL_TRUE; } +GLboolean +_mesa_texstore_rgba5551(TEXSTORE_PARAMS) +{ + ASSERT(dstFormat == &_mesa_texformat_rgba5551); + ASSERT(dstFormat->TexelBytes == 2); + if (!ctx->_ImageTransferState && + !srcPacking->SwapBytes && + dstFormat == &_mesa_texformat_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, + dstFormat->BaseFormat, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); + const GLchan *src =tempImage; + GLint img, row, col; + if (!tempImage) + return GL_FALSE; + _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); + for (img = 0; img < srcDepth; img++) { + GLubyte *dstRow = (GLubyte *) dstAddr + + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes + + dstYoffset * dstRowStride + + dstXoffset * dstFormat->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; + } + } + _mesa_free((void *) tempImage); + } + return GL_TRUE; +} GLboolean _mesa_texstore_argb1555(TEXSTORE_PARAMS) @@ -2692,7 +2770,6 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) GLboolean _mesa_texstore_srgb8(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); const struct gl_texture_format *newDstFormat; StoreTexImageFunc store; GLboolean k; @@ -2700,14 +2777,8 @@ _mesa_texstore_srgb8(TEXSTORE_PARAMS) ASSERT(dstFormat == &_mesa_texformat_srgb8); /* reuse normal rgb texstore code */ - if (littleEndian) { - newDstFormat = &_mesa_texformat_bgr888; - store = _mesa_texstore_bgr888; - } - else { - newDstFormat = &_mesa_texformat_rgb888; - store = _mesa_texstore_rgb888; - } + newDstFormat = &_mesa_texformat_rgb888; + store = _mesa_texstore_rgb888; k = store(ctx, dims, baseInternalFormat, newDstFormat, dstAddr, @@ -2723,17 +2794,13 @@ _mesa_texstore_srgb8(TEXSTORE_PARAMS) GLboolean _mesa_texstore_srgba8(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); const struct gl_texture_format *newDstFormat; GLboolean k; ASSERT(dstFormat == &_mesa_texformat_srgba8); /* reuse normal rgba texstore code */ - if (littleEndian) - newDstFormat = &_mesa_texformat_rgba8888_rev; - else - newDstFormat = &_mesa_texformat_rgba8888; + newDstFormat = &_mesa_texformat_rgba8888; k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat, newDstFormat, dstAddr, @@ -2747,6 +2814,28 @@ _mesa_texstore_srgba8(TEXSTORE_PARAMS) GLboolean +_mesa_texstore_sargb8(TEXSTORE_PARAMS) +{ + const struct gl_texture_format *newDstFormat; + GLboolean k; + + ASSERT(dstFormat == &_mesa_texformat_sargb8); + + /* reuse normal rgba texstore code */ + newDstFormat = &_mesa_texformat_argb8888; + + k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat, + newDstFormat, dstAddr, + dstXoffset, dstYoffset, dstZoffset, + dstRowStride, dstImageOffsets, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, + srcAddr, srcPacking); + return k; +} + + +GLboolean _mesa_texstore_sl8(TEXSTORE_PARAMS) { const struct gl_texture_format *newDstFormat; @@ -2771,17 +2860,13 @@ _mesa_texstore_sl8(TEXSTORE_PARAMS) GLboolean _mesa_texstore_sla8(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); const struct gl_texture_format *newDstFormat; GLboolean k; ASSERT(dstFormat == &_mesa_texformat_sla8); /* reuse normal luminance/alpha texstore code */ - if (littleEndian) - newDstFormat = &_mesa_texformat_al88; - else - newDstFormat = &_mesa_texformat_al88_rev; + newDstFormat = &_mesa_texformat_al88; k = _mesa_texstore_al88(ctx, dims, baseInternalFormat, newDstFormat, dstAddr, @@ -3018,10 +3103,13 @@ choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage, -/* +/** * This is the software fallback for Driver.TexImage1D() * and Driver.CopyTexImage1D(). * \sa _mesa_store_teximage2d() + * Note that the width may not be the actual texture width since it may + * be changed by convolution w/ GL_REDUCE. The texImage->Width field will + * have the actual texture size. */ void _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, @@ -3032,21 +3120,16 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - GLint postConvWidth = width; GLint sizeInBytes; (void) border; - if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { - _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); - } - choose_texture_format(ctx, texImage, 1, format, type, internalFormat); /* allocate memory */ if (texImage->IsCompressed) sizeInBytes = texImage->CompressedSize; else - sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes; + sizeInBytes = texImage->Width * texImage->TexFormat->TexelBytes; texImage->Data = _mesa_alloc_texmemory(sizeInBytes); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); @@ -3106,15 +3189,9 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - GLint postConvWidth = width, postConvHeight = height; GLint texelBytes, sizeInBytes; (void) border; - if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { - _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, - &postConvHeight); - } - choose_texture_format(ctx, texImage, 2, format, type, internalFormat); texelBytes = texImage->TexFormat->TexelBytes; @@ -3123,7 +3200,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, if (texImage->IsCompressed) sizeInBytes = texImage->CompressedSize; else - sizeInBytes = postConvWidth * postConvHeight * texelBytes; + sizeInBytes = texImage->Width * texImage->Height * texelBytes; texImage->Data = _mesa_alloc_texmemory(sizeInBytes); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); @@ -3619,16 +3696,40 @@ is_srgb_teximage(const struct gl_texture_image *texImage) switch (texImage->TexFormat->MesaFormat) { case MESA_FORMAT_SRGB8: case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: case MESA_FORMAT_SL8: case MESA_FORMAT_SLA8: + case MESA_FORMAT_SRGB_DXT1: + case MESA_FORMAT_SRGBA_DXT1: + case MESA_FORMAT_SRGBA_DXT3: + case MESA_FORMAT_SRGBA_DXT5: return GL_TRUE; default: return GL_FALSE; } } -#endif /* FEATURE_EXT_texture_sRGB */ +/** + * Convert a float value from linear space to a + * non-linear sRGB value in [0, 255]. + * Not terribly efficient. + */ +static INLINE GLfloat +linear_to_nonlinear(GLfloat cl) +{ + /* can't have values outside [0, 1] */ + GLfloat cs; + if (cl < 0.0031308) { + cs = 12.92 * cl; + } + else { + cs = 1.055 * _mesa_pow(cl, 0.41666) - 0.055; + } + return cs; +} + +#endif /* FEATURE_EXT_texture_sRGB */ /** * This is the software fallback for Driver.GetTexImage(). @@ -3745,18 +3846,48 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, } #if FEATURE_EXT_texture_sRGB else if (is_srgb_teximage(texImage)) { - /* no pixel transfer and no non-linear to linear conversion */ - const GLint comps = texImage->TexFormat->TexelBytes; - const GLint rowstride = comps * texImage->RowStride; - MEMCPY(dest, - (const GLubyte *) texImage->Data + row * rowstride, - comps * width * sizeof(GLubyte)); + /* special case this since need to backconvert values */ + /* convert row to RGBA format */ + GLfloat rgba[MAX_WIDTH][4]; + GLint col; + GLbitfield transferOps = 0x0; + + for (col = 0; col < width; col++) { + (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]); + if (texImage->TexFormat->BaseFormat == GL_LUMINANCE) { + rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]); + rgba[col][GCOMP] = 0.0; + rgba[col][BCOMP] = 0.0; + } + else if (texImage->TexFormat->BaseFormat == GL_LUMINANCE_ALPHA) { + rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]); + rgba[col][GCOMP] = 0.0; + rgba[col][BCOMP] = 0.0; + } + else if (texImage->TexFormat->BaseFormat == GL_RGB || + texImage->TexFormat->BaseFormat == GL_RGBA) { + rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]); + rgba[col][GCOMP] = linear_to_nonlinear(rgba[col][GCOMP]); + rgba[col][BCOMP] = linear_to_nonlinear(rgba[col][BCOMP]); + } + } + _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, + format, type, dest, + &ctx->Pack, transferOps /*image xfer ops*/); } #endif /* FEATURE_EXT_texture_sRGB */ else { /* general case: convert row to RGBA format */ GLfloat rgba[MAX_WIDTH][4]; GLint col; + GLbitfield transferOps = 0x0; + + if (type == GL_FLOAT && + ((ctx->Color.ClampReadColor == GL_TRUE) || + (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB && + texImage->TexFormat->DataType != GL_FLOAT))) + transferOps |= IMAGE_CLAMP_BIT; + for (col = 0; col < width; col++) { (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]); if (texImage->TexFormat->BaseFormat == GL_ALPHA) { @@ -3781,7 +3912,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, } _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, type, dest, - &ctx->Pack, 0x0 /*image xfer ops*/); + &ctx->Pack, transferOps /*image xfer ops*/); } /* format */ } /* row */ } /* img */ @@ -3802,8 +3933,8 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, void _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, GLvoid *img, - const struct gl_texture_object *texObj, - const struct gl_texture_image *texImage) + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { GLuint size; |