From f6dbb693d211feca9980437c54897ca6619e0a15 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 23 Oct 2010 09:22:48 -0600 Subject: mesa: add pixel packing for unscaled integer types And add some missing GL_RG cases. --- src/mesa/main/pack.c | 501 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 496 insertions(+), 5 deletions(-) diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c index 981d99c4752..877d27ce1e4 100644 --- a/src/mesa/main/pack.c +++ b/src/mesa/main/pack.c @@ -335,12 +335,46 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, +/** + * For small integer types, return the min and max possible values. + * Used for clamping floats to unscaled integer types. + * \return GL_TRUE if type is handled, GL_FALSE otherwise. + */ +static GLboolean +get_type_min_max(GLenum type, GLfloat *min, GLfloat *max) +{ + switch (type) { + case GL_BYTE: + *min = -128.0; + *max = 127.0; + return GL_TRUE; + case GL_UNSIGNED_BYTE: + *min = 0.0; + *max = 255.0; + return GL_TRUE; + case GL_SHORT: + *min = -32768.0; + *max = 32767.0; + return GL_TRUE; + case GL_UNSIGNED_SHORT: + *min = 0.0; + *max = 65535.0; + return GL_TRUE; + default: + return GL_FALSE; + } +} + /** * Used to pack an array [][4] of RGBA float colors as specified - * by the dstFormat, dstType and dstPacking. Used by glReadPixels, - * glGetConvolutionFilter(), etc. + * by the dstFormat, dstType and dstPacking. Used by glReadPixels. + * Historically, the RGBA values were in [0,1] and rescaled to fit + * into GLubytes, etc. But with new integer formats, the RGBA values + * may have any value and we don't always rescale when converting to + * integers. + * * Note: the rgba values will be modified by this function when any pixel * transfer ops are enabled. */ @@ -353,6 +387,7 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], { GLfloat luminance[MAX_WIDTH]; const GLint comps = _mesa_components_in_format(dstFormat); + const GLboolean intDstFormat = _mesa_is_integer_format(dstFormat); GLuint i; /* XXX @@ -360,15 +395,33 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], * IMAGE_CLAMP_BIT as needed. */ if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) { - /* need to clamp to [0, 1] */ - transferOps |= IMAGE_CLAMP_BIT; + if (!intDstFormat) { + /* need to clamp to [0, 1] */ + transferOps |= IMAGE_CLAMP_BIT; + } } if (transferOps) { _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba); } - if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) { + /* + * Component clamping (besides clamping to [0,1] in + * _mesa_apply_rgba_transfer_ops()). + */ + if (intDstFormat) { + /* clamping to dest type's min/max values */ + GLfloat min, max; + if (get_type_min_max(dstType, &min, &max)) { + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], min, max); + rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], min, max); + rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], min, max); + rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], min, max); + } + } + } + else if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) { /* compute luminance values */ if (transferOps & IMAGE_CLAMP_BIT) { for (i = 0; i < n; i++) { @@ -417,6 +470,12 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][ACOMP]); } break; + case GL_RG: + for (i=0;i