diff options
Diffstat (limited to 'mesalib/src/mesa/main/texstore.c')
-rw-r--r-- | mesalib/src/mesa/main/texstore.c | 2827 |
1 files changed, 399 insertions, 2428 deletions
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index aea53f8d1..0e036d9eb 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -55,6 +55,7 @@ #include "bufferobj.h" #include "colormac.h" #include "format_pack.h" +#include "format_utils.h" #include "image.h" #include "macros.h" #include "mipmap.h" @@ -87,35 +88,6 @@ enum { typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS); -/** - * Return GL_TRUE if the given image format is one that be converted - * to another format by swizzling. - */ -static GLboolean -can_swizzle(GLenum logicalBaseFormat) -{ - switch (logicalBaseFormat) { - case GL_RGBA: - case GL_RGB: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_BGR: - case GL_BGRA: - case GL_ABGR_EXT: - case GL_RG: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - - enum { IDX_LUMINANCE = 0, IDX_ALPHA, @@ -233,21 +205,44 @@ static int get_map_idx(GLenum value) { switch (value) { - case GL_LUMINANCE: return IDX_LUMINANCE; - case GL_ALPHA: return IDX_ALPHA; - case GL_INTENSITY: return IDX_INTENSITY; - case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA; - case GL_RGB: return IDX_RGB; - case GL_RGBA: return IDX_RGBA; - case GL_RED: return IDX_RED; - case GL_GREEN: return IDX_GREEN; - case GL_BLUE: return IDX_BLUE; - case GL_BGR: return IDX_BGR; - case GL_BGRA: return IDX_BGRA; - case GL_ABGR_EXT: return IDX_ABGR; - case GL_RG: return IDX_RG; + case GL_LUMINANCE: + case GL_LUMINANCE_INTEGER_EXT: + return IDX_LUMINANCE; + case GL_ALPHA: + case GL_ALPHA_INTEGER: + return IDX_ALPHA; + case GL_INTENSITY: + return IDX_INTENSITY; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA_INTEGER_EXT: + return IDX_LUMINANCE_ALPHA; + case GL_RGB: + case GL_RGB_INTEGER: + return IDX_RGB; + case GL_RGBA: + case GL_RGBA_INTEGER: + return IDX_RGBA; + case GL_RED: + case GL_RED_INTEGER: + return IDX_RED; + case GL_GREEN: + return IDX_GREEN; + case GL_BLUE: + return IDX_BLUE; + case GL_BGR: + case GL_BGR_INTEGER: + return IDX_BGR; + case GL_BGRA: + case GL_BGRA_INTEGER: + return IDX_BGRA; + case GL_ABGR_EXT: + return IDX_ABGR; + case GL_RG: + case GL_RG_INTEGER: + return IDX_RG; default: - _mesa_problem(NULL, "Unexpected inFormat"); + _mesa_problem(NULL, "Unexpected inFormat %s", + _mesa_lookup_enum_by_nr(value)); return 0; } } @@ -662,257 +657,9 @@ _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims, } -/** - * Copy GLubyte pixels from <src> to <dst> with swizzling. - * \param dst destination pixels - * \param dstComponents number of color components in destination pixels - * \param src source pixels - * \param srcComponents number of color components in source pixels - * \param map the swizzle mapping. map[X] says where to find the X component - * in the source image's pixels. For example, if the source image - * is GL_BGRA and X = red, map[0] yields 2. - * \param count number of pixels to copy/swizzle. - */ -static void -swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src, - GLuint srcComponents, const GLubyte *map, GLuint count) -{ -#define SWZ_CPY(dst, src, count, dstComps, srcComps) \ - do { \ - GLuint i; \ - for (i = 0; i < count; i++) { \ - GLuint j; \ - if (srcComps == 4) { \ - COPY_4UBV(tmp, src); \ - } \ - else { \ - for (j = 0; j < srcComps; j++) { \ - tmp[j] = src[j]; \ - } \ - } \ - src += srcComps; \ - for (j = 0; j < dstComps; j++) { \ - dst[j] = tmp[map[j]]; \ - } \ - dst += dstComps; \ - } \ - } while (0) - - GLubyte tmp[6]; - - tmp[ZERO] = 0x0; - tmp[ONE] = 0xff; - - ASSERT(srcComponents <= 4); - ASSERT(dstComponents <= 4); - - switch (dstComponents) { - case 4: - switch (srcComponents) { - case 4: - SWZ_CPY(dst, src, count, 4, 4); - break; - case 3: - SWZ_CPY(dst, src, count, 4, 3); - break; - case 2: - SWZ_CPY(dst, src, count, 4, 2); - break; - case 1: - SWZ_CPY(dst, src, count, 4, 1); - break; - default: - ; - } - break; - case 3: - switch (srcComponents) { - case 4: - SWZ_CPY(dst, src, count, 3, 4); - break; - case 3: - SWZ_CPY(dst, src, count, 3, 3); - break; - case 2: - SWZ_CPY(dst, src, count, 3, 2); - break; - case 1: - SWZ_CPY(dst, src, count, 3, 1); - break; - default: - ; - } - break; - case 2: - switch (srcComponents) { - case 4: - SWZ_CPY(dst, src, count, 2, 4); - break; - case 3: - SWZ_CPY(dst, src, count, 2, 3); - break; - case 2: - SWZ_CPY(dst, src, count, 2, 2); - break; - case 1: - SWZ_CPY(dst, src, count, 2, 1); - break; - default: - ; - } - break; - case 1: - switch (srcComponents) { - case 4: - SWZ_CPY(dst, src, count, 1, 4); - break; - case 3: - SWZ_CPY(dst, src, count, 1, 3); - break; - case 2: - SWZ_CPY(dst, src, count, 1, 2); - break; - case 1: - SWZ_CPY(dst, src, count, 1, 1); - break; - default: - ; - } - break; - default: - ; - } -#undef SWZ_CPY -} - - - static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE }; static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE }; - - -/** - * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a - * mapping array depending on endianness. - */ -static const GLubyte * -type_mapping( GLenum srcType ) -{ - switch (srcType) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return map_identity; - case GL_UNSIGNED_INT_8_8_8_8: - return _mesa_little_endian() ? map_3210 : map_identity; - case GL_UNSIGNED_INT_8_8_8_8_REV: - return _mesa_little_endian() ? map_identity : map_3210; - default: - return NULL; - } -} - - -/** - * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a - * mapping array depending on pixelstore byte swapping state. - */ -static const GLubyte * -byteswap_mapping( GLboolean swapBytes, - GLenum srcType ) -{ - if (!swapBytes) - return map_identity; - - switch (srcType) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return map_identity; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - return map_3210; - default: - return NULL; - } -} - - - -/** - * Transfer a GLubyte texture image with component swizzling. - */ -static void -_mesa_swizzle_ubyte_image(struct gl_context *ctx, - GLuint dimensions, - GLenum srcFormat, - GLenum srcType, - - GLenum baseInternalFormat, - - const GLubyte *rgba2dst, - GLuint dstComponents, - - GLint dstRowStride, - GLubyte **dstSlices, - - GLint srcWidth, GLint srcHeight, GLint srcDepth, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking ) -{ - GLint srcComponents = _mesa_components_in_format(srcFormat); - const GLubyte *srctype2ubyte, *swap; - GLubyte map[4], src2base[6], base2rgba[6]; - GLint i; - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, - srcFormat, GL_UNSIGNED_BYTE); - const GLint srcImageStride - = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, - GL_UNSIGNED_BYTE); - const GLubyte *srcImage - = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr, - srcWidth, srcHeight, srcFormat, - GL_UNSIGNED_BYTE, 0, 0, 0); - - (void) ctx; - - /* Translate from src->baseInternal->GL_RGBA->dst. This will - * correctly deal with RGBA->RGB->RGBA conversions where the final - * A value must be 0xff regardless of the incoming alpha values. - */ - compute_component_mapping(srcFormat, baseInternalFormat, src2base); - compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba); - swap = byteswap_mapping(srcPacking->SwapBytes, srcType); - srctype2ubyte = type_mapping(srcType); - - - for (i = 0; i < 4; i++) - map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]]; - -/* printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */ - - if (srcComponents == dstComponents && - srcRowStride == dstRowStride && - srcRowStride == srcWidth * srcComponents && - dimensions < 3) { - /* 1 and 2D images only */ - GLubyte *dstImage = dstSlices[0]; - swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map, - srcWidth * srcHeight); - } - else { - GLint img, row; - for (img = 0; img < srcDepth; img++) { - const GLubyte *srcRow = srcImage; - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth); - dstRow += dstRowStride; - srcRow += srcRowStride; - } - srcImage += srcImageStride; - } - } -} +static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE }; /** @@ -988,6 +735,10 @@ store_ubyte_texture(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; + /* This way we will use the RGB versions of the packing functions and it + * will work for both RGB and sRGB textures*/ + dstFormat = _mesa_get_srgb_format_linear(dstFormat); + src = tempImage; for (img = 0; img < srcDepth; img++) { _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight, @@ -1178,845 +929,13 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS) dst += dstRowStride; src += srcRowStride; } + return GL_TRUE; + } else { + return GL_FALSE; } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -/** - * Store a texture in MESA_FORMAT_A8B8G8R8_UNORM or MESA_FORMAT_R8G8B8A8_UNORM. - */ -static GLboolean -_mesa_texstore_rgba8888(TEXSTORE_PARAMS) -{ - const GLboolean littleEndian = _mesa_little_endian(); - - ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_UNORM || - dstFormat == MESA_FORMAT_R8G8B8A8_UNORM || - dstFormat == MESA_FORMAT_X8B8G8R8_UNORM || - dstFormat == MESA_FORMAT_R8G8B8X8_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - if (!ctx->_ImageTransferState && - (srcType == GL_UNSIGNED_BYTE || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - if ((littleEndian && (dstFormat == MESA_FORMAT_A8B8G8R8_UNORM || - dstFormat == MESA_FORMAT_X8B8G8R8_UNORM)) || - (!littleEndian && (dstFormat == MESA_FORMAT_R8G8B8A8_UNORM || - dstFormat == MESA_FORMAT_R8G8B8X8_UNORM))) { - dstmap[3] = 0; - dstmap[2] = 1; - dstmap[1] = 2; - dstmap[0] = 3; - } - else { - dstmap[3] = 3; - dstmap[2] = 2; - dstmap[1] = 1; - dstmap[0] = 0; - } - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 4, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_argb8888(TEXSTORE_PARAMS) -{ - const GLboolean littleEndian = _mesa_little_endian(); - - ASSERT(dstFormat == MESA_FORMAT_B8G8R8A8_UNORM || - dstFormat == MESA_FORMAT_A8R8G8B8_UNORM || - dstFormat == MESA_FORMAT_B8G8R8X8_UNORM || - dstFormat == MESA_FORMAT_X8R8G8B8_UNORM ); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - (dstFormat == MESA_FORMAT_B8G8R8A8_UNORM || - dstFormat == MESA_FORMAT_B8G8R8X8_UNORM) && - srcFormat == GL_RGB && - (baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB) && - srcType == GL_UNSIGNED_BYTE) { - int img, row, col; - for (img = 0; img < srcDepth; img++) { - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *d4 = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - d4[col] = PACK_COLOR_8888(0xff, - srcRow[col * 3 + RCOMP], - srcRow[col * 3 + GCOMP], - srcRow[col * 3 + BCOMP]); - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_B8G8R8A8_UNORM && - srcFormat == GL_LUMINANCE_ALPHA && - baseInternalFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { - /* special case of storing LA -> ARGB8888 */ - int img, row, col; - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - for (img = 0; img < srcDepth; img++) { - const GLubyte *srcRow = (const GLubyte *) - _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, - srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *d4 = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1]; - d4[col] = PACK_COLOR_8888(a, l, l, l); - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_B8G8R8A8_UNORM && - srcFormat == GL_RGBA && - baseInternalFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { - /* same as above case, but src data has alpha too */ - GLint img, row, col; - /* For some reason, streaming copies to write-combined regions - * are extremely sensitive to the characteristics of how the - * source data is retrieved. By reordering the source reads to - * be in-order, the speed of this operation increases by half. - * Strangely the same isn't required for the RGB path, above. - */ - for (img = 0; img < srcDepth; img++) { - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *d4 = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP], - srcRow[col * 4 + RCOMP], - srcRow[col * 4 + GCOMP], - srcRow[col * 4 + BCOMP]); - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - (srcType == GL_UNSIGNED_BYTE || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - if ((littleEndian && dstFormat == MESA_FORMAT_B8G8R8A8_UNORM) || - (littleEndian && dstFormat == MESA_FORMAT_B8G8R8X8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_A8R8G8B8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_X8R8G8B8_UNORM)) { - dstmap[3] = 3; /* alpha */ - dstmap[2] = 0; /* red */ - dstmap[1] = 1; /* green */ - dstmap[0] = 2; /* blue */ - } - else { - assert((littleEndian && dstFormat == MESA_FORMAT_A8R8G8B8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_B8G8R8A8_UNORM) || - (littleEndian && dstFormat == MESA_FORMAT_X8R8G8B8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_B8G8R8X8_UNORM)); - dstmap[3] = 2; - dstmap[2] = 1; - dstmap[1] = 0; - dstmap[0] = 3; - } - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 4, - dstRowStride, - dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_rgb888(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_BGR_UNORM8); - ASSERT(_mesa_get_format_bytes(dstFormat) == 3); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { - /* extract RGB from RGBA */ - GLint img, row, col; - for (img = 0; img < srcDepth; img++) { - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP]; - dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP]; - dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP]; - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - dstmap[0] = 2; - dstmap[1] = 1; - dstmap[2] = 0; - dstmap[3] = ONE; /* ? */ - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 3, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_bgr888(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_RGB_UNORM8); - ASSERT(_mesa_get_format_bytes(dstFormat) == 3); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { - /* extract BGR from RGBA */ - int img, row, col; - for (img = 0; img < srcDepth; img++) { - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP]; - dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP]; - dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP]; - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - dstmap[0] = 0; - dstmap[1] = 1; - dstmap[2] = 2; - dstmap[3] = ONE; /* ? */ - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 3, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_argb2101010(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UNORM || - dstFormat == MESA_FORMAT_B10G10R10X2_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0 - * if the internal format is RGB. */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - GL_RGBA, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - if (baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB) { - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b); - src += 4; - } - dstRow += dstRowStride; - } - } else { - ASSERT(0); - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats. - */ -static GLboolean -_mesa_texstore_unorm44(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_L4A4_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 1); - - { - /* general path */ - const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLubyte *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLubyte *dstUS = (GLubyte *) dstRow; - for (col = 0; col < srcWidth; col++) { - /* src[0] is luminance, src[1] is alpha */ - dstUS[col] = PACK_COLOR_44( src[1], - src[0] ); - src += 2; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats. - */ -static GLboolean -_mesa_texstore_unorm88(TEXSTORE_PARAMS) -{ - const GLboolean littleEndian = _mesa_little_endian(); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_L8A8_UNORM || - dstFormat == MESA_FORMAT_A8L8_UNORM || - dstFormat == MESA_FORMAT_R8G8_UNORM || - dstFormat == MESA_FORMAT_G8R8_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - if (!ctx->_ImageTransferState && - littleEndian && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - if (dstFormat == MESA_FORMAT_L8A8_UNORM || dstFormat == MESA_FORMAT_A8L8_UNORM) { - if ((littleEndian && dstFormat == MESA_FORMAT_L8A8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_A8L8_UNORM)) { - dstmap[0] = 0; - dstmap[1] = 3; - } - else { - dstmap[0] = 3; - dstmap[1] = 0; - } - } - else { - if ((littleEndian && dstFormat == MESA_FORMAT_R8G8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_G8R8_UNORM)) { - dstmap[0] = 0; - dstmap[1] = 1; - } - else { - dstmap[0] = 1; - dstmap[1] = 0; - } - } - dstmap[2] = ZERO; /* ? */ - dstmap[3] = ONE; /* ? */ - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 2, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - /* general path */ - const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLubyte *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - if (dstFormat == MESA_FORMAT_L8A8_UNORM || - dstFormat == MESA_FORMAT_R8G8_UNORM) { - for (col = 0; col < srcWidth; col++) { - /* src[0] is luminance (or R), src[1] is alpha (or G) */ - dstUS[col] = PACK_COLOR_88( src[1], - src[0] ); - src += 2; - } - } - else { - for (col = 0; col < srcWidth; col++) { - /* src[0] is luminance (or R), src[1] is alpha (or G) */ - dstUS[col] = PACK_COLOR_88_REV( src[1], - src[0] ); - src += 2; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats. - */ -static GLboolean -_mesa_texstore_unorm1616(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_L16A16_UNORM || - dstFormat == MESA_FORMAT_A16L16_UNORM || - dstFormat == MESA_FORMAT_R16G16_UNORM || - dstFormat == MESA_FORMAT_G16R16_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - if (dstFormat == MESA_FORMAT_L16A16_UNORM || - dstFormat == MESA_FORMAT_R16G16_UNORM) { - for (col = 0; col < srcWidth; col++) { - GLushort l, a; - - UNCLAMPED_FLOAT_TO_USHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[1]); - dstUI[col] = PACK_COLOR_1616(a, l); - src += 2; - } - } - else { - for (col = 0; col < srcWidth; col++) { - GLushort l, a; - - UNCLAMPED_FLOAT_TO_USHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[1]); - dstUI[col] = PACK_COLOR_1616_REV(a, l); - src += 2; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* Texstore for R16, A16, L16, I16. */ -static GLboolean -_mesa_texstore_unorm16(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R_UNORM16 || - dstFormat == MESA_FORMAT_A_UNORM16 || - dstFormat == MESA_FORMAT_L_UNORM16 || - dstFormat == MESA_FORMAT_I_UNORM16); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort r; - - UNCLAMPED_FLOAT_TO_USHORT(r, src[0]); - dstUS[col] = r; - src += 1; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_rgba_16(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_RGBA_UNORM16 || - dstFormat == MESA_FORMAT_RGBX_UNORM16); - ASSERT(_mesa_get_format_bytes(dstFormat) == 8); - - { - /* general path */ - /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0 - * if the internal format is RGB. */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - GL_RGBA, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - - if (!tempImage) - return GL_FALSE; - - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort r, g, b, a; - - UNCLAMPED_FLOAT_TO_USHORT(r, src[0]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[1]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[2]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[3]); - dstUS[col*4+0] = r; - dstUS[col*4+1] = g; - dstUS[col*4+2] = b; - dstUS[col*4+3] = a; - src += 4; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_RGB_SNORM16 || - dstFormat == MESA_FORMAT_RGBA_SNORM16 || - dstFormat == MESA_FORMAT_RGBX_SNORM16); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2; - GLint img, row, col; - - if (!tempImage) - return GL_FALSE; - - /* Note: tempImage is always float[4] / RGBA. We convert to 1, 2, - * 3 or 4 components/pixel here. - */ - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLshort *dstRowS = (GLshort *) dstRow; - if (dstFormat == MESA_FORMAT_RGBA_SNORM16) { - for (col = 0; col < srcWidth; col++) { - GLuint c; - for (c = 0; c < comps; c++) { - GLshort p; - UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]); - dstRowS[col * comps + c] = p; - } - } - dstRow += dstRowStride; - src += 4 * srcWidth; - } - else if (dstFormat == MESA_FORMAT_RGBX_SNORM16) { - for (col = 0; col < srcWidth; col++) { - GLuint c; - - for (c = 0; c < 3; c++) { - GLshort p; - UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]); - dstRowS[col * comps + c] = p; - } - dstRowS[col * comps + 3] = 32767; - } - dstRow += dstRowStride; - src += 3 * srcWidth; - } - else { - for (col = 0; col < srcWidth; col++) { - GLuint c; - for (c = 0; c < comps; c++) { - GLshort p; - UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]); - dstRowS[col * comps + c] = p; - } - } - dstRow += dstRowStride; - src += 3 * srcWidth; - } - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8. - */ -static GLboolean -_mesa_texstore_unorm8(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_A_UNORM8 || - dstFormat == MESA_FORMAT_L_UNORM8 || - dstFormat == MESA_FORMAT_I_UNORM8 || - dstFormat == MESA_FORMAT_R_UNORM8); - ASSERT(_mesa_get_format_bytes(dstFormat) == 1); - - if (!ctx->_ImageTransferState && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - if (dstFormat == MESA_FORMAT_A_UNORM8) { - dstmap[0] = 3; - } - else { - dstmap[0] = 0; - } - dstmap[1] = ZERO; /* ? */ - dstmap[2] = ZERO; /* ? */ - dstmap[3] = ONE; /* ? */ - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 1, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - /* general path */ - const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLubyte *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col] = src[col]; - } - dstRow += dstRowStride; - src += srcWidth; - } - } - free((void *) tempImage); - } - return GL_TRUE; } - /** * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. */ @@ -2063,330 +982,6 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS) /** - * Store a texture in a signed normalized 8-bit format. - */ -static GLboolean -_mesa_texstore_snorm8(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_A_SNORM8 || - dstFormat == MESA_FORMAT_L_SNORM8 || - dstFormat == MESA_FORMAT_I_SNORM8 || - dstFormat == MESA_FORMAT_R_SNORM8); - ASSERT(_mesa_get_format_bytes(dstFormat) == 1); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]); - } - dstRow += dstRowStride; - src += srcWidth; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Store a texture in a signed normalized two-channel 16-bit format. - */ -static GLboolean -_mesa_texstore_snorm88(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_L8A8_SNORM || - dstFormat == MESA_FORMAT_G8R8_SNORM || - dstFormat == MESA_FORMAT_R8G8_SNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dst = (GLushort *) dstRow; - - if (dstFormat == MESA_FORMAT_L8A8_SNORM || - dstFormat == MESA_FORMAT_R8G8_SNORM) { - for (col = 0; col < srcWidth; col++) { - GLubyte l = FLOAT_TO_BYTE_TEX(src[0]); - GLubyte a = FLOAT_TO_BYTE_TEX(src[1]); - - dst[col] = PACK_COLOR_88_REV(l, a); - src += 2; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLubyte l = FLOAT_TO_BYTE_TEX(src[0]); - GLubyte a = FLOAT_TO_BYTE_TEX(src[1]); - - dst[col] = PACK_COLOR_88(l, a); - src += 2; - } - } - - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -/* Texstore for signed R16, A16, L16, I16. */ -static GLboolean -_mesa_texstore_snorm16(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R_SNORM16 || - dstFormat == MESA_FORMAT_A_SNORM16 || - dstFormat == MESA_FORMAT_L_SNORM16 || - dstFormat == MESA_FORMAT_I_SNORM16); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLshort *dstUS = (GLshort *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort r; - - UNCLAMPED_FLOAT_TO_SHORT(r, src[0]); - dstUS[col] = r; - src += 1; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -/** - * Do texstore for 2-channel, 16-bit/channel, signed normalized formats. - */ -static GLboolean -_mesa_texstore_snorm1616(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_LA_SNORM16 || - dstFormat == MESA_FORMAT_G16R16_SNORM || - dstFormat == MESA_FORMAT_R16G16_SNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dst = (GLuint *) dstRow; - - if (dstFormat == MESA_FORMAT_LA_SNORM16 || - dstFormat == MESA_FORMAT_R16G16_SNORM) { - for (col = 0; col < srcWidth; col++) { - GLushort l, a; - - UNCLAMPED_FLOAT_TO_SHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_SHORT(a, src[1]); - dst[col] = PACK_COLOR_1616_REV(l, a); - src += 2; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLushort l, a; - - UNCLAMPED_FLOAT_TO_SHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_SHORT(a, src[1]); - dst[col] = PACK_COLOR_1616_REV(l, a); - src += 2; - } - } - - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -/** - * Store a texture in MESA_FORMAT_X8B8G8R8_SNORM or - * MESA_FORMAT_R8G8B8X8_SNORM. - */ -static GLboolean -_mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_X8B8G8R8_SNORM || - dstFormat == MESA_FORMAT_R8G8B8X8_SNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLbyte *dst = dstRow; - if (dstFormat == MESA_FORMAT_X8B8G8R8_SNORM) { - for (col = 0; col < srcWidth; col++) { - dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); - dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); - dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); - dst[0] = 127; - srcRow += 3; - dst += 4; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); - dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); - dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); - dst[3] = 127; - srcRow += 3; - dst += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - - -/** - * Store a texture in MESA_FORMAT_A8B8G8R8_SNORM or - * MESA_FORMAT_R8G8B8A8_SNORM - */ -static GLboolean -_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_SNORM || - dstFormat == MESA_FORMAT_R8G8B8A8_SNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLbyte *dst = dstRow; - if (dstFormat == MESA_FORMAT_A8B8G8R8_SNORM) { - for (col = 0; col < srcWidth; col++) { - dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); - dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); - dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); - dst[0] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]); - srcRow += 4; - dst += 4; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); - dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); - dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); - dst[3] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]); - srcRow += 4; - dst += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** * Store a combined depth/stencil texture image. */ static GLboolean @@ -2599,742 +1194,6 @@ _mesa_texstore_s8(TEXSTORE_PARAMS) } -/** - * Store an image in any of the formats: - * _mesa_texformat_rgba_float32 - * _mesa_texformat_rgb_float32 - * _mesa_texformat_alpha_float32 - * _mesa_texformat_luminance_float32 - * _mesa_texformat_luminance_alpha_float32 - * _mesa_texformat_intensity_float32 - */ -static GLboolean -_mesa_texstore_rgba_float32(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in _mesa_make_temp_float_image */ - if (dstFormat == MESA_FORMAT_RGBX_FLOAT32) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 || - dstFormat == MESA_FORMAT_RGB_FLOAT32 || - dstFormat == MESA_FORMAT_A_FLOAT32 || - dstFormat == MESA_FORMAT_L_FLOAT32 || - dstFormat == MESA_FORMAT_LA_FLOAT32 || - dstFormat == MESA_FORMAT_I_FLOAT32 || - dstFormat == MESA_FORMAT_R_FLOAT32 || - dstFormat == MESA_FORMAT_RG_FLOAT32 || - dstFormat == MESA_FORMAT_RGBX_FLOAT32); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_RG); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat)); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint bytesPerRow; - GLint img, row; - if (!tempImage) - return GL_FALSE; - bytesPerRow = srcWidth * components * sizeof(GLfloat); - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - memcpy(dstRow, srcRow, bytesPerRow); - dstRow += dstRowStride; - srcRow += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - - -/** - * As above, but store 16-bit floats. - */ -static GLboolean -_mesa_texstore_rgba_float16(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in _mesa_make_temp_float_image */ - if (dstFormat == MESA_FORMAT_RGBX_FLOAT16) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 || - dstFormat == MESA_FORMAT_RGB_FLOAT16 || - dstFormat == MESA_FORMAT_A_FLOAT16 || - dstFormat == MESA_FORMAT_L_FLOAT16 || - dstFormat == MESA_FORMAT_LA_FLOAT16 || - dstFormat == MESA_FORMAT_I_FLOAT16 || - dstFormat == MESA_FORMAT_R_FLOAT16 || - dstFormat == MESA_FORMAT_RG_FLOAT16 || - dstFormat == MESA_FORMAT_RGBX_FLOAT16); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_RG); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB)); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLhalfARB *dstTexel = (GLhalfARB *) dstRow; - GLint i; - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = _mesa_float_to_half(src[i]); - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, signed int8 */ -static GLboolean -_mesa_texstore_rgba_int8(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_SINT8) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_SINT8 || - dstFormat == MESA_FORMAT_RG_SINT8 || - dstFormat == MESA_FORMAT_RGB_SINT8 || - dstFormat == MESA_FORMAT_RGBA_SINT8 || - dstFormat == MESA_FORMAT_A_SINT8 || - dstFormat == MESA_FORMAT_I_SINT8 || - dstFormat == MESA_FORMAT_L_SINT8 || - dstFormat == MESA_FORMAT_LA_SINT8 || - dstFormat == MESA_FORMAT_RGBX_SINT8); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte)); - - { - /* general path */ - 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; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLbyte *dstTexel = (GLbyte *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, signed int16 */ -static GLboolean -_mesa_texstore_rgba_int16(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_SINT16) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_SINT16 || - dstFormat == MESA_FORMAT_RG_SINT16 || - dstFormat == MESA_FORMAT_RGB_SINT16 || - dstFormat == MESA_FORMAT_RGBA_SINT16 || - dstFormat == MESA_FORMAT_A_SINT16 || - dstFormat == MESA_FORMAT_L_SINT16 || - dstFormat == MESA_FORMAT_I_SINT16 || - dstFormat == MESA_FORMAT_LA_SINT16 || - dstFormat == MESA_FORMAT_RGBX_SINT16); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort)); - - { - /* general path */ - 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; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLshort *dstTexel = (GLshort *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, signed int32 */ -static GLboolean -_mesa_texstore_rgba_int32(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_SINT32) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_SINT32 || - dstFormat == MESA_FORMAT_RG_SINT32 || - dstFormat == MESA_FORMAT_RGB_SINT32 || - dstFormat == MESA_FORMAT_RGBA_SINT32 || - dstFormat == MESA_FORMAT_A_SINT32 || - dstFormat == MESA_FORMAT_I_SINT32 || - dstFormat == MESA_FORMAT_L_SINT32 || - dstFormat == MESA_FORMAT_LA_SINT32 || - dstFormat == MESA_FORMAT_RGBX_SINT32); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint)); - - { - /* general path */ - 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; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLint *dstTexel = (GLint *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLint) src[i]; - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, unsigned int8 */ -static GLboolean -_mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_UINT8) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_UINT8 || - dstFormat == MESA_FORMAT_RG_UINT8 || - dstFormat == MESA_FORMAT_RGB_UINT8 || - dstFormat == MESA_FORMAT_RGBA_UINT8 || - dstFormat == MESA_FORMAT_A_UINT8 || - dstFormat == MESA_FORMAT_I_UINT8 || - dstFormat == MESA_FORMAT_L_UINT8 || - dstFormat == MESA_FORMAT_LA_UINT8 || - dstFormat == MESA_FORMAT_RGBX_UINT8); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte)); - - { - /* general path */ - 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; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLubyte *dstTexel = (GLubyte *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLubyte) MIN2(src[i], 0xff); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, unsigned int16 */ -static GLboolean -_mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_UINT16) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_UINT16 || - dstFormat == MESA_FORMAT_RG_UINT16 || - dstFormat == MESA_FORMAT_RGB_UINT16 || - dstFormat == MESA_FORMAT_RGBA_UINT16 || - dstFormat == MESA_FORMAT_A_UINT16 || - dstFormat == MESA_FORMAT_I_UINT16 || - dstFormat == MESA_FORMAT_L_UINT16 || - dstFormat == MESA_FORMAT_LA_UINT16 || - dstFormat == MESA_FORMAT_RGBX_UINT16); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort)); - - { - /* general path */ - 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; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dstTexel = (GLushort *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLushort) MIN2(src[i], 0xffff); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, unsigned int32 */ -static GLboolean -_mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_UINT32) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_UINT32 || - dstFormat == MESA_FORMAT_RG_UINT32 || - dstFormat == MESA_FORMAT_RGB_UINT32 || - dstFormat == MESA_FORMAT_RGBA_UINT32 || - dstFormat == MESA_FORMAT_A_UINT32 || - dstFormat == MESA_FORMAT_I_UINT32 || - dstFormat == MESA_FORMAT_L_UINT32 || - dstFormat == MESA_FORMAT_LA_UINT32 || - dstFormat == MESA_FORMAT_RGBX_UINT32); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint)); - - { - /* general path */ - const GLuint *tempImage = - make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - const GLuint *src = tempImage; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - GLint img, row; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dstTexel = (GLuint *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = src[i]; - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = MAX2((GLint) src[i], 0); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_srgb8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_BGR_SRGB8); - - /* reuse normal rgb texstore code */ - newDstFormat = MESA_FORMAT_BGR_UNORM8; - - k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - - -static GLboolean -_mesa_texstore_srgba8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_SRGB || - dstFormat == MESA_FORMAT_R8G8B8X8_SRGB || - dstFormat == MESA_FORMAT_R8G8B8A8_SRGB); - - newDstFormat = _mesa_get_srgb_format_linear(dstFormat); - - k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - - -static GLboolean -_mesa_texstore_sargb8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - assert(dstFormat == MESA_FORMAT_B8G8R8A8_SRGB || - dstFormat == MESA_FORMAT_B8G8R8X8_SRGB); - - newDstFormat = _mesa_get_srgb_format_linear(dstFormat); - - k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - - -static GLboolean -_mesa_texstore_sl8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_L_SRGB8); - - newDstFormat = MESA_FORMAT_L_UNORM8; - - /* _mesa_textore_a8 handles luminance8 too */ - k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - - -static GLboolean -_mesa_texstore_sla8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_L8A8_SRGB); - - /* reuse normal luminance/alpha texstore code */ - newDstFormat = MESA_FORMAT_L8A8_UNORM; - - k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - -static GLboolean -_mesa_texstore_rgb9_e5(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R9G9B9E5_FLOAT); - ASSERT(baseInternalFormat == GL_RGB); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint*)dstRow; - for (col = 0; col < srcWidth; col++) { - dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]); - } - dstRow += dstRowStride; - srcRow += srcWidth * 3; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R11G11B10_FLOAT); - ASSERT(baseInternalFormat == GL_RGB); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint*)dstRow; - for (col = 0; col < srcWidth; col++) { - dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]); - } - dstRow += dstRowStride; - srcRow += srcWidth * 3; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - static GLboolean _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) { @@ -3496,118 +1355,16 @@ _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) return GL_TRUE; } -static GLboolean -_mesa_texstore_abgr2101010(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - dstUI[col] = PACK_COLOR_2101010_US(a, b, g, r); - src += 4; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} static GLboolean -_mesa_texstore_null(TEXSTORE_PARAMS) -{ - (void) ctx; (void) dims; - (void) baseInternalFormat; - (void) dstFormat; - (void) dstRowStride; (void) dstSlices, - (void) srcWidth; (void) srcHeight; (void) srcDepth; - (void) srcFormat; (void) srcType; - (void) srcAddr; - (void) srcPacking; - - /* should never happen */ - _mesa_problem(NULL, "_mesa_texstore_null() is called"); - return GL_FALSE; -} - - -/** - * Return the StoreTexImageFunc pointer to store an image in the given format. - */ -static StoreTexImageFunc -_mesa_get_texstore_func(mesa_format format) +texstore_depth_stencil(TEXSTORE_PARAMS) { static StoreTexImageFunc table[MESA_FORMAT_COUNT]; static GLboolean initialized = GL_FALSE; if (!initialized) { - table[MESA_FORMAT_NONE] = _mesa_texstore_null; - - table[MESA_FORMAT_A8B8G8R8_UNORM] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_R8G8B8A8_UNORM] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_B8G8R8A8_UNORM] = _mesa_texstore_argb8888; - table[MESA_FORMAT_A8R8G8B8_UNORM] = _mesa_texstore_argb8888; - table[MESA_FORMAT_X8B8G8R8_UNORM] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_R8G8B8X8_UNORM] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_B8G8R8X8_UNORM] = _mesa_texstore_argb8888; - table[MESA_FORMAT_X8R8G8B8_UNORM] = _mesa_texstore_argb8888; - table[MESA_FORMAT_BGR_UNORM8] = _mesa_texstore_rgb888; - table[MESA_FORMAT_RGB_UNORM8] = _mesa_texstore_bgr888; - table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565; - table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565; - table[MESA_FORMAT_B4G4R4A4_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_A4R4G4B4_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_A1B5G5R5_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_B5G5R5A1_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_A1R5G5B5_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_L4A4_UNORM] = _mesa_texstore_unorm44; - table[MESA_FORMAT_L8A8_UNORM] = _mesa_texstore_unorm88; - table[MESA_FORMAT_A8L8_UNORM] = _mesa_texstore_unorm88; - table[MESA_FORMAT_L16A16_UNORM] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_A16L16_UNORM] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_B2G3R3_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_A_UNORM8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_A_UNORM16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_L_UNORM8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_L_UNORM16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_I_UNORM8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_I_UNORM16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr; - table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr; - table[MESA_FORMAT_R_UNORM8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_R8G8_UNORM] = _mesa_texstore_unorm88; - table[MESA_FORMAT_G8R8_UNORM] = _mesa_texstore_unorm88; - table[MESA_FORMAT_R_UNORM16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_R16G16_UNORM] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_G16R16_UNORM] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_B10G10R10A2_UNORM] = _mesa_texstore_argb2101010; + memset(table, 0, sizeof table); + table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8; table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24; table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16; @@ -3615,11 +1372,28 @@ _mesa_get_texstore_func(mesa_format format) table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8; table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32; table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8; - table[MESA_FORMAT_BGR_SRGB8] = _mesa_texstore_srgb8; - table[MESA_FORMAT_A8B8G8R8_SRGB] = _mesa_texstore_srgba8; - table[MESA_FORMAT_B8G8R8A8_SRGB] = _mesa_texstore_sargb8; - table[MESA_FORMAT_L_SRGB8] = _mesa_texstore_sl8; - table[MESA_FORMAT_L8A8_SRGB] = _mesa_texstore_sla8; + table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32; + table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8; + + initialized = GL_TRUE; + } + + ASSERT(table[dstFormat]); + return table[dstFormat](ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); +} + +static GLboolean +texstore_compressed(TEXSTORE_PARAMS) +{ + static StoreTexImageFunc table[MESA_FORMAT_COUNT]; + static GLboolean initialized = GL_FALSE; + + if (!initialized) { + memset(table, 0, sizeof table); + table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1; table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1; table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3; @@ -3630,32 +1404,6 @@ _mesa_get_texstore_func(mesa_format format) table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1; table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3; table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5; - table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_A_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_A_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_L_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_L_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_LA_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_LA_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_I_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_I_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_R_SNORM8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_R8G8_SNORM] = _mesa_texstore_snorm88; - table[MESA_FORMAT_X8B8G8R8_SNORM] = _mesa_texstore_signed_rgbx8888; - table[MESA_FORMAT_A8B8G8R8_SNORM] = _mesa_texstore_signed_rgba8888; - table[MESA_FORMAT_R8G8B8A8_SNORM] = _mesa_texstore_signed_rgba8888; - table[MESA_FORMAT_R_SNORM16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_R16G16_SNORM] = _mesa_texstore_snorm1616; - table[MESA_FORMAT_RGB_SNORM16] = _mesa_texstore_signed_rgba_16; - table[MESA_FORMAT_RGBA_SNORM16] = _mesa_texstore_signed_rgba_16; - table[MESA_FORMAT_RGBA_UNORM16] = _mesa_texstore_rgba_16; table[MESA_FORMAT_R_RGTC1_UNORM] = _mesa_texstore_red_rgtc1; table[MESA_FORMAT_R_RGTC1_SNORM] = _mesa_texstore_signed_red_rgtc1; table[MESA_FORMAT_RG_RGTC2_UNORM] = _mesa_texstore_rg_rgtc2; @@ -3677,107 +1425,327 @@ _mesa_get_texstore_func(mesa_format format) _mesa_texstore_etc2_rgb8_punchthrough_alpha1; table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] = _mesa_texstore_etc2_srgb8_punchthrough_alpha1; - table[MESA_FORMAT_A_SNORM8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_L_SNORM8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_L8A8_SNORM] = _mesa_texstore_snorm88; - table[MESA_FORMAT_I_SNORM8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_A_SNORM16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_L_SNORM16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_LA_SNORM16] = _mesa_texstore_snorm1616; - table[MESA_FORMAT_I_SNORM16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_R9G9B9E5_FLOAT] = _mesa_texstore_rgb9_e5; - table[MESA_FORMAT_R11G11B10_FLOAT] = _mesa_texstore_r11_g11_b10f; - table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32; - table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8; - table[MESA_FORMAT_A_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_A_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_A_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_A_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_A_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_A_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_I_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_I_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_I_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_I_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_I_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_I_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_L_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_L_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_L_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_L_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_L_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_L_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_LA_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_LA_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_LA_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_LA_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_LA_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_LA_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_R_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_RG_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_RGB_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_RGBA_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_R_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RG_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RGB_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RGBA_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_R_SINT32] = _mesa_texstore_rgba_int32; - table[MESA_FORMAT_RG_SINT32] = _mesa_texstore_rgba_int32; - table[MESA_FORMAT_RGB_SINT32] = _mesa_texstore_rgba_int32; - table[MESA_FORMAT_RGBA_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32; + initialized = GL_TRUE; + } + + ASSERT(table[dstFormat]); + return table[dstFormat](ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); +} + +static void +invert_swizzle(uint8_t dst[4], const uint8_t src[4]) +{ + int i, j; + + dst[0] = MESA_FORMAT_SWIZZLE_NONE; + dst[1] = MESA_FORMAT_SWIZZLE_NONE; + dst[2] = MESA_FORMAT_SWIZZLE_NONE; + dst[3] = MESA_FORMAT_SWIZZLE_NONE; + + for (i = 0; i < 4; ++i) + for (j = 0; j < 4; ++j) + if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE) + dst[i] = j; +} + +/** Store a texture by per-channel conversions and swizzling. + * + * This function attempts to perform a texstore operation by doing simple + * per-channel conversions and swizzling. This covers a huge chunk of the + * texture storage operations that anyone cares about. If this function is + * incapable of performing the operation, it bails and returns GL_FALSE. + */ +static GLboolean +texstore_swizzle(TEXSTORE_PARAMS) +{ + const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, + srcFormat, srcType); + const GLint srcImageStride = _mesa_image_image_stride(srcPacking, + srcWidth, srcHeight, srcFormat, srcType); + const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dims, + srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0); + const int src_components = _mesa_components_in_format(srcFormat); + + GLubyte swizzle[4], rgba2base[6], base2src[6], rgba2dst[4], dst2rgba[4]; + const GLubyte *swap; + GLenum dst_type; + int dst_components; + bool is_array, normalized, need_swap; + GLint i, img, row; + const GLubyte *src_row; + GLubyte *dst_row; + + is_array = _mesa_format_to_array(dstFormat, &dst_type, &dst_components, + rgba2dst, &normalized); + + if (!is_array) + return GL_FALSE; + + switch (srcType) { + case GL_FLOAT: + case GL_UNSIGNED_BYTE: + case GL_BYTE: + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_UNSIGNED_INT: + case GL_INT: + /* If wa have to swap bytes in a multi-byte datatype, that means + * we're not doing an array conversion anymore */ + if (srcPacking->SwapBytes) + return GL_FALSE; + need_swap = false; + break; + case GL_UNSIGNED_INT_8_8_8_8: + need_swap = srcPacking->SwapBytes; + if (_mesa_little_endian()) + need_swap = !need_swap; + srcType = GL_UNSIGNED_BYTE; + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + need_swap = srcPacking->SwapBytes; + if (!_mesa_little_endian()) + need_swap = !need_swap; + srcType = GL_UNSIGNED_BYTE; + break; + default: + return GL_FALSE; + } + swap = need_swap ? map_3210 : map_identity; + + compute_component_mapping(srcFormat, baseInternalFormat, base2src); + compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base); + invert_swizzle(dst2rgba, rgba2dst); + + for (i = 0; i < 4; i++) { + if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE) + swizzle[i] = MESA_FORMAT_SWIZZLE_NONE; + else + swizzle[i] = swap[base2src[rgba2base[dst2rgba[i]]]]; + } + + /* Is it normalized? */ + normalized |= !_mesa_is_enum_format_integer(srcFormat); + + for (img = 0; img < srcDepth; img++) { + if (dstRowStride == srcWidth * dst_components && + srcRowStride == srcWidth * src_components) { + _mesa_swizzle_and_convert(dstSlices[img], dst_type, dst_components, + srcImage, srcType, src_components, + swizzle, normalized, srcWidth * srcHeight); + } else { + src_row = srcImage; + dst_row = dstSlices[img]; + for (row = 0; row < srcHeight; row++) { + _mesa_swizzle_and_convert(dst_row, dst_type, dst_components, + src_row, srcType, src_components, + swizzle, normalized, srcWidth); + dst_row += dstRowStride; + src_row += srcRowStride; + } + } + srcImage += srcImageStride; + } + + return GL_TRUE; +} + + +/** Stores a texture by converting float and then to the texture format + * + * This function performs a texstore operation by converting to float, + * applying pixel transfer ops, and then converting to the texture's + * internal format using pixel store functions. This function will work + * for any rgb or srgb textore format. + */ +static GLboolean +texstore_via_float(TEXSTORE_PARAMS) +{ + GLuint i, img, row; + const GLint src_stride = + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); + float *tmp_row; + bool need_convert; + uint8_t *src_row, *dst_row, map[4], rgba2base[6], base2rgba[6]; + + tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row)); + if (!tmp_row) + return GL_FALSE; + + /* The GL spec (4.0, compatibility profile) only specifies srgb + * conversion as something that is done in the sampler during the + * filtering process before the colors are handed to the shader. + * Furthermore, the flowchart (Figure 3.7 in the 4.0 compatibility spec) + * does not list RGB <-> sRGB conversions anywhere. Therefore, we just + * treat sRGB formats the same as RGB formats for the purposes of + * texture upload and transfer ops. + */ + dstFormat = _mesa_get_srgb_format_linear(dstFormat); + + need_convert = false; + if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) { + compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba); + compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base); + for (i = 0; i < 4; ++i) { + map[i] = base2rgba[rgba2base[i]]; + if (map[i] != i) + need_convert = true; + } + } + + for (img = 0; img < srcDepth; img++) { + dst_row = dstSlices[img]; + src_row = _mesa_image_address(dims, srcPacking, srcAddr, + srcWidth, srcHeight, + srcFormat, srcType, + img, 0, 0); + for (row = 0; row < srcHeight; row++) { + _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, tmp_row, + srcFormat, srcType, src_row, + srcPacking, ctx->_ImageTransferState); + if (need_convert) + _mesa_swizzle_and_convert(tmp_row, GL_FLOAT, 4, + tmp_row, GL_FLOAT, 4, + map, false, srcWidth); + _mesa_pack_float_rgba_row(dstFormat, srcWidth, + (const GLfloat (*)[4])tmp_row, + dst_row); + dst_row += dstRowStride; + src_row += src_stride; + } + } + + return GL_TRUE; +} + +/** Stores an integer rgba texture + * + * This function performs an integer texture storage operation by unpacking + * the texture to 32-bit integers, and repacking it into the internal + * format of the texture. This will work for any integer rgb texture + * storage operation. + */ +static GLboolean +texstore_rgba_integer(TEXSTORE_PARAMS) +{ + GLuint i, img, row, *tmp_row; + GLenum dst_type, tmp_type; + const GLint src_stride = + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); + int num_dst_components; + bool is_array, normalized; + uint8_t *src_row, *dst_row; + uint8_t swizzle[4], rgba2base[6], base2rgba[6], rgba2dst[4], dst2rgba[4]; + + tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row)); + if (!tmp_row) + return GL_FALSE; + + is_array = _mesa_format_to_array(dstFormat, &dst_type, &num_dst_components, + rgba2dst, &normalized); + + assert(is_array && !normalized); + + if (!is_array) + return GL_FALSE; + + invert_swizzle(dst2rgba, rgba2dst); + compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba); + compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base); + + for (i = 0; i < 4; ++i) { + if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE) + swizzle[i] = MESA_FORMAT_SWIZZLE_NONE; + else + swizzle[i] = base2rgba[rgba2base[dst2rgba[i]]]; + } + + if (_mesa_is_type_unsigned(srcType)) { + tmp_type = GL_UNSIGNED_INT; + } else { + tmp_type = GL_INT; + } + + for (img = 0; img < srcDepth; img++) { + dst_row = dstSlices[img]; + src_row = _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, GL_RGBA, tmp_row, + srcFormat, srcType, src_row, srcPacking); + _mesa_swizzle_and_convert(dst_row, dst_type, num_dst_components, + tmp_row, tmp_type, 4, + swizzle, false, srcWidth); + dst_row += dstRowStride; + src_row += src_stride; + } + } + + return GL_TRUE; +} + +static GLboolean +texstore_rgba(TEXSTORE_PARAMS) +{ + static StoreTexImageFunc table[MESA_FORMAT_COUNT]; + static GLboolean initialized = GL_FALSE; + + if (!initialized) { + memset(table, 0, sizeof table); + + table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565; + table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565; + table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr; + table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr; table[MESA_FORMAT_B10G10R10A2_UINT] = _mesa_texstore_argb2101010_uint; table[MESA_FORMAT_R10G10B10A2_UINT] = _mesa_texstore_abgr2101010_uint; - table[MESA_FORMAT_B4G4R4X4_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_B5G5R5X1_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_R8G8B8X8_SNORM] = _mesa_texstore_signed_rgbx8888; - table[MESA_FORMAT_R8G8B8X8_SRGB] = _mesa_texstore_srgba8; - table[MESA_FORMAT_R8G8B8A8_SRGB] = _mesa_texstore_srgba8; - table[MESA_FORMAT_RGBX_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_RGBX_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_B10G10R10X2_UNORM] = _mesa_texstore_argb2101010; - table[MESA_FORMAT_RGBX_UNORM16] = _mesa_texstore_rgba_16; - table[MESA_FORMAT_RGBX_SNORM16] = _mesa_texstore_signed_rgba_16; - table[MESA_FORMAT_RGBX_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_RGBX_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_RGBX_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RGBX_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_RGBX_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_RGBX_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_R10G10B10A2_UNORM] = _mesa_texstore_abgr2101010; - - table[MESA_FORMAT_G8R8_SNORM] = _mesa_texstore_snorm88; - table[MESA_FORMAT_G16R16_SNORM] = _mesa_texstore_snorm1616; - - table[MESA_FORMAT_B8G8R8X8_SRGB] = _mesa_texstore_sargb8; - initialized = GL_TRUE; } - ASSERT(table[format]); - return table[format]; -} + if (table[dstFormat] && table[dstFormat](ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking)) { + return GL_TRUE; + } + + if (texstore_swizzle(ctx, dims, baseInternalFormat, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking)) { + return GL_TRUE; + } + if (_mesa_is_format_integer(dstFormat)) { + return texstore_rgba_integer(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); + } else if (_mesa_get_format_max_bits(dstFormat) <= 8 && + !_mesa_is_format_signed(dstFormat)) { + return store_ubyte_texture(ctx, dims, baseInternalFormat, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + } else { + return texstore_via_float(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); + } +} GLboolean _mesa_texstore_needs_transfer_ops(struct gl_context *ctx, @@ -3863,8 +1831,6 @@ _mesa_texstore_memcpy(TEXSTORE_PARAMS) srcAddr, srcPacking); return GL_TRUE; } - - /** * Store user data into texture memory. * Called via glTex[Sub]Image1/2/3D() @@ -3873,9 +1839,6 @@ _mesa_texstore_memcpy(TEXSTORE_PARAMS) GLboolean _mesa_texstore(TEXSTORE_PARAMS) { - StoreTexImageFunc storeImage; - GLboolean success; - if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat, dstFormat, dstRowStride, dstSlices, @@ -3884,14 +1847,22 @@ _mesa_texstore(TEXSTORE_PARAMS) return GL_TRUE; } - storeImage = _mesa_get_texstore_func(dstFormat); - - success = storeImage(ctx, dims, baseInternalFormat, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - return success; + if (_mesa_is_depth_or_stencil_format(baseInternalFormat)) { + return texstore_depth_stencil(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + } else if (_mesa_is_format_compressed(dstFormat)) { + return texstore_compressed(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + } else { + return texstore_rgba(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + } } |