mesa: implement uint texstore code

We used float temporary images before which could lose precision for
uint-valued texture images.
This commit is contained in:
Brian Paul 2010-11-07 18:33:42 -07:00
parent 90c52c26d8
commit dd28b4c1fc

View file

@ -418,6 +418,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.
@ -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;