diff options
author | Brian Paul <[email protected]> | 2010-11-07 18:33:42 -0700 |
---|---|---|
committer | Brian Paul <[email protected]> | 2010-11-07 18:33:42 -0700 |
commit | dd28b4c1fc56106e5ac2f13767f41b9f721dbb36 (patch) | |
tree | b02d1ef2c29cfbb41e1265f3438cfe53a7778dee /src | |
parent | 90c52c26d8345cf9854b2f0e444966acc1642253 (diff) |
mesa: implement uint texstore code
We used float temporary images before which could lose precision for
uint-valued texture images.
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/main/texstore.c | 151 |
1 files changed, 127 insertions, 24 deletions
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 31967fdcd35..fd7476d2273 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -419,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. @@ -3505,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, 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; if (!tempImage) return GL_FALSE; @@ -3524,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; @@ -3570,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, 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; if (!tempImage) return GL_FALSE; @@ -3589,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; @@ -3635,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, 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; if (!tempImage) return GL_FALSE; @@ -3654,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; |