X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexstore.c;h=0e036d9ebe64d98e914d00587ae9e308e000efe4;hb=7207830047964aff16324cb5617ab40d12f32e3e;hp=5adbd5dc92aea03c8797dc964be1bd6de4dfa83b;hpb=7d913903597779b896d70358a45be9d12bd0a0df;p=mesa.git diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 5adbd5dc92a..0e036d9ebe6 100644 --- a/src/mesa/main/texstore.c +++ b/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 to 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 }; /** @@ -923,7 +670,7 @@ _mesa_swizzle_ubyte_image(struct gl_context *ctx, static void memcpy_texture(struct gl_context *ctx, GLuint dimensions, - gl_format dstFormat, + mesa_format dstFormat, GLint dstRowStride, GLubyte **dstSlices, GLint srcWidth, GLint srcHeight, GLint srcDepth, @@ -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, @@ -1012,11 +763,11 @@ _mesa_texstore_z32(TEXSTORE_PARAMS) const GLuint depthScale = 0xffffffff; GLenum dstType; (void) dims; - ASSERT(dstFormat == MESA_FORMAT_Z32 || - dstFormat == MESA_FORMAT_Z32_FLOAT); + ASSERT(dstFormat == MESA_FORMAT_Z_UNORM32 || + dstFormat == MESA_FORMAT_Z_FLOAT32); ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint)); - if (dstFormat == MESA_FORMAT_Z32) + if (dstFormat == MESA_FORMAT_Z_UNORM32) dstType = GL_UNSIGNED_INT; else dstType = GL_FLOAT; @@ -1049,7 +800,7 @@ _mesa_texstore_x8_z24(TEXSTORE_PARAMS) const GLuint depthScale = 0xffffff; (void) dims; - ASSERT(dstFormat == MESA_FORMAT_X8_Z24); + ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT); { /* general path */ @@ -1079,7 +830,7 @@ _mesa_texstore_z24_x8(TEXSTORE_PARAMS) const GLuint depthScale = 0xffffff; (void) dims; - ASSERT(dstFormat == MESA_FORMAT_Z24_X8); + ASSERT(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM); { /* general path */ @@ -1112,7 +863,7 @@ _mesa_texstore_z16(TEXSTORE_PARAMS) { const GLuint depthScale = 0xffff; (void) dims; - ASSERT(dstFormat == MESA_FORMAT_Z16); + ASSERT(dstFormat == MESA_FORMAT_Z_UNORM16); ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort)); { @@ -1141,8 +892,8 @@ _mesa_texstore_z16(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_rgb565(TEXSTORE_PARAMS) { - ASSERT(dstFormat == MESA_FORMAT_RGB565 || - dstFormat == MESA_FORMAT_RGB565_REV); + ASSERT(dstFormat == MESA_FORMAT_B5G6R5_UNORM || + dstFormat == MESA_FORMAT_R5G6B5_UNORM); ASSERT(_mesa_get_format_bytes(dstFormat) == 2); if (!ctx->_ImageTransferState && @@ -1163,7 +914,7 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS) const GLubyte *srcUB = (const GLubyte *) src; GLushort *dstUS = (GLushort *) dst; /* check for byteswapped format */ - if (dstFormat == MESA_FORMAT_RGB565) { + if (dstFormat == MESA_FORMAT_B5G6R5_UNORM) { for (col = 0; col < srcWidth; col++) { dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] ); srcUB += 3; @@ -1178,2219 +929,267 @@ _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_RGBA8888 or MESA_FORMAT_RGBA8888_REV. + * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. */ static GLboolean -_mesa_texstore_rgba8888(TEXSTORE_PARAMS) +_mesa_texstore_ycbcr(TEXSTORE_PARAMS) { const GLboolean littleEndian = _mesa_little_endian(); - ASSERT(dstFormat == MESA_FORMAT_RGBA8888 || - dstFormat == MESA_FORMAT_RGBA8888_REV || - dstFormat == MESA_FORMAT_RGBX8888 || - dstFormat == MESA_FORMAT_RGBX8888_REV); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); + (void) ctx; (void) dims; (void) baseInternalFormat; - 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)) { + ASSERT((dstFormat == MESA_FORMAT_YCBCR) || + (dstFormat == MESA_FORMAT_YCBCR_REV)); + ASSERT(_mesa_get_format_bytes(dstFormat) == 2); + ASSERT(ctx->Extensions.MESA_ycbcr_texture); + ASSERT(srcFormat == GL_YCBCR_MESA); + ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) || + (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA)); + ASSERT(baseInternalFormat == GL_YCBCR_MESA); - GLubyte dstmap[4]; + /* always just memcpy since no pixel transfer ops apply */ + memcpy_texture(ctx, dims, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, srcFormat, srcType, + srcAddr, srcPacking); - /* dstmap - how to swizzle from RGBA to dst format: - */ - if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 || - dstFormat == MESA_FORMAT_RGBX8888)) || - (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV || - dstFormat == MESA_FORMAT_RGBX8888_REV))) { - 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; + /* Check if we need byte swapping */ + /* XXX the logic here _might_ be wrong */ + if (srcPacking->SwapBytes ^ + (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^ + (dstFormat == MESA_FORMAT_YCBCR_REV) ^ + !littleEndian) { + GLint img, row; + for (img = 0; img < srcDepth; img++) { + GLubyte *dstRow = dstSlices[img]; + for (row = 0; row < srcHeight; row++) { + _mesa_swap2((GLushort *) dstRow, srcWidth); + dstRow += dstRowStride; + } } - - _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; } +/** + * Store a combined depth/stencil texture image. + */ static GLboolean -_mesa_texstore_argb8888(TEXSTORE_PARAMS) +_mesa_texstore_z24_s8(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); + const GLuint depthScale = 0xffffff; + const GLint srcRowStride + = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); + GLint img, row; + GLuint *depth = malloc(srcWidth * sizeof(GLuint)); + GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte)); - ASSERT(dstFormat == MESA_FORMAT_ARGB8888 || - dstFormat == MESA_FORMAT_ARGB8888_REV || - dstFormat == MESA_FORMAT_XRGB8888 || - dstFormat == MESA_FORMAT_XRGB8888_REV ); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); + ASSERT(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM); + ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || + srcFormat == GL_DEPTH_COMPONENT || + srcFormat == GL_STENCIL_INDEX); + ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || + srcType == GL_UNSIGNED_INT_24_8_EXT || + srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - (dstFormat == MESA_FORMAT_ARGB8888 || - dstFormat == MESA_FORMAT_XRGB8888) && - 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; - } - } + if (!depth || !stencil) { + free(depth); + free(stencil); + return GL_FALSE; } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_ARGB8888 && - 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; + + /* In case we only upload depth we need to preserve the stencil */ + for (img = 0; img < srcDepth; img++) { + GLuint *dstRow = (GLuint *) dstSlices[img]; + const GLubyte *src + = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, + srcWidth, srcHeight, + srcFormat, srcType, + img, 0, 0); + for (row = 0; row < srcHeight; row++) { + GLint i; + GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; + + if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ + keepstencil = GL_TRUE; } - } - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_ARGB8888 && - 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 (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ + keepdepth = GL_TRUE; } - } - } - 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]; + if (keepdepth == GL_FALSE) + /* the 24 depth bits will be in the low position: */ + _mesa_unpack_depth_span(ctx, srcWidth, + GL_UNSIGNED_INT, /* dst type */ + keepstencil ? depth : dstRow, /* dst addr */ + depthScale, + srcType, src, srcPacking); - /* dstmap - how to swizzle from RGBA to dst format: - */ - if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) || - (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) || - (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) || - (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) { - dstmap[3] = 3; /* alpha */ - dstmap[2] = 0; /* red */ - dstmap[1] = 1; /* green */ - dstmap[0] = 2; /* blue */ - } - else { - assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) || - (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) || - (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) || - (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888)); - dstmap[3] = 2; - dstmap[2] = 1; - dstmap[1] = 0; - dstmap[0] = 3; + if (keepstencil == GL_FALSE) + /* get the 8-bit stencil values */ + _mesa_unpack_stencil_span(ctx, srcWidth, + GL_UNSIGNED_BYTE, /* dst type */ + stencil, /* dst addr */ + srcType, src, srcPacking, + ctx->_ImageTransferState); + + for (i = 0; i < srcWidth; i++) { + if (keepstencil) + dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF); + else + dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF); + } + src += srcRowStride; + dstRow += dstRowStride / sizeof(GLuint); } - - _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_RGB888); - 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_BGR888); - 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_ARGB2101010 || - dstFormat == MESA_FORMAT_XRGB2101010_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); - } + free(depth); + free(stencil); return GL_TRUE; } /** - * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats. + * Store a combined depth/stencil texture image. */ static GLboolean -_mesa_texstore_unorm44(TEXSTORE_PARAMS) +_mesa_texstore_s8_z24(TEXSTORE_PARAMS) { - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + const GLuint depthScale = 0xffffff; + const GLint srcRowStride + = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); + GLint img, row; + GLuint *depth; + GLubyte *stencil; - ASSERT(dstFormat == MESA_FORMAT_AL44); - ASSERT(_mesa_get_format_bytes(dstFormat) == 1); + ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT); + ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || + srcFormat == GL_DEPTH_COMPONENT || + srcFormat == GL_STENCIL_INDEX); + ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || + srcType == GL_UNSIGNED_INT_24_8_EXT || + srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - { - /* 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); + depth = malloc(srcWidth * sizeof(GLuint)); + stencil = malloc(srcWidth * sizeof(GLubyte)); + + if (!depth || !stencil) { + free(depth); + free(stencil); + return GL_FALSE; } - return GL_TRUE; -} + for (img = 0; img < srcDepth; img++) { + GLuint *dstRow = (GLuint *) dstSlices[img]; + const GLubyte *src + = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, + srcWidth, srcHeight, + srcFormat, srcType, + img, 0, 0); + for (row = 0; row < srcHeight; row++) { + GLint i; + GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; + + if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ + keepstencil = GL_TRUE; + } + else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ + keepdepth = 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); + if (keepdepth == GL_FALSE) + /* the 24 depth bits will be in the low position: */ + _mesa_unpack_depth_span(ctx, srcWidth, + GL_UNSIGNED_INT, /* dst type */ + keepstencil ? depth : dstRow, /* dst addr */ + depthScale, + srcType, src, srcPacking); - ASSERT(dstFormat == MESA_FORMAT_AL88 || - dstFormat == MESA_FORMAT_AL88_REV || - dstFormat == MESA_FORMAT_GR88 || - dstFormat == MESA_FORMAT_RG88); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); + if (keepstencil == GL_FALSE) + /* get the 8-bit stencil values */ + _mesa_unpack_stencil_span(ctx, srcWidth, + GL_UNSIGNED_BYTE, /* dst type */ + stencil, /* dst addr */ + srcType, src, srcPacking, + ctx->_ImageTransferState); - if (!ctx->_ImageTransferState && - littleEndian && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - GLubyte dstmap[4]; + /* merge stencil values into depth values */ + for (i = 0; i < srcWidth; i++) { + if (keepstencil) + dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000); + else + dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24); - /* dstmap - how to swizzle from RGBA to dst format: - */ - if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) { - if ((littleEndian && dstFormat == MESA_FORMAT_AL88) || - (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) { - dstmap[0] = 0; - dstmap[1] = 3; - } - else { - dstmap[0] = 3; - dstmap[1] = 0; - } - } - else { - if ((littleEndian && dstFormat == MESA_FORMAT_GR88) || - (!littleEndian && dstFormat == MESA_FORMAT_RG88)) { - 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_AL88 || - dstFormat == MESA_FORMAT_GR88) { - 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; - } + src += srcRowStride; + dstRow += dstRowStride / sizeof(GLuint); } - 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_AL1616 || - dstFormat == MESA_FORMAT_AL1616_REV || - dstFormat == MESA_FORMAT_GR1616 || - dstFormat == MESA_FORMAT_RG1616); - 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_AL1616 || - dstFormat == MESA_FORMAT_GR1616) { - 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; + free(depth); + free(stencil); - 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. */ +/** + * Store simple 8-bit/value stencil texture data. + */ static GLboolean -_mesa_texstore_unorm16(TEXSTORE_PARAMS) +_mesa_texstore_s8(TEXSTORE_PARAMS) { - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R16 || - dstFormat == MESA_FORMAT_A16 || - dstFormat == MESA_FORMAT_L16 || - dstFormat == MESA_FORMAT_I16); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); + ASSERT(dstFormat == MESA_FORMAT_S_UINT8); + ASSERT(srcFormat == GL_STENCIL_INDEX); { - /* 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_16 || - dstFormat == MESA_FORMAT_XBGR16161616_UNORM); - 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_SIGNED_RGB_16 || - dstFormat == MESA_FORMAT_SIGNED_RGBA_16 || - dstFormat == MESA_FORMAT_XBGR16161616_SNORM); - - { - /* 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_SIGNED_RGBA_16) { - 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_XBGR16161616_SNORM) { - 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_A8 || - dstFormat == MESA_FORMAT_L8 || - dstFormat == MESA_FORMAT_I8 || - dstFormat == MESA_FORMAT_R8); - 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_A8) { - 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. - */ -static GLboolean -_mesa_texstore_ycbcr(TEXSTORE_PARAMS) -{ - const GLboolean littleEndian = _mesa_little_endian(); - - (void) ctx; (void) dims; (void) baseInternalFormat; - - ASSERT((dstFormat == MESA_FORMAT_YCBCR) || - (dstFormat == MESA_FORMAT_YCBCR_REV)); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - ASSERT(ctx->Extensions.MESA_ycbcr_texture); - ASSERT(srcFormat == GL_YCBCR_MESA); - ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) || - (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA)); - ASSERT(baseInternalFormat == GL_YCBCR_MESA); - - /* always just memcpy since no pixel transfer ops apply */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - - /* Check if we need byte swapping */ - /* XXX the logic here _might_ be wrong */ - if (srcPacking->SwapBytes ^ - (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^ - (dstFormat == MESA_FORMAT_YCBCR_REV) ^ - !littleEndian) { - GLint img, row; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - _mesa_swap2((GLushort *) dstRow, srcWidth); - dstRow += dstRowStride; - } - } - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_dudv8(TEXSTORE_PARAMS) -{ - const GLboolean littleEndian = _mesa_little_endian(); - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_DUDV8); - ASSERT(texelBytes == 2); - ASSERT(ctx->Extensions.ATI_envmap_bumpmap); - ASSERT((srcFormat == GL_DU8DV8_ATI) || - (srcFormat == GL_DUDV_ATI)); - ASSERT(baseInternalFormat == GL_DUDV_ATI); - - if (srcType == GL_BYTE) { - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - if (littleEndian) { - dstmap[0] = 0; - dstmap[1] = 3; - } - else { - dstmap[0] = 3; - dstmap[1] = 0; - } - dstmap[2] = ZERO; /* ? */ - dstmap[3] = ONE; /* ? */ - - _mesa_swizzle_ubyte_image(ctx, dims, - GL_LUMINANCE_ALPHA, /* hack */ - GL_UNSIGNED_BYTE, /* hack */ - GL_LUMINANCE_ALPHA, /* hack */ - dstmap, 2, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - /* general path - note this is defined for 2d textures only */ - const GLint components = _mesa_components_in_format(baseInternalFormat); - const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth, - srcFormat, srcType); - GLbyte *tempImage, *dst, *src; - GLint row; - - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLbyte)); - if (!tempImage) - return GL_FALSE; - - src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - 0, 0, 0); - - dst = tempImage; - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat, - dst, srcFormat, srcType, src, - srcPacking, 0); - dst += srcWidth * components; - src += srcStride; - } - - src = tempImage; - dst = (GLbyte *) dstSlices[0]; - for (row = 0; row < srcHeight; row++) { - memcpy(dst, src, srcWidth * texelBytes); - dst += dstRowStride; - src += srcWidth * texelBytes; - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * 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_SIGNED_A8 || - dstFormat == MESA_FORMAT_SIGNED_L8 || - dstFormat == MESA_FORMAT_SIGNED_I8 || - dstFormat == MESA_FORMAT_SIGNED_R8); - 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_SIGNED_AL88 || - dstFormat == MESA_FORMAT_SIGNED_RG88_REV); - 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++) { - GLbyte *dst = dstRow; - for (col = 0; col < srcWidth; col++) { - dst[0] = FLOAT_TO_BYTE_TEX(src[0]); - dst[1] = FLOAT_TO_BYTE_TEX(src[1]); - src += 2; - dst += 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_SIGNED_R16 || - dstFormat == MESA_FORMAT_SIGNED_A16 || - dstFormat == MESA_FORMAT_SIGNED_L16 || - dstFormat == MESA_FORMAT_SIGNED_I16); - 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_SIGNED_AL1616 || - dstFormat == MESA_FORMAT_SIGNED_GR1616); - 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++) { - GLshort *dst = (GLshort *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort l, a; - - UNCLAMPED_FLOAT_TO_SHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_SHORT(a, src[1]); - dst[0] = l; - dst[1] = a; - src += 2; - dst += 2; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -/** - * Store a texture in MESA_FORMAT_SIGNED_RGBX8888 or - * MESA_FORMAT_XBGR8888_SNORM. - */ -static GLboolean -_mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888 || - dstFormat == MESA_FORMAT_XBGR8888_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_SIGNED_RGBX8888) { - 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_SIGNED_RGBA8888 or - * MESA_FORMAT_SIGNED_RGBA8888_REV - */ -static GLboolean -_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 || - dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV); - 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_SIGNED_RGBA8888) { - 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 -_mesa_texstore_z24_s8(TEXSTORE_PARAMS) -{ - const GLuint depthScale = 0xffffff; - const GLint srcRowStride - = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLint img, row; - - ASSERT(dstFormat == MESA_FORMAT_Z24_S8); - ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || - srcFormat == GL_DEPTH_COMPONENT || - srcFormat == GL_STENCIL_INDEX); - ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT); - - if (srcFormat == GL_DEPTH_COMPONENT || - srcFormat == GL_STENCIL_INDEX) { - GLuint *depth = malloc(srcWidth * sizeof(GLuint)); - GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte)); - - if (!depth || !stencil) { - free(depth); - free(stencil); - return GL_FALSE; - } - - /* In case we only upload depth we need to preserve the stencil */ - for (img = 0; img < srcDepth; img++) { - GLuint *dstRow = (GLuint *) dstSlices[img]; - const GLubyte *src - = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - GLint i; - GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; - - if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ - keepstencil = GL_TRUE; - } - else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ - keepdepth = GL_TRUE; - } - - if (keepdepth == GL_FALSE) - /* the 24 depth bits will be in the low position: */ - _mesa_unpack_depth_span(ctx, srcWidth, - GL_UNSIGNED_INT, /* dst type */ - keepstencil ? depth : dstRow, /* dst addr */ - depthScale, - srcType, src, srcPacking); - - if (keepstencil == GL_FALSE) - /* get the 8-bit stencil values */ - _mesa_unpack_stencil_span(ctx, srcWidth, - GL_UNSIGNED_BYTE, /* dst type */ - stencil, /* dst addr */ - srcType, src, srcPacking, - ctx->_ImageTransferState); - - for (i = 0; i < srcWidth; i++) { - if (keepstencil) - dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF); - else - dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF); - } - - src += srcRowStride; - dstRow += dstRowStride / sizeof(GLuint); - } - } - - free(depth); - free(stencil); - } - return GL_TRUE; -} - - -/** - * Store a combined depth/stencil texture image. - */ -static GLboolean -_mesa_texstore_s8_z24(TEXSTORE_PARAMS) -{ - const GLuint depthScale = 0xffffff; - const GLint srcRowStride - = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLint img, row; - GLuint *depth; - GLubyte *stencil; - - ASSERT(dstFormat == MESA_FORMAT_S8_Z24); - ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || - srcFormat == GL_DEPTH_COMPONENT || - srcFormat == GL_STENCIL_INDEX); - ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || - srcType == GL_UNSIGNED_INT_24_8_EXT); - - depth = malloc(srcWidth * sizeof(GLuint)); - stencil = malloc(srcWidth * sizeof(GLubyte)); - - if (!depth || !stencil) { - free(depth); - free(stencil); - return GL_FALSE; - } - - for (img = 0; img < srcDepth; img++) { - GLuint *dstRow = (GLuint *) dstSlices[img]; - const GLubyte *src - = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - GLint i; - GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; - - if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ - keepstencil = GL_TRUE; - } - else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ - keepdepth = GL_TRUE; - } - - if (keepdepth == GL_FALSE) - /* the 24 depth bits will be in the low position: */ - _mesa_unpack_depth_span(ctx, srcWidth, - GL_UNSIGNED_INT, /* dst type */ - keepstencil ? depth : dstRow, /* dst addr */ - depthScale, - srcType, src, srcPacking); - - if (keepstencil == GL_FALSE) - /* get the 8-bit stencil values */ - _mesa_unpack_stencil_span(ctx, srcWidth, - GL_UNSIGNED_BYTE, /* dst type */ - stencil, /* dst addr */ - srcType, src, srcPacking, - ctx->_ImageTransferState); - - /* merge stencil values into depth values */ - for (i = 0; i < srcWidth; i++) { - if (keepstencil) - dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000); - else - dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24); - - } - src += srcRowStride; - dstRow += dstRowStride / sizeof(GLuint); - } - } - - free(depth); - free(stencil); - - return GL_TRUE; -} - - -/** - * Store simple 8-bit/value stencil texture data. - */ -static GLboolean -_mesa_texstore_s8(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_S8); - ASSERT(srcFormat == GL_STENCIL_INDEX); - - { - const GLint srcRowStride - = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLint img, row; - GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte)); - - if (!stencil) - return GL_FALSE; - - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - const GLubyte *src - = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - GLint i; - - /* get the 8-bit stencil values */ - _mesa_unpack_stencil_span(ctx, srcWidth, - GL_UNSIGNED_BYTE, /* dst type */ - stencil, /* dst addr */ - srcType, src, srcPacking, - ctx->_ImageTransferState); - /* merge stencil values into depth values */ - for (i = 0; i < srcWidth; i++) - dstRow[i] = stencil[i]; - - src += srcRowStride; - dstRow += dstRowStride / sizeof(GLubyte); - } - } - - free(stencil); - } - - return GL_TRUE; -} - - -/** - * 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_XBGR32323232_FLOAT) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 || - dstFormat == MESA_FORMAT_RGB_FLOAT32 || - dstFormat == MESA_FORMAT_ALPHA_FLOAT32 || - dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 || - dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 || - dstFormat == MESA_FORMAT_INTENSITY_FLOAT32 || - dstFormat == MESA_FORMAT_R_FLOAT32 || - dstFormat == MESA_FORMAT_RG_FLOAT32 || - dstFormat == MESA_FORMAT_XBGR32323232_FLOAT); - 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_XBGR16161616_FLOAT) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 || - dstFormat == MESA_FORMAT_RGB_FLOAT16 || - dstFormat == MESA_FORMAT_ALPHA_FLOAT16 || - dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 || - dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 || - dstFormat == MESA_FORMAT_INTENSITY_FLOAT16 || - dstFormat == MESA_FORMAT_R_FLOAT16 || - dstFormat == MESA_FORMAT_RG_FLOAT16 || - dstFormat == MESA_FORMAT_XBGR16161616_FLOAT); - 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_XBGR8888_SINT) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_INT8 || - dstFormat == MESA_FORMAT_RG_INT8 || - dstFormat == MESA_FORMAT_RGB_INT8 || - dstFormat == MESA_FORMAT_RGBA_INT8 || - dstFormat == MESA_FORMAT_ALPHA_INT8 || - dstFormat == MESA_FORMAT_INTENSITY_INT8 || - dstFormat == MESA_FORMAT_LUMINANCE_INT8 || - dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8 || - dstFormat == MESA_FORMAT_XBGR8888_SINT); - 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_XBGR16161616_SINT) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_INT16 || - dstFormat == MESA_FORMAT_RG_INT16 || - dstFormat == MESA_FORMAT_RGB_INT16 || - dstFormat == MESA_FORMAT_RGBA_INT16 || - dstFormat == MESA_FORMAT_ALPHA_INT16 || - dstFormat == MESA_FORMAT_LUMINANCE_INT16 || - dstFormat == MESA_FORMAT_INTENSITY_INT16 || - dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16 || - dstFormat == MESA_FORMAT_XBGR16161616_SINT); - 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_XBGR32323232_SINT) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_INT32 || - dstFormat == MESA_FORMAT_RG_INT32 || - dstFormat == MESA_FORMAT_RGB_INT32 || - dstFormat == MESA_FORMAT_RGBA_INT32 || - dstFormat == MESA_FORMAT_ALPHA_INT32 || - dstFormat == MESA_FORMAT_INTENSITY_INT32 || - dstFormat == MESA_FORMAT_LUMINANCE_INT32 || - dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32 || - dstFormat == MESA_FORMAT_XBGR32323232_SINT); - 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_XBGR8888_UINT) { - 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_ALPHA_UINT8 || - dstFormat == MESA_FORMAT_INTENSITY_UINT8 || - dstFormat == MESA_FORMAT_LUMINANCE_UINT8 || - dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8 || - dstFormat == MESA_FORMAT_XBGR8888_UINT); - 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_XBGR16161616_UINT) { - 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_ALPHA_UINT16 || - dstFormat == MESA_FORMAT_INTENSITY_UINT16 || - dstFormat == MESA_FORMAT_LUMINANCE_UINT16 || - dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16 || - dstFormat == MESA_FORMAT_XBGR16161616_UINT); - 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_XBGR32323232_UINT) { - 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_ALPHA_UINT32 || - dstFormat == MESA_FORMAT_INTENSITY_UINT32 || - dstFormat == MESA_FORMAT_LUMINANCE_UINT32 || - dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32 || - dstFormat == MESA_FORMAT_XBGR32323232_UINT); - 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) -{ - gl_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_SRGB8); - - /* reuse normal rgb texstore code */ - newDstFormat = MESA_FORMAT_RGB888; - - 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) -{ - gl_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_SRGBA8 || - dstFormat == MESA_FORMAT_XBGR8888_SRGB); - - /* reuse normal rgba texstore code */ - if (dstFormat == MESA_FORMAT_SRGBA8) { - newDstFormat = MESA_FORMAT_RGBA8888; - } - else if (dstFormat == MESA_FORMAT_XBGR8888_SRGB) { - newDstFormat = MESA_FORMAT_RGBX8888_REV; - } - else { - ASSERT(0); - return GL_TRUE; - } - - 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) -{ - gl_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_SARGB8); - - /* reuse normal rgba texstore code */ - newDstFormat = MESA_FORMAT_ARGB8888; - - 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) -{ - gl_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_SL8); - - newDstFormat = MESA_FORMAT_L8; - - /* _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) -{ - gl_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_SLA8); - - /* reuse normal luminance/alpha texstore code */ - newDstFormat = MESA_FORMAT_AL88; - - 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_RGB9_E5_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_R11_G11_B10_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) + const GLint srcRowStride + = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); + GLint img, row; + GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte)); + + if (!stencil) return GL_FALSE; + for (img = 0; img < srcDepth; img++) { GLubyte *dstRow = dstSlices[img]; + const GLubyte *src + = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, + srcWidth, srcHeight, + srcFormat, srcType, + img, 0, 0); for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint*)dstRow; - for (col = 0; col < srcWidth; col++) { - dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]); - } - dstRow += dstRowStride; - srcRow += srcWidth * 3; + GLint i; + + /* get the 8-bit stencil values */ + _mesa_unpack_stencil_span(ctx, srcWidth, + GL_UNSIGNED_BYTE, /* dst type */ + stencil, /* dst addr */ + srcType, src, srcPacking, + ctx->_ImageTransferState); + /* merge stencil values into depth values */ + for (i = 0; i < srcWidth; i++) + dstRow[i] = stencil[i]; + + src += srcRowStride; + dstRow += dstRowStride / sizeof(GLubyte); } } - free((void *) tempImage); + free(stencil); } + return GL_TRUE; } @@ -3398,49 +1197,47 @@ _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) { - ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8); + GLint img, row; + const GLint srcRowStride + = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) + / sizeof(uint64_t); + + ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT); ASSERT(srcFormat == GL_DEPTH_STENCIL || srcFormat == GL_DEPTH_COMPONENT || srcFormat == GL_STENCIL_INDEX); ASSERT(srcFormat != GL_DEPTH_STENCIL || + srcType == GL_UNSIGNED_INT_24_8 || srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - if (srcFormat == GL_DEPTH_COMPONENT || - srcFormat == GL_STENCIL_INDEX) { - GLint img, row; - const GLint srcRowStride - = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) - / sizeof(uint64_t); + /* In case we only upload depth we need to preserve the stencil */ + for (img = 0; img < srcDepth; img++) { + uint64_t *dstRow = (uint64_t *) dstSlices[img]; + const uint64_t *src + = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr, + srcWidth, srcHeight, + srcFormat, srcType, + img, 0, 0); + for (row = 0; row < srcHeight; row++) { + /* The unpack functions with: + * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV + * only write their own dword, so the other dword (stencil + * or depth) is preserved. */ + if (srcFormat != GL_STENCIL_INDEX) + _mesa_unpack_depth_span(ctx, srcWidth, + GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ + dstRow, /* dst addr */ + ~0U, srcType, src, srcPacking); - /* In case we only upload depth we need to preserve the stencil */ - for (img = 0; img < srcDepth; img++) { - uint64_t *dstRow = (uint64_t *) dstSlices[img]; - const uint64_t *src - = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - /* The unpack functions with: - * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV - * only write their own dword, so the other dword (stencil - * or depth) is preserved. */ - if (srcFormat != GL_STENCIL_INDEX) - _mesa_unpack_depth_span(ctx, srcWidth, - GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ - dstRow, /* dst addr */ - ~0U, srcType, src, srcPacking); - - if (srcFormat != GL_DEPTH_COMPONENT) - _mesa_unpack_stencil_span(ctx, srcWidth, - GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ - dstRow, /* dst addr */ - srcType, src, srcPacking, - ctx->_ImageTransferState); + if (srcFormat != GL_DEPTH_COMPONENT) + _mesa_unpack_stencil_span(ctx, srcWidth, + GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ + dstRow, /* dst addr */ + srcType, src, srcPacking, + ctx->_ImageTransferState); - src += srcRowStride; - dstRow += dstRowStride / sizeof(uint64_t); - } + src += srcRowStride; + dstRow += dstRowStride / sizeof(uint64_t); } } return GL_TRUE; @@ -3451,7 +1248,7 @@ _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS) { const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT); + ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UINT); ASSERT(_mesa_get_format_bytes(dstFormat) == 4); { @@ -3507,7 +1304,7 @@ _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) { const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT); + ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UINT); ASSERT(_mesa_get_format_bytes(dstFormat) == 4); { @@ -3558,86 +1355,45 @@ _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) return GL_TRUE; } + static GLboolean -_mesa_texstore_null(TEXSTORE_PARAMS) +texstore_depth_stencil(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; -} + static StoreTexImageFunc table[MESA_FORMAT_COUNT]; + static GLboolean initialized = GL_FALSE; + if (!initialized) { + 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; + table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24; + 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_Z_FLOAT32] = _mesa_texstore_z32; + table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8; -/** - * Return the StoreTexImageFunc pointer to store an image in the given format. - */ -static StoreTexImageFunc -_mesa_get_texstore_func(gl_format format) + 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) { - table[MESA_FORMAT_NONE] = _mesa_texstore_null; - - table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888; - table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888; - table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888; - table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888; - table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888; - table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888; - table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565; - table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565; - table[MESA_FORMAT_ARGB4444] = store_ubyte_texture; - table[MESA_FORMAT_ARGB4444_REV] = store_ubyte_texture; - table[MESA_FORMAT_RGBA5551] = store_ubyte_texture; - table[MESA_FORMAT_ARGB1555] = store_ubyte_texture; - table[MESA_FORMAT_ARGB1555_REV] = store_ubyte_texture; - table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44; - table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88; - table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88; - table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_RGB332] = store_ubyte_texture; - table[MESA_FORMAT_A8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_A16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_L8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_L16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_I8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_I16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr; - table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr; - table[MESA_FORMAT_R8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88; - table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88; - table[MESA_FORMAT_R16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_GR1616] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010; - table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8; - table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24; - table[MESA_FORMAT_Z16] = _mesa_texstore_z16; - table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24; - table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8; - table[MESA_FORMAT_Z32] = _mesa_texstore_z32; - table[MESA_FORMAT_S8] = _mesa_texstore_s8; - table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8; - table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8; - table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8; - table[MESA_FORMAT_SL8] = _mesa_texstore_sl8; - table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8; + 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; @@ -3648,41 +1404,14 @@ _mesa_get_texstore_func(gl_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_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_INTENSITY_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_DUDV8] = _mesa_texstore_dudv8; - table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88; - table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888; - table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888; - table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888; - table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616; - table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16; - table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16; - table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16; - table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1; - table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1; - table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2; - table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2; - table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1; - table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1; - table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2; - table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2; + 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; + table[MESA_FORMAT_RG_RGTC2_SNORM] = _mesa_texstore_signed_rg_rgtc2; + table[MESA_FORMAT_L_LATC1_UNORM] = _mesa_texstore_red_rgtc1; + table[MESA_FORMAT_L_LATC1_SNORM] = _mesa_texstore_signed_red_rgtc1; + table[MESA_FORMAT_LA_LATC2_UNORM] = _mesa_texstore_rg_rgtc2; + table[MESA_FORMAT_LA_LATC2_SNORM] = _mesa_texstore_signed_rg_rgtc2; table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8; table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8; table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8; @@ -3696,104 +1425,332 @@ _mesa_get_texstore_func(gl_format format) _mesa_texstore_etc2_rgb8_punchthrough_alpha1; table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] = _mesa_texstore_etc2_srgb8_punchthrough_alpha1; - table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88; - table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616; - table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5; - table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f; - table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32; - table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8; - - table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32; - table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32; - table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32; - table[MESA_FORMAT_RGBA_INT32] = _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; - - table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint; - table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint; - - table[MESA_FORMAT_XRGB4444_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_XRGB1555_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_XBGR8888_SNORM] = _mesa_texstore_signed_rgbx8888; - table[MESA_FORMAT_XBGR8888_SRGB] = _mesa_texstore_srgba8; - table[MESA_FORMAT_XBGR8888_UINT] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_XBGR8888_SINT] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_XRGB2101010_UNORM] = _mesa_texstore_argb2101010; - table[MESA_FORMAT_XBGR16161616_UNORM] = _mesa_texstore_rgba_16; - table[MESA_FORMAT_XBGR16161616_SNORM] = _mesa_texstore_signed_rgba_16; - table[MESA_FORMAT_XBGR16161616_FLOAT] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_XBGR16161616_UINT] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_XBGR16161616_SINT] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_XBGR32323232_FLOAT] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_XBGR32323232_UINT] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_XBGR32323232_SINT] = _mesa_texstore_rgba_int32; initialized = GL_TRUE; } - ASSERT(table[format]); - return table[format]; + 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; + + initialized = GL_TRUE; + } + + 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, GLenum baseInternalFormat, - gl_format dstFormat) + mesa_format dstFormat) { GLenum dstType; @@ -3822,7 +1779,7 @@ _mesa_texstore_needs_transfer_ops(struct gl_context *ctx, GLboolean _mesa_texstore_can_use_memcpy(struct gl_context *ctx, - GLenum baseInternalFormat, gl_format dstFormat, + GLenum baseInternalFormat, mesa_format dstFormat, GLenum srcFormat, GLenum srcType, const struct gl_pixelstore_attrib *srcPacking) { @@ -3841,6 +1798,21 @@ _mesa_texstore_can_use_memcpy(struct gl_context *ctx, return GL_FALSE; } + /* Depth texture data needs clamping in following cases: + * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0]. + * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1]. + * + * All the cases except one (float dstFormat with float srcType) are ruled + * out by _mesa_format_matches_format_and_type() check above. Handle the + * remaining case here. + */ + if ((baseInternalFormat == GL_DEPTH_COMPONENT || + baseInternalFormat == GL_DEPTH_STENCIL) && + (srcType == GL_FLOAT || + srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)) { + return GL_FALSE; + } + return GL_TRUE; } @@ -3859,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() @@ -3869,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, @@ -3880,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); + } } @@ -3900,7 +1875,7 @@ _mesa_texstore(TEXSTORE_PARAMS) * \param texFormat the destination texture format */ static GLbitfield -get_read_write_mode(GLenum userFormat, gl_format texFormat) +get_read_write_mode(GLenum userFormat, mesa_format texFormat) { if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT) && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL) @@ -4090,6 +2065,78 @@ _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, format, type, pixels, packing, "glTexSubImage"); } +static void +clear_image_to_zero(GLubyte *dstMap, GLint dstRowStride, + GLsizei width, GLsizei height, + GLsizei clearValueSize) +{ + GLsizei y; + + for (y = 0; y < height; y++) { + memset(dstMap, 0, clearValueSize * width); + dstMap += dstRowStride; + } +} + +static void +clear_image_to_value(GLubyte *dstMap, GLint dstRowStride, + GLsizei width, GLsizei height, + const GLvoid *clearValue, + GLsizei clearValueSize) +{ + GLsizei y, x; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + memcpy(dstMap, clearValue, clearValueSize); + dstMap += clearValueSize; + } + dstMap += dstRowStride - clearValueSize * width; + } +} + +/* + * Fallback for Driver.ClearTexSubImage(). + */ +void +_mesa_store_cleartexsubimage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue) +{ + GLubyte *dstMap; + GLint dstRowStride; + GLsizeiptr clearValueSize; + GLsizei z; + + clearValueSize = _mesa_get_format_bytes(texImage->TexFormat); + + for (z = 0; z < depth; z++) { + ctx->Driver.MapTextureImage(ctx, texImage, + z + zoffset, xoffset, yoffset, + width, height, + GL_MAP_WRITE_BIT, + &dstMap, &dstRowStride); + if (dstMap == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearTex*Image"); + return; + } + + if (clearValue) { + clear_image_to_value(dstMap, dstRowStride, + width, height, + clearValue, + clearValueSize); + } else { + clear_image_to_zero(dstMap, dstRowStride, + width, height, + clearValueSize); + } + + ctx->Driver.UnmapTextureImage(ctx, texImage, z + zoffset); + } +} /** * Fallback for Driver.CompressedTexImage() @@ -4128,6 +2175,61 @@ _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, } +void +_mesa_compute_compressed_pixelstore(GLuint dims, struct gl_texture_image *texImage, + GLsizei width, GLsizei height, GLsizei depth, + const struct gl_pixelstore_attrib *packing, + struct compressed_pixelstore *store) +{ + GLuint bw, bh; + const mesa_format texFormat = texImage->TexFormat; + + _mesa_get_format_block_size(texFormat, &bw, &bh); + + store->SkipBytes = 0; + store->TotalBytesPerRow = store->CopyBytesPerRow = + _mesa_format_row_stride(texFormat, width); + store->TotalRowsPerSlice = store->CopyRowsPerSlice = + (height + bh - 1) / bh; + store->CopySlices = depth; + + if (packing->CompressedBlockWidth && + packing->CompressedBlockSize) { + + bw = packing->CompressedBlockWidth; + + if (packing->RowLength) { + store->TotalBytesPerRow = packing->CompressedBlockSize * + (packing->RowLength + bw - 1) / bw; + } + + store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw; + } + + if (dims > 1 && packing->CompressedBlockHeight && + packing->CompressedBlockSize) { + + bh = packing->CompressedBlockHeight; + + store->SkipBytes += packing->SkipRows * store->TotalBytesPerRow / bh; + store->CopyRowsPerSlice = (height + bh - 1) / bh; /* rows in blocks */ + + if (packing->ImageHeight) { + store->TotalRowsPerSlice = (packing->ImageHeight + bh - 1) / bh; + } + } + + if (dims > 2 && packing->CompressedBlockDepth && + packing->CompressedBlockSize) { + + int bd = packing->CompressedBlockDepth; + + store->SkipBytes += packing->SkipImages * store->TotalBytesPerRow * + store->TotalRowsPerSlice / bd; + } +} + + /** * Fallback for Driver.CompressedTexSubImage() */ @@ -4139,20 +2241,19 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, GLenum format, GLsizei imageSize, const GLvoid *data) { - GLint bytesPerRow, dstRowStride, srcRowStride; - GLint i, rows; + struct compressed_pixelstore store; + GLint dstRowStride; + GLint i, slice; GLubyte *dstMap; const GLubyte *src; - const gl_format texFormat = texImage->TexFormat; - GLuint bw, bh; - GLint slice; if (dims == 1) { _mesa_problem(ctx, "Unexpected 1D compressed texsubimage call"); return; } - _mesa_get_format_block_size(texFormat, &bw, &bh); + _mesa_compute_compressed_pixelstore(dims, texImage, width, height, depth, + &ctx->Unpack, &store); /* get pointer to src pixels (may be in a pbo which we'll map here) */ data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data, @@ -4161,10 +2262,9 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, if (!data) return; - srcRowStride = _mesa_format_row_stride(texFormat, width); - src = (const GLubyte *) data; + src = (const GLubyte *) data + store.SkipBytes; - for (slice = 0; slice < depth; slice++) { + for (slice = 0; slice < store.CopySlices; slice++) { /* Map dest texture buffer */ ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset, xoffset, yoffset, width, height, @@ -4172,17 +2272,18 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, &dstMap, &dstRowStride); if (dstMap) { - bytesPerRow = srcRowStride; /* bytes per row of blocks */ - rows = (height + bh - 1) / bh; /* rows in blocks */ /* copy rows of blocks */ - for (i = 0; i < rows; i++) { - memcpy(dstMap, src, bytesPerRow); + for (i = 0; i < store.CopyRowsPerSlice; i++) { + memcpy(dstMap, src, store.CopyBytesPerRow); dstMap += dstRowStride; - src += srcRowStride; + src += store.TotalBytesPerRow; } ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset); + + /* advance to next slice */ + src += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD",