Add function _mesa_etc1_image_decode_to_abgr8888(). It is intended to be used by glCompressedTexSubImage2D to translate ETC1 textures into ABGR.
Signed-off-by: Chad Versace <chad.vers...@linux.intel.com> --- src/mesa/main/texcompress_etc.c | 82 +++++++++++++++++++++++++++++++++++++++++ src/mesa/main/texcompress_etc.h | 6 +++ 2 files changed, 88 insertions(+) diff --git a/src/mesa/main/texcompress_etc.c b/src/mesa/main/texcompress_etc.c index e3b2e83..d84ee0e 100644 --- a/src/mesa/main/texcompress_etc.c +++ b/src/mesa/main/texcompress_etc.c @@ -178,3 +178,85 @@ _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage, texel[BCOMP] = UBYTE_TO_FLOAT(bgr888[2]); texel[ACOMP] = 1.0f; } + +static int +align(int x, int m) +{ + return (m * x + m - 1) / m; +} + +/** + * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to + * `MESA_FORMAT_ABGR8888`. + * + * The size of the source data must be a multiple of the ETC1 block size, + * which is 8, even if the texture image's dimensions are not aligned to 4. + * From the GL_OES_compressed_ETC1_RGB8_texture spec: + * The texture is described as a number of 4x4 pixel blocks. If the + * texture (or a particular mip-level) is smaller than 4 pixels in + * any dimension (such as a 2x2 or a 8x1 texture), the texture is + * found in the upper left part of the block(s), and the rest of the + * pixels are not used. For instance, a texture of size 4x2 will be + * placed in the upper half of a 4x4 block, and the lower half of the + * pixels in the block will not be accessed. + * + * \param src_width in pixels + * \param src_height in pixels + * \param dst_rowstride in bytes + */ +void +_mesa_etc1_image_decode_to_abgr8888(const uint8_t *src, + int src_width, + int src_height, + uint8_t *dst, + int dst_rowstride) +{ + /* An XRGB pixel is 4 bytes. */ + const int pixel_bytes = 4; + + /* A block contains 4x4 pixels. */ + const int block_width = 4; + const int block_height = 4; + + /* A block contains 8 bytes. */ + const int block_bytes = 8; + + /* The stride in units of blocks. */ + const int block_stride = align(src_width, block_width) / block_width; + + /* The block being decoded. */ + int block_x; + int block_y; + + /* Iterate over each block. */ + for (block_y = 0; block_y * block_height < src_height; ++block_y) { + for (block_x = 0; block_x * block_width < src_width; ++block_x) { + struct etc1_block block; + + /* The pixel's position relative to the block's base. */ + int pixel_x; + int pixel_y; + + const uint8_t *src_block_base = + src + block_bytes * (block_y * block_stride + block_x); + + uint8_t *dst_block_base = dst + + block_y * block_height * dst_rowstride + + block_x * block_width * pixel_bytes; + + etc1_parse_block(&block, src_block_base); + + /* Iterate over each pixel in block. */ + for (pixel_y = 0; pixel_y < block_height; ++pixel_y) { + for (pixel_x = 0; pixel_x < block_width; ++pixel_x) { + uint8_t *dst_texel = dst_block_base + + pixel_y * dst_rowstride + + pixel_x * pixel_bytes; + + etc1_fetch_texel(&block, pixel_x, pixel_y, dst_texel); + dst_texel[3] = 0xff; + } + } + } + } +} diff --git a/src/mesa/main/texcompress_etc.h b/src/mesa/main/texcompress_etc.h index 8e8427f..552a7bd 100644 --- a/src/mesa/main/texcompress_etc.h +++ b/src/mesa/main/texcompress_etc.h @@ -36,5 +36,11 @@ _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS); void _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel); +void +_mesa_etc1_image_decode_to_abgr8888(const uint8_t *src, + int src_width, + int src_height, + uint8_t *dst, + int dst_rowstride); #endif -- 1.7.11.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev