mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 18:18:06 +02:00
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:
parent
90c52c26d8
commit
dd28b4c1fc
1 changed files with 127 additions and 24 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue