summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-11-07 18:33:42 -0700
committerBrian Paul <brianp@vmware.com>2010-11-07 18:33:42 -0700
commitdd28b4c1fc56106e5ac2f13767f41b9f721dbb36 (patch)
treeb02d1ef2c29cfbb41e1265f3438cfe53a7778dee
parent90c52c26d8345cf9854b2f0e444966acc1642253 (diff)
mesa: implement uint texstore code
We used float temporary images before which could lose precision for uint-valued texture images.
-rw-r--r--src/mesa/main/texstore.c151
1 files changed, 127 insertions, 24 deletions
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 31967fdcd3..fd7476d227 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;