diff options
author | marha <marha@users.sourceforge.net> | 2015-02-22 14:31:16 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2015-02-22 14:31:16 +0100 |
commit | f1c2db43dcf35d2cf4715390bd2391c28e42a8c2 (patch) | |
tree | 46b537271afe0f6534231b1bd4cc4f91ae1fb446 /mesalib/src/mesa/main/texstore.c | |
parent | 5e5a48ff8cd08f123601cd0625ca62a86675aac9 (diff) | |
download | vcxsrv-f1c2db43dcf35d2cf4715390bd2391c28e42a8c2.tar.gz vcxsrv-f1c2db43dcf35d2cf4715390bd2391c28e42a8c2.tar.bz2 vcxsrv-f1c2db43dcf35d2cf4715390bd2391c28e42a8c2.zip |
xwininfo fontconfig libX11 libXdmcp libfontenc libxcb libxcb/xcb-proto mesalib xserver xkeyboard-config mkfontscale git update 22 Feb 2015
xserver commit 3a06faf3fcdb7451125a46181f9152e8e59e9770
libxcb commit e3ec1f74637237ce500dfd0ca59f2e422da4e019
libxcb/xcb-proto commit 4c550465934164aab2449a125f75f4ca07816233
xkeyboard-config commit 26f344c93f8c6141e9233eb68088ba4fd56bc9ef
libX11 commit c8e19b393defd53f046ddc2da3a16881221b3c34
libXdmcp commit 9f4cac7656b221ce2a8f97e7bd31e5e23126d001
libfontenc commit de1843aaf76015c9d99416f3122d169fe331b849
mkfontscale commit 87d628f8eec170ec13bb9feefb1ce05aed07d1d6
xwininfo commit 0c49f8f2bd56b1e77721e81030ea948386dcdf4e
fontconfig commit d6d5adeb7940c0d0beb86489c2a1c2ce59e5c044
mesa commit 4359954d842caa2a9f8d4b50d70ecc789884b68b
Diffstat (limited to 'mesalib/src/mesa/main/texstore.c')
-rw-r--r-- | mesalib/src/mesa/main/texstore.c | 1179 |
1 files changed, 113 insertions, 1066 deletions
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 50aa1fd5e..7039cdf81 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -73,6 +73,7 @@ #include "texstore.h" #include "enums.h" #include "glformats.h" +#include "pixeltransfer.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" @@ -87,577 +88,6 @@ enum { * Texture image storage function. */ typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS); - - -enum { - IDX_LUMINANCE = 0, - IDX_ALPHA, - IDX_INTENSITY, - IDX_LUMINANCE_ALPHA, - IDX_RGB, - IDX_RGBA, - IDX_RED, - IDX_GREEN, - IDX_BLUE, - IDX_BGR, - IDX_BGRA, - IDX_ABGR, - IDX_RG, - MAX_IDX -}; - -#define MAP1(x) MAP4(x, ZERO, ZERO, ZERO) -#define MAP2(x,y) MAP4(x, y, ZERO, ZERO) -#define MAP3(x,y,z) MAP4(x, y, z, ZERO) -#define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE } - - -static const struct { - GLubyte format_idx; - GLubyte to_rgba[6]; - GLubyte from_rgba[6]; -} mappings[MAX_IDX] = -{ - { - IDX_LUMINANCE, - MAP4(0,0,0,ONE), - MAP1(0) - }, - - { - IDX_ALPHA, - MAP4(ZERO, ZERO, ZERO, 0), - MAP1(3) - }, - - { - IDX_INTENSITY, - MAP4(0, 0, 0, 0), - MAP1(0), - }, - - { - IDX_LUMINANCE_ALPHA, - MAP4(0,0,0,1), - MAP2(0,3) - }, - - { - IDX_RGB, - MAP4(0,1,2,ONE), - MAP3(0,1,2) - }, - - { - IDX_RGBA, - MAP4(0,1,2,3), - MAP4(0,1,2,3), - }, - - { - IDX_RED, - MAP4(0, ZERO, ZERO, ONE), - MAP1(0), - }, - - { - IDX_GREEN, - MAP4(ZERO, 0, ZERO, ONE), - MAP1(1), - }, - - { - IDX_BLUE, - MAP4(ZERO, ZERO, 0, ONE), - MAP1(2), - }, - - { - IDX_BGR, - MAP4(2,1,0,ONE), - MAP3(2,1,0) - }, - - { - IDX_BGRA, - MAP4(2,1,0,3), - MAP4(2,1,0,3) - }, - - { - IDX_ABGR, - MAP4(3,2,1,0), - MAP4(3,2,1,0) - }, - - { - IDX_RG, - MAP4(0, 1, ZERO, ONE), - MAP2(0, 1) - }, -}; - - - -/** - * Convert a GL image format enum to an IDX_* value (see above). - */ -static int -get_map_idx(GLenum value) -{ - switch (value) { - 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 %s", - _mesa_lookup_enum_by_nr(value)); - return 0; - } -} - - -/** - * When promoting texture formats (see below) we need to compute the - * mapping of dest components back to source components. - * This function does that. - * \param inFormat the incoming format of the texture - * \param outFormat the final texture format - * \return map[6] a full 6-component map - */ -static void -compute_component_mapping(GLenum inFormat, GLenum outFormat, - GLubyte *map) -{ - const int inFmt = get_map_idx(inFormat); - const int outFmt = get_map_idx(outFormat); - const GLubyte *in2rgba = mappings[inFmt].to_rgba; - const GLubyte *rgba2out = mappings[outFmt].from_rgba; - int i; - - for (i = 0; i < 4; i++) - map[i] = in2rgba[rgba2out[i]]; - - map[ZERO] = ZERO; - map[ONE] = ONE; - -#if 0 - printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n", - inFormat, _mesa_lookup_enum_by_nr(inFormat), - outFormat, _mesa_lookup_enum_by_nr(outFormat), - map[0], - map[1], - map[2], - map[3], - map[4], - map[5]); -#endif -} - - -/** - * Make a temporary (color) texture image with GLfloat components. - * Apply all needed pixel unpacking and pixel transfer operations. - * Note that there are both logicalBaseFormat and textureBaseFormat parameters. - * Suppose the user specifies GL_LUMINANCE as the internal texture format - * but the graphics hardware doesn't support luminance textures. So, we might - * use an RGB hardware format instead. - * If logicalBaseFormat != textureBaseFormat we have some extra work to do. - * - * \param ctx the rendering context - * \param dims image dimensions: 1, 2 or 3 - * \param logicalBaseFormat basic texture derived from the user's - * internal texture format value - * \param textureBaseFormat the actual basic format of the texture - * \param srcWidth source image width - * \param srcHeight source image height - * \param srcDepth source image depth - * \param srcFormat source image format - * \param srcType source image type - * \param srcAddr source image address - * \param srcPacking source image pixel packing - * \return resulting image with format = textureBaseFormat and type = GLfloat. - */ -GLfloat * -_mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps) -{ - GLfloat *tempImage; - const GLint components = _mesa_components_in_format(logicalBaseFormat); - const GLint srcStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLfloat *dst; - GLint img, row; - - ASSERT(dims >= 1 && dims <= 3); - - ASSERT(logicalBaseFormat == GL_RGBA || - logicalBaseFormat == GL_RGB || - logicalBaseFormat == GL_RG || - logicalBaseFormat == GL_RED || - logicalBaseFormat == GL_LUMINANCE_ALPHA || - logicalBaseFormat == GL_LUMINANCE || - logicalBaseFormat == GL_ALPHA || - logicalBaseFormat == GL_INTENSITY || - logicalBaseFormat == GL_DEPTH_COMPONENT); - - ASSERT(textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_RGB || - textureBaseFormat == GL_RG || - textureBaseFormat == GL_RED || - textureBaseFormat == GL_LUMINANCE_ALPHA || - textureBaseFormat == GL_LUMINANCE || - textureBaseFormat == GL_ALPHA || - textureBaseFormat == GL_INTENSITY || - textureBaseFormat == GL_DEPTH_COMPONENT); - - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLfloat)); - if (!tempImage) - return NULL; - - dst = tempImage; - for (img = 0; img < srcDepth; img++) { - const GLubyte *src - = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat, - dst, srcFormat, srcType, src, - srcPacking, transferOps); - dst += srcWidth * components; - src += srcStride; - } - } - - if (logicalBaseFormat != textureBaseFormat) { - /* more work */ - GLint texComponents = _mesa_components_in_format(textureBaseFormat); - GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLfloat *newImage; - GLint i, n; - GLubyte map[6]; - - /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ - ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_LUMINANCE_ALPHA); - - /* The actual texture format should have at least as many components - * as the logical texture format. - */ - ASSERT(texComponents >= logComponents); - - newImage = malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLfloat)); - if (!newImage) { - free(tempImage); - return NULL; - } - - compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); - - n = srcWidth * srcHeight * srcDepth; - for (i = 0; i < n; i++) { - GLint k; - for (k = 0; k < texComponents; k++) { - GLint j = map[k]; - if (j == ZERO) - newImage[i * texComponents + k] = 0.0F; - else if (j == ONE) - newImage[i * texComponents + k] = 1.0F; - else - newImage[i * texComponents + k] = tempImage[i * logComponents + j]; - } - } - - free(tempImage); - tempImage = newImage; - } - - return tempImage; -} - - -/** - * Make temporary image with uint pixel values. Used for unsigned - * integer-valued textures. - */ -static GLuint * -make_temp_uint_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) -{ - GLuint *tempImage; - const GLint components = _mesa_components_in_format(logicalBaseFormat); - const GLint srcStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLuint *dst; - GLint img, row; - - ASSERT(dims >= 1 && dims <= 3); - - ASSERT(logicalBaseFormat == GL_RGBA || - logicalBaseFormat == GL_RGB || - logicalBaseFormat == GL_RG || - logicalBaseFormat == GL_RED || - logicalBaseFormat == GL_LUMINANCE_ALPHA || - logicalBaseFormat == GL_LUMINANCE || - logicalBaseFormat == GL_INTENSITY || - logicalBaseFormat == GL_ALPHA); - - ASSERT(textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_RGB || - textureBaseFormat == GL_RG || - textureBaseFormat == GL_RED || - textureBaseFormat == GL_LUMINANCE_ALPHA || - textureBaseFormat == GL_LUMINANCE || - textureBaseFormat == GL_INTENSITY || - textureBaseFormat == GL_ALPHA); - - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLuint)); - if (!tempImage) - return NULL; - - dst = tempImage; - for (img = 0; img < srcDepth; img++) { - const GLubyte *src - = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat, - dst, srcFormat, srcType, src, - srcPacking); - dst += srcWidth * components; - src += srcStride; - } - } - - if (logicalBaseFormat != textureBaseFormat) { - /* more work */ - GLint texComponents = _mesa_components_in_format(textureBaseFormat); - GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLuint *newImage; - GLint i, n; - GLubyte map[6]; - - /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ - ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_LUMINANCE_ALPHA); - - /* The actual texture format should have at least as many components - * as the logical texture format. - */ - ASSERT(texComponents >= logComponents); - - newImage = malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLuint)); - if (!newImage) { - free(tempImage); - return NULL; - } - - compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); - - n = srcWidth * srcHeight * srcDepth; - for (i = 0; i < n; i++) { - GLint k; - for (k = 0; k < texComponents; k++) { - GLint j = map[k]; - if (j == ZERO) - newImage[i * texComponents + k] = 0; - else if (j == ONE) - newImage[i * texComponents + k] = 1; - else - newImage[i * texComponents + k] = tempImage[i * logComponents + j]; - } - } - - free(tempImage); - tempImage = newImage; - } - - return tempImage; -} - - - -/** - * Make a temporary (color) texture image with GLubyte components. - * Apply all needed pixel unpacking and pixel transfer operations. - * Note that there are both logicalBaseFormat and textureBaseFormat parameters. - * Suppose the user specifies GL_LUMINANCE as the internal texture format - * but the graphics hardware doesn't support luminance textures. So, we might - * use an RGB hardware format instead. - * If logicalBaseFormat != textureBaseFormat we have some extra work to do. - * - * \param ctx the rendering context - * \param dims image dimensions: 1, 2 or 3 - * \param logicalBaseFormat basic texture derived from the user's - * internal texture format value - * \param textureBaseFormat the actual basic format of the texture - * \param srcWidth source image width - * \param srcHeight source image height - * \param srcDepth source image depth - * \param srcFormat source image format - * \param srcType source image type - * \param srcAddr source image address - * \param srcPacking source image pixel packing - * \return resulting image with format = textureBaseFormat and type = GLubyte. - */ -GLubyte * -_mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) -{ - GLuint transferOps = ctx->_ImageTransferState; - const GLint components = _mesa_components_in_format(logicalBaseFormat); - GLint img, row; - GLubyte *tempImage, *dst; - - ASSERT(dims >= 1 && dims <= 3); - - ASSERT(logicalBaseFormat == GL_RGBA || - logicalBaseFormat == GL_RGB || - logicalBaseFormat == GL_RG || - logicalBaseFormat == GL_RED || - logicalBaseFormat == GL_LUMINANCE_ALPHA || - logicalBaseFormat == GL_LUMINANCE || - logicalBaseFormat == GL_ALPHA || - logicalBaseFormat == GL_INTENSITY); - - ASSERT(textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_RGB || - textureBaseFormat == GL_RG || - textureBaseFormat == GL_RED || - textureBaseFormat == GL_LUMINANCE_ALPHA || - textureBaseFormat == GL_LUMINANCE || - textureBaseFormat == GL_ALPHA || - textureBaseFormat == GL_INTENSITY); - - /* unpack and transfer the source image */ - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLubyte)); - if (!tempImage) { - return NULL; - } - - dst = tempImage; - for (img = 0; img < srcDepth; img++) { - const GLint srcStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - const GLubyte *src = - (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst, - srcFormat, srcType, src, srcPacking, - transferOps); - dst += srcWidth * components; - src += srcStride; - } - } - - if (logicalBaseFormat != textureBaseFormat) { - /* one more conversion step */ - GLint texComponents = _mesa_components_in_format(textureBaseFormat); - GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLubyte *newImage; - GLint i, n; - GLubyte map[6]; - - /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ - ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_LUMINANCE_ALPHA); - - /* The actual texture format should have at least as many components - * as the logical texture format. - */ - ASSERT(texComponents >= logComponents); - - newImage = malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLubyte)); - if (!newImage) { - free(tempImage); - return NULL; - } - - compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); - - n = srcWidth * srcHeight * srcDepth; - for (i = 0; i < n; i++) { - GLint k; - for (k = 0; k < texComponents; k++) { - GLint j = map[k]; - if (j == ZERO) - newImage[i * texComponents + k] = 0; - else if (j == ONE) - newImage[i * texComponents + k] = 255; - else - newImage[i * texComponents + k] = tempImage[i * logComponents + j]; - } - } - - free(tempImage); - tempImage = newImage; - } - - return tempImage; -} - - static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE }; static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE }; static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE }; @@ -716,46 +146,6 @@ memcpy_texture(struct gl_context *ctx, /** - * General-case function for storing a color texture images with - * components that can be represented with ubytes. Example destination - * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565. - */ -static GLboolean -store_ubyte_texture(TEXSTORE_PARAMS) -{ - const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte); - GLubyte *tempImage, *src; - GLint img; - - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - GL_RGBA, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - 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, - src, srcRowStride, - dstSlices[img], dstRowStride); - src += srcHeight * srcRowStride; - } - free(tempImage); - - return GL_TRUE; -} - - - - -/** * Store a 32-bit integer or float depth component texture image. */ static GLboolean @@ -888,56 +278,6 @@ _mesa_texstore_z16(TEXSTORE_PARAMS) /** - * Store an rgb565 or rgb565_rev texture image. - */ -static GLboolean -_mesa_texstore_rgb565(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_B5G6R5_UNORM || - dstFormat == MESA_FORMAT_R5G6B5_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGB && - srcFormat == GL_RGB && - srcType == GL_UNSIGNED_BYTE && - dims == 2) { - /* do optimized tex store */ - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - const GLubyte *src = (const GLubyte *) - _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, - srcFormat, srcType, 0, 0, 0); - GLubyte *dst = dstSlices[0]; - GLint row, col; - for (row = 0; row < srcHeight; row++) { - const GLubyte *srcUB = (const GLubyte *) src; - GLushort *dstUS = (GLushort *) dst; - /* check for byteswapped format */ - 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; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] ); - srcUB += 3; - } - } - dst += dstRowStride; - src += srcRowStride; - } - return GL_TRUE; - } else { - return GL_FALSE; - } -} - - -/** * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. */ static GLboolean @@ -1245,119 +585,6 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) } static GLboolean -_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UINT); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* 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, col; - 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++) { - GLuint *dstUI = (GLuint *) dstRow; - if (is_unsigned) { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = MIN2(src[RCOMP], 0x3ff); - g = MIN2(src[GCOMP], 0x3ff); - b = MIN2(src[BCOMP], 0x3ff); - a = MIN2(src[ACOMP], 0x003); - dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); - src += 4; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); - g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); - b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); - a = CLAMP((GLint) src[ACOMP], 0, 0x003); - dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UINT); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* 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, col; - 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++) { - GLuint *dstUI = (GLuint *) dstRow; - if (is_unsigned) { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = MIN2(src[RCOMP], 0x3ff); - g = MIN2(src[GCOMP], 0x3ff); - b = MIN2(src[BCOMP], 0x3ff); - a = MIN2(src[ACOMP], 0x003); - dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); - src += 4; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); - g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); - b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); - a = CLAMP((GLint) src[ACOMP], 0, 0x003); - dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -static GLboolean texstore_depth_stencil(TEXSTORE_PARAMS) { static StoreTexImageFunc table[MESA_FORMAT_COUNT]; @@ -1446,329 +673,149 @@ texstore_compressed(TEXSTORE_PARAMS) 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) +texstore_rgba(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; - - if (srcFormat == GL_COLOR_INDEX) - return GL_FALSE; - - if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) - 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; + void *tempImage = NULL, *tempRGBA = NULL; + int srcRowStride, img; + GLubyte *src, *dst; + uint32_t srcMesaFormat; + uint8_t rebaseSwizzle[4]; + bool needRebase; + bool transferOpsDone = false; + + /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case + * and _mesa_format_convert does not support it. In this case the we only + * allow conversions between YCBCR formats and it is mostly a memcpy. + */ + if (dstFormat == MESA_FORMAT_YCBCR || dstFormat == MESA_FORMAT_YCBCR_REV) { + return _mesa_texstore_ycbcr(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); } - 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]]]]; - } + /* We have to deal with GL_COLOR_INDEX manually because + * _mesa_format_convert does not handle this format. So what we do here is + * convert it to RGBA ubyte first and then convert from that to dst as usual. + */ + if (srcFormat == GL_COLOR_INDEX) { + /* Notice that this will already handle byte swapping if necessary */ + tempImage = + _mesa_unpack_color_index_to_rgba_ubyte(ctx, dims, + srcAddr, srcFormat, srcType, + srcWidth, srcHeight, srcDepth, + srcPacking, + ctx->_ImageTransferState); + if (!tempImage) + return GL_FALSE; - /* Is it normalized? */ - normalized |= !_mesa_is_enum_format_integer(srcFormat); + /* _mesa_unpack_color_index_to_rgba_ubyte has handled transferops + * if needed. + */ + transferOpsDone = true; - 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; - } + /* Now we only have to adjust our src info for a conversion from + * the RGBA ubyte and then we continue as usual. + */ + srcAddr = tempImage; + srcFormat = GL_RGBA; + srcType = GL_UNSIGNED_BYTE; + } else if (srcPacking->SwapBytes) { + /* We have to handle byte-swapping scenarios before calling + * _mesa_format_convert + */ + GLint swapSize = _mesa_sizeof_packed_type(srcType); + if (swapSize == 2 || swapSize == 4) { + int bytesPerPixel = _mesa_bytes_per_pixel(srcFormat, srcType); + int swapsPerPixel = bytesPerPixel / swapSize; + int elementCount = srcWidth * srcHeight * srcDepth; + assert(bytesPerPixel % swapSize == 0); + tempImage = malloc(elementCount * bytesPerPixel); + if (!tempImage) + return GL_FALSE; + if (swapSize == 2) + _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, + elementCount * swapsPerPixel); + else + _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, + elementCount * swapsPerPixel); + srcAddr = tempImage; } - 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 = + srcRowStride = _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. - */ + srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType); 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; + /* If we have transferOps then we need to convert to RGBA float first, + then apply transferOps, then do the conversion to dst + */ + if (!transferOpsDone && + _mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) { + /* Allocate RGBA float image */ + int elementCount = srcWidth * srcHeight * srcDepth; + tempRGBA = malloc(4 * elementCount * sizeof(float)); + if (!tempRGBA) { + free(tempImage); + free(tempRGBA); + return GL_FALSE; } - } - 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; + /* Convert from src to RGBA float */ + src = (GLubyte *) srcAddr; + dst = (GLubyte *) tempRGBA; + for (img = 0; img < srcDepth; img++) { + _mesa_format_convert(dst, RGBA32_FLOAT, 4 * srcWidth * sizeof(float), + src, srcMesaFormat, srcRowStride, + srcWidth, srcHeight, NULL); + src += srcHeight * srcRowStride; + dst += srcHeight * 4 * srcWidth * sizeof(float); } - } - free(tmp_row); - - return GL_TRUE; -} + /* Apply transferOps */ + _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState, elementCount, + (float(*)[4]) tempRGBA); -/** 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) { - free(tmp_row); - return GL_FALSE; + /* Now we have to adjust our src info for a conversion from + * the RGBA float image and then we continue as usual. + */ + srcAddr = tempRGBA; + srcFormat = GL_RGBA; + srcType = GL_FLOAT; + srcRowStride = srcWidth * 4 * sizeof(float); + srcMesaFormat = RGBA32_FLOAT; } - 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]]]; - } + src = (GLubyte *) + _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, + srcFormat, srcType, 0, 0, 0); - if (_mesa_is_type_unsigned(srcType)) { - tmp_type = GL_UNSIGNED_INT; + if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) { + needRebase = + _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat, + rebaseSwizzle); } else { - tmp_type = GL_INT; + needRebase = false; } 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; - } + _mesa_format_convert(dstSlices[img], dstFormat, dstRowStride, + src, srcMesaFormat, srcRowStride, + srcWidth, srcHeight, + needRebase ? rebaseSwizzle : NULL); + src += srcHeight * srcRowStride; } - free(tmp_row); + free(tempImage); + free(tempRGBA); 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, |