On 07/09/2012 10:46 AM, Chad Versace wrote: > 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; > +}
Perhaps we should just move the ALIGN and ROUND_DOWN_TO macros from intel_context.h into macros.h? For reference, ALIGN() is: #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1)) Either way, this patch looks right to me. Reviewed-by: Kenneth Graunke <kenn...@whitecape.org> > + > +/** > + * 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 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev