[Mesa-dev] [PATCH 2/6] mesa: Add decoding functions for GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
Brian Paul
brianp at vmware.com
Thu Oct 25 15:14:35 PDT 2012
On 10/24/2012 02:22 PM, Anuj Phogat wrote:
>
> Signed-off-by: Anuj Phogat<anuj.phogat at gmail.com>
> ---
> src/mesa/main/texcompress_etc.c | 179 ++++++++++++++++++++++++++++++++++-----
> src/mesa/main/texcompress_etc.h | 8 ++
> 2 files changed, 166 insertions(+), 21 deletions(-)
>
> diff --git a/src/mesa/main/texcompress_etc.c b/src/mesa/main/texcompress_etc.c
> index 168da1e..eb2ce1a 100644
> --- a/src/mesa/main/texcompress_etc.c
> +++ b/src/mesa/main/texcompress_etc.c
> @@ -48,6 +48,7 @@
>
> struct etc2_block {
> int flipped;
> + int opaque;
> int distance;
> uint64_t pixel_indices[2];
> const int *modifier_tables[2];
> @@ -85,6 +86,17 @@ static const int etc2_modifier_tables[16][8] = {
> { -3, -5, -7, -9, 2, 4, 6, 8},
> };
>
> +static const int etc2_modifier_tables_non_opaque[8][4] = {
> + { 0, 8, 0, -8},
> + { 0, 17, 0, -17},
> + { 0, 29, 0, -29},
> + { 0, 42, 0, -42},
> + { 0, 60, 0, -60},
> + { 0, 80, 0, -80},
> + { 0, 106, 0, -106},
> + { 0, 183, 0, -183}
> +};
> +
> /* define etc1_parse_block and etc. */
> #define UINT8_TYPE GLubyte
> #define TAG(x) x
> @@ -340,10 +352,12 @@ etc2_clamp3(int color)
> }
>
> static void
> -etc2_rgb8_parse_block(struct etc2_block *block, const GLubyte *src)
> +etc2_rgb8_parse_block(struct etc2_block *block,
> + const GLubyte *src,
> + GLboolean punchthrough_alpha)
> {
> unsigned i;
> - GLboolean diffbit = src[3]& 0x2;
> + GLboolean diffbit = false;
> static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
>
> const int R_plus_dR = (src[0]>> 3) + lookup[src[0]& 0x7];
> @@ -357,7 +371,12 @@ etc2_rgb8_parse_block(struct etc2_block *block, const GLubyte *src)
> block->is_h_mode = false;
> block->is_planar_mode = false;
>
> - if (!diffbit) {
> + if (punchthrough_alpha)
> + block->opaque = src[3]& 0x2;
> + else
> + diffbit = src[3]& 0x2;
> +
> + if (!diffbit&& !punchthrough_alpha) {
> /* individual mode */
> block->is_ind_mode = true;
>
> @@ -424,17 +443,21 @@ etc2_rgb8_parse_block(struct etc2_block *block, const GLubyte *src)
> block->distance);
> }
> }
> - else if (B_plus_dB< 0 || B_plus_dB> 31){
> + else if (B_plus_dB< 0 || B_plus_dB> 31) {
> /* Planar mode */
> block->is_planar_mode = true;
>
> + /* opaque bit must be set in planar mode */
> + if (block->opaque == 0)
> + block->opaque = 1;
> +
> for (i = 0; i< 3; i++) {
> block->base_colors[0][i] = etc2_base_color_o_planar(src, i);
> block->base_colors[1][i] = etc2_base_color_h_planar(src, i);
> block->base_colors[2][i] = etc2_base_color_v_planar(src, i);
> }
> }
> - else if (diffbit) {
> + else if (diffbit || punchthrough_alpha) {
> /* differential mode */
> block->is_diff_mode = true;
>
> @@ -448,9 +471,19 @@ etc2_rgb8_parse_block(struct etc2_block *block, const GLubyte *src)
> }
>
> if(block->is_ind_mode || block->is_diff_mode) {
> - /* pick modifier tables. same for etc1& etc2 textures */
> - block->modifier_tables[0] = etc1_modifier_tables[(src[3]>> 5)& 0x7];
> - block->modifier_tables[1] = etc1_modifier_tables[(src[3]>> 2)& 0x7];
> + int table1_idx = (src[3]>> 5)& 0x7;
> + int table2_idx = (src[3]>> 2)& 0x7;
> +
> + /* Use same modifier tables as for etc1 textures if opaque bit is set
> + * or if non punchthrough texture format
> + */
> + block->modifier_tables[0] = (block->opaque || !punchthrough_alpha) ?
> + etc1_modifier_tables[table1_idx] :
> + etc2_modifier_tables_non_opaque[table1_idx];
> + block->modifier_tables[1] = (block->opaque || !punchthrough_alpha) ?
> + etc1_modifier_tables[table2_idx] :
> + etc2_modifier_tables_non_opaque[table2_idx];
> +
> block->flipped = (src[3]& 0x1);
> }
>
> @@ -460,7 +493,8 @@ etc2_rgb8_parse_block(struct etc2_block *block, const GLubyte *src)
>
> static void
> etc2_rgb8_fetch_texel(const struct etc2_block *block,
> - int x, int y, GLubyte *dst)
> + int x, int y, GLubyte *dst,
> + GLboolean punchthrough_alpha)
> {
> const GLubyte *base_color;
> int modifier, bit, idx, blk;
> @@ -471,6 +505,16 @@ etc2_rgb8_fetch_texel(const struct etc2_block *block,
> ((block->pixel_indices[0]>> (bit))& 0x1);
>
> if (block->is_ind_mode || block->is_diff_mode) {
> + /* check for punchthrough_alpha format */
> + if (punchthrough_alpha) {
> + if (block->opaque == 0&& idx == 2) {
> + dst[0] = dst[1] = dst[2] = dst[3] = 0;
> + return;
> + }
The indentation looks funny there and in the previous chunk (mixing
tabs & spaces?).
> + else
> + dst[3] = 255;
> + }
> +
> /* Use pixel index and subblock to get the modifier */
> blk = (block->flipped) ? (y>= 2) : (x>= 2);
> base_color = block->base_colors[blk];
> @@ -481,6 +525,16 @@ etc2_rgb8_fetch_texel(const struct etc2_block *block,
> dst[2] = etc2_clamp(base_color[2] + modifier);
> }
> else if (block->is_t_mode || block->is_h_mode) {
> + /* check for punchthrough_alpha format */
> + if (punchthrough_alpha) {
> + if (block->opaque == 0&& idx == 2) {
> + dst[0] = dst[1] = dst[2] = dst[3] = 0;
> + return;
> + }
> + else
> + dst[3] = 255;
> + }
> +
> /* Use pixel index to pick one of the paint colors */
> dst[0] = block->paint_colors[idx][0];
> dst[1] = block->paint_colors[idx][1];
> @@ -507,7 +561,11 @@ etc2_rgb8_fetch_texel(const struct etc2_block *block,
> dst[0] = etc2_clamp(red);
> dst[1] = etc2_clamp(green);
> dst[2] = etc2_clamp(blue);
> - }
> +
> + /* check for punchthrough_alpha format */
> + if (punchthrough_alpha)
> + dst[3] = 255;
> + }
> }
>
> static void
> @@ -526,7 +584,8 @@ static void
> etc2_rgba8_fetch_texel(const struct etc2_block *block,
> int x, int y, GLubyte *dst)
> {
> - etc2_rgb8_fetch_texel(block, x, y, dst);
> + etc2_rgb8_fetch_texel(block, x, y, dst,
> + false /* punchthrough_alpha */);
> etc2_alpha8_fetch_texel(block, x, y, dst);
> }
>
> @@ -608,8 +667,8 @@ static void
> etc2_rgba8_parse_block(struct etc2_block *block, const GLubyte *src)
> {
> /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
> - etc2_rgb8_parse_block(block, src + 8);
> -
> + etc2_rgb8_parse_block(block, src + 8,
> + false /* punchthrough_alpha */);
> /* Parse Alpha component */
> etc2_alpha8_parse_block(block, src);
> }
> @@ -651,12 +710,14 @@ etc2_unpack_rgb8(uint8_t *dst_row,
> const uint8_t *src = src_row;
>
> for (x = 0; x< width; x+= bw) {
> - etc2_rgb8_parse_block(&block, src);
> + etc2_rgb8_parse_block(&block, src,
> + false /* punchthrough_alpha */);
>
> for (j = 0; j< bh; j++) {
> uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
> for (i = 0; i< bw; i++) {
> - etc2_rgb8_fetch_texel(&block, i, j, dst);
> + etc2_rgb8_fetch_texel(&block, i, j, dst,
> + false /* punchthrough_alpha */);
> dst[3] = 255;
> dst += comps;
> }
> @@ -685,12 +746,14 @@ etc2_unpack_srgb8(uint8_t *dst_row,
> const uint8_t *src = src_row;
>
> for (x = 0; x< width; x+= bw) {
> - etc2_rgb8_parse_block(&block, src);
> + etc2_rgb8_parse_block(&block, src,
> + false /* punchthrough_alpha */);
>
> for (j = 0; j< bh; j++) {
> uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
> for (i = 0; i< bw; i++) {
> - etc2_rgb8_fetch_texel(&block, i, j, dst);
> + etc2_rgb8_fetch_texel(&block, i, j, dst,
> + false /* punchthrough_alpha */);
> dst[3] = 255;
>
> /* sRGB color space to linear color space conversion */
> @@ -955,6 +1018,40 @@ etc2_unpack_signed_rg11(uint8_t *dst_row,
> }
> }
>
> +static void
> +etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row,
> + unsigned dst_stride,
> + const uint8_t *src_row,
> + unsigned src_stride,
> + unsigned width,
> + unsigned height)
> +{
> + const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
> + struct etc2_block block;
> + unsigned x, y, i, j;
> +
> + for (y = 0; y< height; y += bh) {
> + const uint8_t *src = src_row;
> +
> + for (x = 0; x< width; x+= bw) {
> + etc2_rgb8_parse_block(&block, src,
> + true /* punchthrough_alpha */);
> + for (j = 0; j< bh; j++) {
> + uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
> + for (i = 0; i< bw; i++) {
> + etc2_rgb8_fetch_texel(&block, i, j, dst,
> + true /* punchthrough_alpha */);
> + dst += comps;
> + }
> + }
> +
> + src += bs;
> + }
> +
> + src_row += src_stride;
> + }
> +}
> +
> /* ETC2 texture formats are valid in glCompressedTexImage2D and
> * glCompressedTexSubImage2D functions */
> GLboolean
> @@ -1021,6 +1118,14 @@ _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS)
> return GL_FALSE;
> }
>
> +GLboolean
> +_mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS)
> +{
> + ASSERT(0);
> +
> + return GL_FALSE;
> +}
> +
> void
> _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
> GLint i, GLint j, GLint k, GLfloat *texel)
> @@ -1032,8 +1137,10 @@ _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
> src = (const GLubyte *) texImage->Map +
> (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
>
> - etc2_rgb8_parse_block(&block, src);
> - etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
> + etc2_rgb8_parse_block(&block, src,
> + false /* punchthrough_alpha */);
> + etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
> + false /* punchthrough_alpha */);
>
> texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
> texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
> @@ -1052,8 +1159,10 @@ _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image *texImage,
> src = (const GLubyte *) texImage->Map +
> (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
>
> - etc2_rgb8_parse_block(&block, src);
> - etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst);
> + etc2_rgb8_parse_block(&block, src,
> + false /* punchthrough_alpha */);
> + etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
> + false /* punchthrough_alpha */);
>
> texel[RCOMP] = decode_srgb(UBYTE_TO_FLOAT(dst[0]));
> texel[GCOMP] = decode_srgb(UBYTE_TO_FLOAT(dst[1]));
> @@ -1185,6 +1294,29 @@ _mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct swrast_texture_image *t
> texel[GCOMP] = SHORT_TO_FLOAT(dst[1]);
> }
>
> +void
> +_mesa_fetch_texel_2d_f_etc2_rgb8_punchthrough_alpha1(
> + const struct swrast_texture_image *texImage,
> + GLint i, GLint j,
> + GLint k, GLfloat *texel)
> +{
> + struct etc2_block block;
> + GLubyte dst[4];
> + const GLubyte *src;
> +
> + src = (const GLubyte *) texImage->Map +
> + (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
> +
> + etc2_rgb8_parse_block(&block, src,
> + true /* punchthrough alpha */);
> + etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
> + true /* punchthrough alpha */);
> + texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
> + texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
> + texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
> + texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
> +}
> +
> /**
> * Decode texture data in any one of following formats:
> * `MESA_FORMAT_ETC2_RGB8`
> @@ -1195,6 +1327,7 @@ _mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct swrast_texture_image *t
> * `MESA_FORMAT_ETC2_RG11_EAC`
> * `MESA_FORMAT_ETC2_SIGNED_R11_EAC`
> * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC`
> + * `MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1`
> *
> * The size of the source data must be a multiple of the ETC2 block size
> * even if the texture image's dimensions are not aligned to 4.
> @@ -1245,4 +1378,8 @@ _mesa_unpack_etc2_format(uint8_t *dst_row,
> etc2_unpack_signed_rg11(dst_row, dst_stride,
> src_row, src_stride,
> src_width, src_height);
> + else if (format == MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1)
> + etc2_unpack_rgb8_punchthrough_alpha1(dst_row, dst_stride,
> + src_row, src_stride,
> + src_width, src_height);
> }
> diff --git a/src/mesa/main/texcompress_etc.h b/src/mesa/main/texcompress_etc.h
> index d12a145..b9e4d85 100644
> --- a/src/mesa/main/texcompress_etc.h
> +++ b/src/mesa/main/texcompress_etc.h
> @@ -58,6 +58,9 @@ _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS);
> GLboolean
> _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS);
>
> +GLboolean
> +_mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS);
> +
> void
> _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage,
> GLint i, GLint j, GLint k, GLfloat *texel);
> @@ -92,6 +95,11 @@ _mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct
> GLint i, GLint j,
> GLint k, GLfloat *texel);
> void
> +_mesa_fetch_texel_2d_f_etc2_rgb8_punchthrough_alpha1(
> + const struct swrast_texture_image *texImage,
> + GLint i, GLint j,
> + GLint k, GLfloat *texel);
> +void
> _mesa_etc1_unpack_rgba8888(uint8_t *dst_row,
> unsigned dst_stride,
> const uint8_t *src_row,
More information about the mesa-dev
mailing list