X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fpack.c;h=4f0caa7636c4e9a9e1f24d6e13cde14953724618;hb=d012e6d8fe2f4f1139af9e47a684960e8cde103e;hp=512835cb803d135e9e976bab2d3a307817c19246;hpb=0117da40cd7edd3d165bb28569c289b37eca12b9;p=mesa.git diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c index 512835cb803..4f0caa7636c 100644 --- a/src/mesa/main/pack.c +++ b/src/mesa/main/pack.c @@ -29,35 +29,32 @@ */ +/* + * XXX: MSVC takes forever to compile this module for x86_64 unless we disable + * this global optimization. + * + * See also: + * - http://msdn.microsoft.com/en-us/library/1yk3ydd7.aspx + * - http://msdn.microsoft.com/en-us/library/chh3fb0k.aspx + */ +#if defined(_MSC_VER) && defined(_M_X64) +# pragma optimize( "g", off ) +#endif + + #include "glheader.h" #include "colormac.h" #include "enums.h" #include "image.h" #include "imports.h" +#include "macros.h" #include "mtypes.h" #include "pack.h" #include "pixeltransfer.h" #include "imports.h" - - -/** - * NOTE: - * Normally, BYTE_TO_FLOAT(0) returns 0.00392 That causes problems when - * we later convert the float to a packed integer value (such as for - * GL_RGB5_A1) because we'll wind up with a non-zero value. - * - * We redefine the macros here so zero is handled correctly. - */ -#undef BYTE_TO_FLOAT -#define BYTE_TO_FLOAT(B) ((B) == 0 ? 0.0F : ((2.0F * (B) + 1.0F) * (1.0F/255.0F))) - -#undef SHORT_TO_FLOAT -#define SHORT_TO_FLOAT(S) ((S) == 0 ? 0.0F : ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))) - - - -/** Compute ceiling of integer quotient of A divided by B. */ -#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) +#include "glformats.h" +#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" /** @@ -160,7 +157,7 @@ _mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels, /* Alloc dest storage */ bytes = ((width + 7) / 8 * height); - buffer = (GLubyte *) malloc( bytes ); + buffer = malloc( bytes ); if (!buffer) return NULL; @@ -465,6 +462,785 @@ get_type_min_max(GLenum type, GLfloat *min, GLfloat *max) } } +/* Customization of unsigned integer packing. + */ +#define SRC_TYPE GLuint + +#define DST_TYPE GLuint +#define SRC_CONVERT(x) (x) +#define FN_NAME pack_uint_from_uint_rgba +#include "pack_tmp.h" +#undef DST_TYPE +#undef SRC_CONVERT +#undef FN_NAME + +#define DST_TYPE GLint +#define SRC_CONVERT(x) MIN2(x, 0x7fffffff) +#define FN_NAME pack_int_from_uint_rgba +#include "pack_tmp.h" +#undef DST_TYPE +#undef SRC_CONVERT +#undef FN_NAME + +#define DST_TYPE GLushort +#define SRC_CONVERT(x) MIN2(x, 0xffff) +#define FN_NAME pack_ushort_from_uint_rgba +#include "pack_tmp.h" +#undef DST_TYPE +#undef SRC_CONVERT +#undef FN_NAME + +#define DST_TYPE GLshort +#define SRC_CONVERT(x) CLAMP((int)x, -32768, 32767) +#define FN_NAME pack_short_from_uint_rgba +#include "pack_tmp.h" +#undef DST_TYPE +#undef SRC_CONVERT +#undef FN_NAME + +#define DST_TYPE GLubyte +#define SRC_CONVERT(x) MIN2(x, 0xff) +#define FN_NAME pack_ubyte_from_uint_rgba +#include "pack_tmp.h" +#undef DST_TYPE +#undef SRC_CONVERT +#undef FN_NAME + +#define DST_TYPE GLbyte +#define SRC_CONVERT(x) CLAMP((int)x, -128, 127) +#define FN_NAME pack_byte_from_uint_rgba +#include "pack_tmp.h" +#undef DST_TYPE +#undef SRC_CONVERT +#undef FN_NAME + +#undef SRC_TYPE + +static void +_pack_rgba_span_from_uints_problem(struct gl_context *ctx, + GLenum dstFormat, GLenum dstType) +{ + _mesa_problem(ctx, + "Unsupported type (%s) / format (%s) " + "in _mesa_pack_rgba_span_from_uints", + _mesa_lookup_enum_by_nr(dstType), + _mesa_lookup_enum_by_nr(dstFormat)); +} + +void +_mesa_pack_rgba_span_from_uints(struct gl_context *ctx, GLuint n, GLuint rgba[][4], + GLenum dstFormat, GLenum dstType, + GLvoid *dstAddr) +{ + GLuint i; + + switch(dstType) { + case GL_UNSIGNED_INT: + pack_uint_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); + break; + case GL_INT: + pack_int_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); + break; + case GL_UNSIGNED_SHORT: + pack_ushort_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); + break; + case GL_SHORT: + pack_short_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); + break; + case GL_UNSIGNED_BYTE: + pack_ubyte_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); + break; + case GL_BYTE: + pack_byte_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); + break; + case GL_UNSIGNED_BYTE_3_3_2: + if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { + GLubyte *dst = (GLubyte *) dstAddr; + for (i=0;iColor.ClampReadColor == GL_TRUE) { - if (!intDstFormat) { - /* need to clamp to [0, 1] */ - transferOps |= IMAGE_CLAMP_BIT; - } - } + if (intDstFormat) + transferOps = 0; if (transferOps) { _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba); @@ -648,6 +1420,12 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], dst[i] = (GLubyte) rgba[i][ACOMP]; } break; + case GL_RG_INTEGER: + for (i=0;iSwapBytes) { GLint swapSize = _mesa_sizeof_packed_type(dstType); if (swapSize == 2) { - if (dstPacking->SwapBytes) { - _mesa_swap2((GLushort *) dstAddr, n * comps); - } + _mesa_swap2((GLushort *) dstAddr, n * comps); } else if (swapSize == 4) { - if (dstPacking->SwapBytes) { - _mesa_swap4((GLuint *) dstAddr, n * comps); - } + _mesa_swap4((GLuint *) dstAddr, n * comps); } } @@ -1964,7 +2785,8 @@ extract_uint_indexes(GLuint n, GLuint indexes[], srcType == GL_INT || srcType == GL_UNSIGNED_INT_24_8_EXT || srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT); + srcType == GL_FLOAT || + srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); switch (srcType) { case GL_BITMAP: @@ -2131,7 +2953,24 @@ extract_uint_indexes(GLuint n, GLuint indexes[], } else { for (i = 0; i < n; i++) - indexes[i] = s[i] & 0xff; /* lower 8 bits */ + indexes[i] = s[i] & 0xff; /* lower 8 bits */ + } + } + break; + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + { + GLuint i; + const GLuint *s = (const GLuint *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLuint value = s[i*2+1]; + SWAP4BYTE(value); + indexes[i] = value & 0xff; /* lower 8 bits */ + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i*2+1] & 0xff; /* lower 8 bits */ } } break; @@ -2168,7 +3007,7 @@ get_component_mapping(GLenum format, *gSrc = 0; *rSrc = *bSrc = *aSrc = -1; break; - case GL_BLUE: + case GL_BLUE: case GL_BLUE_INTEGER_EXT: *bSrc = 0; *rSrc = *gSrc = *aSrc = -1; @@ -2214,6 +3053,7 @@ get_component_mapping(GLenum format, *aDst = 3; break; case GL_BGR: + case GL_BGR_INTEGER: *rSrc = 2; *gSrc = 1; *bSrc = 0; @@ -2235,6 +3075,7 @@ get_component_mapping(GLenum format, *aDst = 3; break; case GL_BGRA: + case GL_BGRA_INTEGER: *rSrc = 2; *gSrc = 1; *bSrc = 0; @@ -2316,6 +3157,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], srcFormat == GL_GREEN_INTEGER_EXT || srcFormat == GL_BLUE_INTEGER_EXT || srcFormat == GL_ALPHA_INTEGER_EXT || + srcFormat == GL_RG_INTEGER || srcFormat == GL_RGB_INTEGER_EXT || srcFormat == GL_RGBA_INTEGER_EXT || srcFormat == GL_BGR_INTEGER_EXT || @@ -2342,7 +3184,9 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], srcType == GL_UNSIGNED_INT_8_8_8_8 || srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV); + srcType == GL_UNSIGNED_INT_2_10_10_10_REV || + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); get_component_mapping(srcFormat, &rSrc, &gSrc, &bSrc, &aSrc, @@ -2350,7 +3194,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], stride = _mesa_components_in_format(srcFormat); - intFormat = _mesa_is_integer_format(srcFormat); + intFormat = _mesa_is_enum_format_integer(srcFormat); #define PROCESS(SRC_INDEX, DST_INDEX, DEFAULT_FLT, DEFAULT_INT, TYPE, CONVERSION) \ if ((SRC_INDEX) < 0) { \ @@ -2409,10 +3253,10 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], PROCESS(aSrc, ACOMP, 1.0F, 255, GLubyte, UBYTE_TO_FLOAT); break; case GL_BYTE: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 127, GLbyte, BYTE_TO_FLOAT); + PROCESS(rSrc, RCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOATZ); + PROCESS(gSrc, GCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOATZ); + PROCESS(bSrc, BCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOATZ); + PROCESS(aSrc, ACOMP, 1.0F, 127, GLbyte, BYTE_TO_FLOATZ); break; case GL_UNSIGNED_SHORT: PROCESS(rSrc, RCOMP, 0.0F, 0, GLushort, USHORT_TO_FLOAT); @@ -2421,10 +3265,10 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], PROCESS(aSrc, ACOMP, 1.0F, 0xffff, GLushort, USHORT_TO_FLOAT); break; case GL_SHORT: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 32767, GLshort, SHORT_TO_FLOAT); + PROCESS(rSrc, RCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOATZ); + PROCESS(gSrc, GCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOATZ); + PROCESS(bSrc, BCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOATZ); + PROCESS(aSrc, ACOMP, 1.0F, 32767, GLshort, SHORT_TO_FLOATZ); break; case GL_UNSIGNED_INT: PROCESS(rSrc, RCOMP, 0.0F, 0, GLuint, UINT_TO_FLOAT); @@ -2812,6 +3656,62 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], } } break; + case GL_UNSIGNED_INT_5_9_9_9_REV: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + GLfloat f[3]; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + SWAP4BYTE(p); + rgb9e5_to_float3(p, f); + rgba[i][rDst] = f[0]; + rgba[i][gDst] = f[1]; + rgba[i][bDst] = f[2]; + rgba[i][aDst] = 1.0F; + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + GLfloat f[3]; + for (i = 0; i < n; i ++) { + rgb9e5_to_float3(uisrc[i], f); + rgba[i][rDst] = f[0]; + rgba[i][gDst] = f[1]; + rgba[i][bDst] = f[2]; + rgba[i][aDst] = 1.0F; + } + } + break; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + GLfloat f[3]; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + SWAP4BYTE(p); + r11g11b10f_to_float3(p, f); + rgba[i][rDst] = f[0]; + rgba[i][gDst] = f[1]; + rgba[i][bDst] = f[2]; + rgba[i][aDst] = 1.0F; + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + GLfloat f[3]; + for (i = 0; i < n; i ++) { + r11g11b10f_to_float3(uisrc[i], f); + rgba[i][rDst] = f[0]; + rgba[i][gDst] = f[1]; + rgba[i][bDst] = f[2]; + rgba[i][aDst] = 1.0F; + } + } + break; default: _mesa_problem(NULL, "bad srcType in extract float data"); break; @@ -2820,39 +3720,18 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], } -static INLINE GLuint -clamp_byte_to_uint(GLbyte b) -{ - return b < 0 ? 0 : b; -} - - -static INLINE GLuint -clamp_short_to_uint(GLshort s) -{ - return s < 0 ? 0 : s; -} - - -static INLINE GLuint -clamp_int_to_uint(GLint i) -{ - return i < 0 ? 0 : i; -} - - -static INLINE GLuint +static inline GLuint clamp_float_to_uint(GLfloat f) { - return f < 0.0F ? 0 : IROUND(f); + return f < 0.0F ? 0 : F_TO_I(f); } -static INLINE GLuint +static inline GLuint clamp_half_to_uint(GLhalfARB h) { GLfloat f = _mesa_half_to_float(h); - return f < 0.0F ? 0 : IROUND(f); + return f < 0.0F ? 0 : F_TO_I(f); } @@ -2867,7 +3746,6 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], GLint rSrc, gSrc, bSrc, aSrc; GLint stride; GLint rDst, bDst, gDst, aDst; - GLboolean intFormat; ASSERT(srcFormat == GL_RED || srcFormat == GL_GREEN || @@ -2885,6 +3763,7 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], srcFormat == GL_DU8DV8_ATI || srcFormat == GL_DUDV_ATI || srcFormat == GL_RED_INTEGER_EXT || + srcFormat == GL_RG_INTEGER || srcFormat == GL_GREEN_INTEGER_EXT || srcFormat == GL_BLUE_INTEGER_EXT || srcFormat == GL_ALPHA_INTEGER_EXT || @@ -2914,7 +3793,9 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], srcType == GL_UNSIGNED_INT_8_8_8_8 || srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV); + srcType == GL_UNSIGNED_INT_2_10_10_10_REV || + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); get_component_mapping(srcFormat, &rSrc, &gSrc, &bSrc, &aSrc, @@ -2922,8 +3803,6 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], stride = _mesa_components_in_format(srcFormat); - intFormat = _mesa_is_integer_format(srcFormat); - #define PROCESS(SRC_INDEX, DST_INDEX, DEFAULT, TYPE, CONVERSION) \ if ((SRC_INDEX) < 0) { \ GLuint i; \ @@ -2963,10 +3842,10 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], PROCESS(aSrc, ACOMP, 1, GLubyte, (GLuint)); break; case GL_BYTE: - PROCESS(rSrc, RCOMP, 0, GLbyte, clamp_byte_to_uint); - PROCESS(gSrc, GCOMP, 0, GLbyte, clamp_byte_to_uint); - PROCESS(bSrc, BCOMP, 0, GLbyte, clamp_byte_to_uint); - PROCESS(aSrc, ACOMP, 1, GLbyte, clamp_byte_to_uint); + PROCESS(rSrc, RCOMP, 0, GLbyte, (GLuint)); + PROCESS(gSrc, GCOMP, 0, GLbyte, (GLuint)); + PROCESS(bSrc, BCOMP, 0, GLbyte, (GLuint)); + PROCESS(aSrc, ACOMP, 1, GLbyte, (GLuint)); break; case GL_UNSIGNED_SHORT: PROCESS(rSrc, RCOMP, 0, GLushort, (GLuint)); @@ -2975,10 +3854,10 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], PROCESS(aSrc, ACOMP, 1, GLushort, (GLuint)); break; case GL_SHORT: - PROCESS(rSrc, RCOMP, 0, GLshort, clamp_short_to_uint); - PROCESS(gSrc, GCOMP, 0, GLshort, clamp_short_to_uint); - PROCESS(bSrc, BCOMP, 0, GLshort, clamp_short_to_uint); - PROCESS(aSrc, ACOMP, 1, GLshort, clamp_short_to_uint); + PROCESS(rSrc, RCOMP, 0, GLshort, (GLuint)); + PROCESS(gSrc, GCOMP, 0, GLshort, (GLuint)); + PROCESS(bSrc, BCOMP, 0, GLshort, (GLuint)); + PROCESS(aSrc, ACOMP, 1, GLshort, (GLuint)); break; case GL_UNSIGNED_INT: PROCESS(rSrc, RCOMP, 0, GLuint, (GLuint)); @@ -2987,10 +3866,10 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], PROCESS(aSrc, ACOMP, 1, GLuint, (GLuint)); break; case GL_INT: - PROCESS(rSrc, RCOMP, 0, GLint, clamp_int_to_uint); - PROCESS(gSrc, GCOMP, 0, GLint, clamp_int_to_uint); - PROCESS(bSrc, BCOMP, 0, GLint, clamp_int_to_uint); - PROCESS(aSrc, ACOMP, 1, GLint, clamp_int_to_uint); + PROCESS(rSrc, RCOMP, 0, GLint, (GLuint)); + PROCESS(gSrc, GCOMP, 0, GLint, (GLuint)); + PROCESS(bSrc, BCOMP, 0, GLint, (GLuint)); + PROCESS(aSrc, ACOMP, 1, GLint, (GLuint)); break; case GL_FLOAT: PROCESS(rSrc, RCOMP, 0, GLfloat, clamp_float_to_uint); @@ -3278,6 +4157,64 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], } } break; + case GL_UNSIGNED_INT_5_9_9_9_REV: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + float f[3]; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + SWAP4BYTE(p); + rgb9e5_to_float3(p, f); + rgba[i][rDst] = clamp_float_to_uint(f[0]); + rgba[i][gDst] = clamp_float_to_uint(f[1]); + rgba[i][bDst] = clamp_float_to_uint(f[2]); + rgba[i][aDst] = 1; + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + float f[3]; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + rgb9e5_to_float3(p, f); + rgba[i][rDst] = clamp_float_to_uint(f[0]); + rgba[i][gDst] = clamp_float_to_uint(f[1]); + rgba[i][bDst] = clamp_float_to_uint(f[2]); + rgba[i][aDst] = 1; + } + } + break; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + float f[3]; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + SWAP4BYTE(p); + r11g11b10f_to_float3(p, f); + rgba[i][rDst] = clamp_float_to_uint(f[0]); + rgba[i][gDst] = clamp_float_to_uint(f[1]); + rgba[i][bDst] = clamp_float_to_uint(f[2]); + rgba[i][aDst] = 1; + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + float f[3]; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + r11g11b10f_to_float3(p, f); + rgba[i][rDst] = clamp_float_to_uint(f[0]); + rgba[i][gDst] = clamp_float_to_uint(f[1]); + rgba[i][bDst] = clamp_float_to_uint(f[2]); + rgba[i][aDst] = 1; + } + } + break; default: _mesa_problem(NULL, "bad srcType in extract uint data"); break; @@ -3290,7 +4227,7 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], /* * Unpack a row of color image data from a client buffer according to * the pixel unpacking parameters. - * Return GLchan values in the specified dest image format. + * Return GLubyte values in the specified dest image format. * This is used by glDrawPixels and glTexImage?D(). * \param ctx - the context * n - number of pixels in the span @@ -3305,13 +4242,14 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], * XXX perhaps expand this to process whole images someday. */ void -_mesa_unpack_color_span_chan( struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLchan dest[], +_mesa_unpack_color_span_ubyte(struct gl_context *ctx, + GLuint n, GLenum dstFormat, GLubyte dest[], GLenum srcFormat, GLenum srcType, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking, GLbitfield transferOps ) { + GLboolean intFormat = _mesa_is_enum_format_integer(srcFormat); ASSERT(dstFormat == GL_ALPHA || dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA || @@ -3319,8 +4257,7 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, dstFormat == GL_RED || dstFormat == GL_RG || dstFormat == GL_RGB || - dstFormat == GL_RGBA || - dstFormat == GL_COLOR_INDEX); + dstFormat == GL_RGBA); ASSERT(srcFormat == GL_RED || srcFormat == GL_GREEN || @@ -3357,25 +4294,34 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, srcType == GL_UNSIGNED_INT_8_8_8_8 || srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV); + srcType == GL_UNSIGNED_INT_2_10_10_10_REV || + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); + + /* EXT_texture_integer specifies no transfer ops on integer + * types in the resolved issues section. Just set them to 0 + * for integer surfaces. + */ + if (intFormat) + transferOps = 0; /* Try simple cases first */ if (transferOps == 0) { - if (srcType == CHAN_TYPE) { + if (srcType == GL_UNSIGNED_BYTE) { if (dstFormat == GL_RGBA) { if (srcFormat == GL_RGBA) { - memcpy( dest, source, n * 4 * sizeof(GLchan) ); + memcpy( dest, source, n * 4 * sizeof(GLubyte) ); return; } else if (srcFormat == GL_RGB) { GLuint i; - const GLchan *src = (const GLchan *) source; - GLchan *dst = dest; + const GLubyte *src = (const GLubyte *) source; + GLubyte *dst = dest; for (i = 0; i < n; i++) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; - dst[3] = CHAN_MAX; + dst[3] = 255; src += 3; dst += 4; } @@ -3384,13 +4330,13 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, } else if (dstFormat == GL_RGB) { if (srcFormat == GL_RGB) { - memcpy( dest, source, n * 3 * sizeof(GLchan) ); + memcpy( dest, source, n * 3 * sizeof(GLubyte) ); return; } else if (srcFormat == GL_RGBA) { GLuint i; - const GLchan *src = (const GLchan *) source; - GLchan *dst = dest; + const GLubyte *src = (const GLubyte *) source; + GLubyte *dst = dest; for (i = 0; i < n; i++) { dst[0] = src[0]; dst[1] = src[1]; @@ -3404,74 +4350,10 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, else if (dstFormat == srcFormat) { GLint comps = _mesa_components_in_format(srcFormat); assert(comps > 0); - memcpy( dest, source, n * comps * sizeof(GLchan) ); + memcpy( dest, source, n * comps * sizeof(GLubyte) ); return; } } - /* - * Common situation, loading 8bit RGBA/RGB source images - * into 16/32 bit destination. (OSMesa16/32) - */ - else if (srcType == GL_UNSIGNED_BYTE) { - if (dstFormat == GL_RGBA) { - if (srcFormat == GL_RGB) { - GLuint i; - const GLubyte *src = (const GLubyte *) source; - GLchan *dst = dest; - for (i = 0; i < n; i++) { - dst[0] = UBYTE_TO_CHAN(src[0]); - dst[1] = UBYTE_TO_CHAN(src[1]); - dst[2] = UBYTE_TO_CHAN(src[2]); - dst[3] = CHAN_MAX; - src += 3; - dst += 4; - } - return; - } - else if (srcFormat == GL_RGBA) { - GLuint i; - const GLubyte *src = (const GLubyte *) source; - GLchan *dst = dest; - for (i = 0; i < n; i++) { - dst[0] = UBYTE_TO_CHAN(src[0]); - dst[1] = UBYTE_TO_CHAN(src[1]); - dst[2] = UBYTE_TO_CHAN(src[2]); - dst[3] = UBYTE_TO_CHAN(src[3]); - src += 4; - dst += 4; - } - return; - } - } - else if (dstFormat == GL_RGB) { - if (srcFormat == GL_RGB) { - GLuint i; - const GLubyte *src = (const GLubyte *) source; - GLchan *dst = dest; - for (i = 0; i < n; i++) { - dst[0] = UBYTE_TO_CHAN(src[0]); - dst[1] = UBYTE_TO_CHAN(src[1]); - dst[2] = UBYTE_TO_CHAN(src[2]); - src += 3; - dst += 3; - } - return; - } - else if (srcFormat == GL_RGBA) { - GLuint i; - const GLubyte *src = (const GLubyte *) source; - GLchan *dst = dest; - for (i = 0; i < n; i++) { - dst[0] = UBYTE_TO_CHAN(src[0]); - dst[1] = UBYTE_TO_CHAN(src[1]); - dst[2] = UBYTE_TO_CHAN(src[2]); - src += 4; - dst += 3; - } - return; - } - } - } } @@ -3479,7 +4361,7 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, { GLint dstComponents; GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); + GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat)); if (!rgba) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); @@ -3494,34 +4376,22 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, * Extract image data and convert to RGBA floats */ if (srcFormat == GL_COLOR_INDEX) { - GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); + GLuint *indexes = malloc(n * sizeof(GLuint)); if (!indexes) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + free(rgba); return; } extract_uint_indexes(n, indexes, srcFormat, srcType, source, srcPacking); - if (dstFormat == GL_COLOR_INDEX) { - GLuint i; - _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes); - /* convert to GLchan and return */ - for (i = 0; i < n; i++) { - dest[i] = (GLchan) (indexes[i] & 0xff); - } - free(indexes); - free(rgba); - return; - } - else { - /* Convert indexes to RGBA */ - if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { - _mesa_shift_and_offset_ci(ctx, n, indexes); - } - _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); - } + /* Convert indexes to RGBA */ + if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { + _mesa_shift_and_offset_ci(ctx, n, indexes); + } + _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting * with color indexes. @@ -3536,10 +4406,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, srcPacking->SwapBytes); } - /* Need to clamp if returning GLubytes or GLushorts */ -#if CHAN_TYPE != GL_FLOAT + /* Need to clamp if returning GLubytes */ transferOps |= IMAGE_CLAMP_BIT; -#endif if (transferOps) { _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba); @@ -3548,61 +4416,61 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, get_component_indexes(dstFormat, &rDst, &gDst, &bDst, &aDst, &lDst, &iDst); - /* Now return the GLchan data in the requested dstFormat */ + /* Now return the GLubyte data in the requested dstFormat */ if (rDst >= 0) { - GLchan *dst = dest; + GLubyte *dst = dest; GLuint i; for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_CHAN(dst[rDst], rgba[i][RCOMP]); + CLAMPED_FLOAT_TO_UBYTE(dst[rDst], rgba[i][RCOMP]); dst += dstComponents; } } if (gDst >= 0) { - GLchan *dst = dest; + GLubyte *dst = dest; GLuint i; for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_CHAN(dst[gDst], rgba[i][GCOMP]); + CLAMPED_FLOAT_TO_UBYTE(dst[gDst], rgba[i][GCOMP]); dst += dstComponents; } } if (bDst >= 0) { - GLchan *dst = dest; + GLubyte *dst = dest; GLuint i; for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_CHAN(dst[bDst], rgba[i][BCOMP]); + CLAMPED_FLOAT_TO_UBYTE(dst[bDst], rgba[i][BCOMP]); dst += dstComponents; } } if (aDst >= 0) { - GLchan *dst = dest; + GLubyte *dst = dest; GLuint i; for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_CHAN(dst[aDst], rgba[i][ACOMP]); + CLAMPED_FLOAT_TO_UBYTE(dst[aDst], rgba[i][ACOMP]); dst += dstComponents; } } if (iDst >= 0) { - GLchan *dst = dest; + GLubyte *dst = dest; GLuint i; assert(iDst == 0); assert(dstComponents == 1); for (i = 0; i < n; i++) { /* Intensity comes from red channel */ - CLAMPED_FLOAT_TO_CHAN(dst[i], rgba[i][RCOMP]); + CLAMPED_FLOAT_TO_UBYTE(dst[i], rgba[i][RCOMP]); } } if (lDst >= 0) { - GLchan *dst = dest; + GLubyte *dst = dest; GLuint i; assert(lDst == 0); for (i = 0; i < n; i++) { /* Luminance comes from red channel */ - CLAMPED_FLOAT_TO_CHAN(dst[0], rgba[i][RCOMP]); + CLAMPED_FLOAT_TO_UBYTE(dst[0], rgba[i][RCOMP]); dst += dstComponents; } } @@ -3613,8 +4481,8 @@ _mesa_unpack_color_span_chan( struct gl_context *ctx, /** - * Same as _mesa_unpack_color_span_chan(), but return GLfloat data - * instead of GLchan. + * Same as _mesa_unpack_color_span_ubyte(), but return GLfloat data + * instead of GLubyte. */ void _mesa_unpack_color_span_float( struct gl_context *ctx, @@ -3631,8 +4499,7 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, dstFormat == GL_RED || dstFormat == GL_RG || dstFormat == GL_RGB || - dstFormat == GL_RGBA || - dstFormat == GL_COLOR_INDEX); + dstFormat == GL_RGBA); ASSERT(srcFormat == GL_RED || srcFormat == GL_GREEN || @@ -3651,6 +4518,7 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, srcFormat == GL_GREEN_INTEGER_EXT || srcFormat == GL_BLUE_INTEGER_EXT || srcFormat == GL_ALPHA_INTEGER_EXT || + srcFormat == GL_RG_INTEGER || srcFormat == GL_RGB_INTEGER_EXT || srcFormat == GL_RGBA_INTEGER_EXT || srcFormat == GL_BGR_INTEGER_EXT || @@ -3679,13 +4547,16 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, srcType == GL_UNSIGNED_INT_8_8_8_8 || srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV); + srcType == GL_UNSIGNED_INT_2_10_10_10_REV || + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); /* general solution, no special cases, yet */ { GLint dstComponents; GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); + GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat)); + GLboolean intFormat = _mesa_is_enum_format_integer(srcFormat); if (!rgba) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); @@ -3696,11 +4567,18 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, /* source & dest image formats should have been error checked by now */ assert(dstComponents > 0); + /* EXT_texture_integer specifies no transfer ops on integer + * types in the resolved issues section. Just set them to 0 + * for integer surfaces. + */ + if (intFormat) + transferOps = 0; + /* * Extract image data and convert to RGBA floats */ if (srcFormat == GL_COLOR_INDEX) { - GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); + GLuint *indexes = malloc(n * sizeof(GLuint)); if (!indexes) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); @@ -3711,24 +4589,11 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, extract_uint_indexes(n, indexes, srcFormat, srcType, source, srcPacking); - if (dstFormat == GL_COLOR_INDEX) { - GLuint i; - _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes); - /* convert to GLchan and return */ - for (i = 0; i < n; i++) { - dest[i] = (GLchan) (indexes[i] & 0xff); - } - free(indexes); - free(rgba); - return; - } - else { - /* Convert indexes to RGBA */ - if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { - _mesa_shift_and_offset_ci(ctx, n, indexes); - } - _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); - } + /* Convert indexes to RGBA */ + if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { + _mesa_shift_and_offset_ci(ctx, n, indexes); + } + _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting * with color indexes. @@ -3815,8 +4680,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx, /** - * Same as _mesa_unpack_color_span_chan(), but return GLuint data - * instead of GLchan. + * Same as _mesa_unpack_color_span_ubyte(), but return GLuint data + * instead of GLubyte. * No pixel transfer ops are applied. */ void @@ -3826,7 +4691,7 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking) { - GLuint (*rgba)[4] = (GLuint (*)[4]) malloc(n * 4 * sizeof(GLfloat)); + GLuint (*rgba)[4] = malloc(n * 4 * sizeof(GLfloat)); if (!rgba) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); @@ -3859,6 +4724,7 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx, srcFormat == GL_GREEN_INTEGER_EXT || srcFormat == GL_BLUE_INTEGER_EXT || srcFormat == GL_ALPHA_INTEGER_EXT || + srcFormat == GL_RG_INTEGER || srcFormat == GL_RGB_INTEGER_EXT || srcFormat == GL_RGBA_INTEGER_EXT || srcFormat == GL_BGR_INTEGER_EXT || @@ -3885,7 +4751,9 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx, srcType == GL_UNSIGNED_INT_8_8_8_8 || srcType == GL_UNSIGNED_INT_8_8_8_8_REV || srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV); + srcType == GL_UNSIGNED_INT_2_10_10_10_REV || + srcType == GL_UNSIGNED_INT_5_9_9_9_REV || + srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); /* Extract image data as uint[4] pixels */ @@ -3984,7 +4852,8 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx, GLbitfield transferOps ) { ASSERT(dstFormat == GL_DUDV_ATI); - ASSERT(srcFormat == GL_DUDV_ATI); + ASSERT(srcFormat == GL_DUDV_ATI || + srcFormat == GL_DU8DV8_ATI); ASSERT(srcType == GL_UNSIGNED_BYTE || srcType == GL_BYTE || @@ -4000,7 +4869,7 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx, GLint dstComponents; GLbyte *dst = dest; GLuint i; - GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); + GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat)); if (!rgba) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); @@ -4087,7 +4956,7 @@ _mesa_unpack_index_span( struct gl_context *ctx, GLuint n, /* * general solution */ - GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); + GLuint *indexes = malloc(n * sizeof(GLuint)); if (!indexes) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); @@ -4138,7 +5007,7 @@ _mesa_pack_index_span( struct gl_context *ctx, GLuint n, const struct gl_pixelstore_attrib *dstPacking, GLbitfield transferOps ) { - GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); + GLuint *indexes = malloc(n * sizeof(GLuint)); if (!indexes) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); @@ -4283,11 +5152,13 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n, srcType == GL_INT || srcType == GL_UNSIGNED_INT_24_8_EXT || srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT); + srcType == GL_FLOAT || + srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); ASSERT(dstType == GL_UNSIGNED_BYTE || dstType == GL_UNSIGNED_SHORT || - dstType == GL_UNSIGNED_INT); + dstType == GL_UNSIGNED_INT || + dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); /* only shift and offset apply to stencil */ transferOps &= IMAGE_SHIFT_OFFSET_BIT; @@ -4312,7 +5183,7 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n, /* * general solution */ - GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint)); + GLuint *indexes = malloc(n * sizeof(GLuint)); if (!indexes) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil unpacking"); @@ -4359,6 +5230,15 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n, case GL_UNSIGNED_INT: memcpy(dest, indexes, n * sizeof(GLuint)); break; + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + { + GLuint *dst = (GLuint *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i*2+1] = indexes[i] & 0xff; /* lower 8 bits */ + } + } + break; default: _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span"); } @@ -4370,10 +5250,10 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n, void _mesa_pack_stencil_span( struct gl_context *ctx, GLuint n, - GLenum dstType, GLvoid *dest, const GLstencil *source, + GLenum dstType, GLvoid *dest, const GLubyte *source, const struct gl_pixelstore_attrib *dstPacking ) { - GLstencil *stencil = (GLstencil *) malloc(n * sizeof(GLstencil)); + GLubyte *stencil = malloc(n * sizeof(GLubyte)); if (!stencil) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil packing"); @@ -4383,23 +5263,14 @@ _mesa_pack_stencil_span( struct gl_context *ctx, GLuint n, if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag) { /* make a copy of input */ - memcpy(stencil, source, n * sizeof(GLstencil)); + memcpy(stencil, source, n * sizeof(GLubyte)); _mesa_apply_stencil_transfer_ops(ctx, n, stencil); source = stencil; } switch (dstType) { case GL_UNSIGNED_BYTE: - if (sizeof(GLstencil) == 1) { - memcpy( dest, source, n ); - } - else { - GLubyte *dst = (GLubyte *) dest; - GLuint i; - for (i=0;iSwapBytes) { + SWAP4BYTE(value); + } + depthValues[i] = value; + } + needClamp = GL_TRUE; + } + break; case GL_FLOAT: DEPTH_VALUES(GLfloat, 1*); needClamp = GL_TRUE; @@ -4728,7 +5614,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, else { /* need to use double precision to prevent overflow problems */ for (i = 0; i < n; i++) { - GLdouble z = depthValues[i] * (GLfloat) depthMax; + GLdouble z = depthValues[i] * (GLdouble) depthMax; if (z >= (GLdouble) 0xffffffff) zValues[i] = 0xffffffff; else @@ -4744,9 +5630,18 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, zValues[i] = (GLushort) (depthValues[i] * (GLfloat) depthMax); } } + else if (dstType == GL_FLOAT) { + /* Nothing to do. depthValues is pointing to dest. */ + } + else if (dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) { + GLfloat *zValues = (GLfloat*) dest; + GLuint i; + for (i = 0; i < n; i++) { + zValues[i*2] = depthValues[i]; + } + } else { - ASSERT(dstType == GL_FLOAT); - /*ASSERT(depthMax == 1.0F);*/ + ASSERT(0); } free(depthTemp); @@ -4761,7 +5656,7 @@ _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest, GLenum dstType, const GLfloat *depthSpan, const struct gl_pixelstore_attrib *dstPacking ) { - GLfloat *depthCopy = (GLfloat *) malloc(n * sizeof(GLfloat)); + GLfloat *depthCopy = malloc(n * sizeof(GLfloat)); if (!depthCopy) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); return; @@ -4874,16 +5769,17 @@ _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest, /** - * Pack depth and stencil values as GL_DEPTH_STENCIL/GL_UNSIGNED_INT_24_8. + * Pack depth and stencil values as GL_DEPTH_STENCIL (GL_UNSIGNED_INT_24_8 etc) */ void -_mesa_pack_depth_stencil_span(struct gl_context *ctx, GLuint n, GLuint *dest, +_mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n, + GLenum dstType, GLuint *dest, const GLfloat *depthVals, - const GLstencil *stencilVals, + const GLubyte *stencilVals, const struct gl_pixelstore_attrib *dstPacking) { - GLfloat *depthCopy = (GLfloat *) malloc(n * sizeof(GLfloat)); - GLstencil *stencilCopy = (GLstencil *) malloc(n * sizeof(GLstencil)); + GLfloat *depthCopy = malloc(n * sizeof(GLfloat)); + GLubyte *stencilCopy = malloc(n * sizeof(GLubyte)); GLuint i; if (!depthCopy || !stencilCopy) { @@ -4902,14 +5798,24 @@ _mesa_pack_depth_stencil_span(struct gl_context *ctx, GLuint n, GLuint *dest, if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag) { - memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil)); + memcpy(stencilCopy, stencilVals, n * sizeof(GLubyte)); _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy); stencilVals = stencilCopy; } - for (i = 0; i < n; i++) { - GLuint z = (GLuint) (depthVals[i] * 0xffffff); - dest[i] = (z << 8) | (stencilVals[i] & 0xff); + switch (dstType) { + case GL_UNSIGNED_INT_24_8: + for (i = 0; i < n; i++) { + GLuint z = (GLuint) (depthVals[i] * 0xffffff); + dest[i] = (z << 8) | (stencilVals[i] & 0xff); + } + break; + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + for (i = 0; i < n; i++) { + ((GLfloat*)dest)[i*2] = depthVals[i]; + dest[i*2+1] = stencilVals[i] & 0xff; + } + break; } if (dstPacking->SwapBytes) { @@ -4971,7 +5877,7 @@ _mesa_unpack_image( GLuint dimensions, { GLubyte *destBuffer - = (GLubyte *) malloc(bytesPerRow * height * depth); + = malloc(bytesPerRow * height * depth); GLubyte *dst; GLint img, row; if (!destBuffer) @@ -5062,3 +5968,94 @@ _mesa_unpack_image( GLuint dimensions, } } + + +/** + * If we unpack colors from a luminance surface, we'll get pixel colors + * such as (l, l, l, a). + * When we call _mesa_pack_rgba_span_float(format=GL_LUMINANCE), that + * function will compute L=R+G+B before packing. The net effect is we'll + * accidentally store luminance values = 3*l. + * This function compensates for that by converting (aka rebasing) (l,l,l,a) + * to be (l,0,0,a). + * It's a similar story for other formats such as LUMINANCE_ALPHA, ALPHA + * and INTENSITY. + * + * Finally, we also need to do this when the actual surface format does + * not match the logical surface format. For example, suppose the user + * requests a GL_LUMINANCE texture but the driver stores it as RGBA. + * Again, we'll get pixel values like (l,l,l,a). + */ +void +_mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat) +{ + GLuint i; + + switch (baseFormat) { + case GL_ALPHA: + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = 0.0F; + rgba[i][GCOMP] = 0.0F; + rgba[i][BCOMP] = 0.0F; + } + break; + case GL_INTENSITY: + /* fall-through */ + case GL_LUMINANCE: + for (i = 0; i < n; i++) { + rgba[i][GCOMP] = 0.0F; + rgba[i][BCOMP] = 0.0F; + rgba[i][ACOMP] = 1.0F; + } + break; + case GL_LUMINANCE_ALPHA: + for (i = 0; i < n; i++) { + rgba[i][GCOMP] = 0.0F; + rgba[i][BCOMP] = 0.0F; + } + break; + default: + /* no-op */ + ; + } +} + + +/** + * As above, but GLuint components. + */ +void +_mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat) +{ + GLuint i; + + switch (baseFormat) { + case GL_ALPHA: + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = 0; + rgba[i][GCOMP] = 0; + rgba[i][BCOMP] = 0; + } + break; + case GL_INTENSITY: + /* fall-through */ + case GL_LUMINANCE: + for (i = 0; i < n; i++) { + rgba[i][GCOMP] = 0; + rgba[i][BCOMP] = 0; + rgba[i][ACOMP] = 1; + } + break; + case GL_LUMINANCE_ALPHA: + for (i = 0; i < n; i++) { + rgba[i][GCOMP] = 0; + rgba[i][BCOMP] = 0; + } + break; + default: + /* no-op */ + ; + } +} + +