[Mesa-dev] [PATCH 08/27] mesa: Add decoding functions for GL_COMPRESSED_SRGB8_ETC2
Ian Romanick
idr at freedesktop.org
Tue Nov 6 15:23:09 PST 2012
On 10/19/2012 04:28 PM, Anuj Phogat wrote:
> Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
> ---
> src/mesa/main/texcompress_etc.c | 96 +++++++++++++++++++++++++++++++++++++--
> src/mesa/main/texcompress_etc.h | 7 +++
> 2 files changed, 99 insertions(+), 4 deletions(-)
>
> diff --git a/src/mesa/main/texcompress_etc.c b/src/mesa/main/texcompress_etc.c
> index 8294144..6589c8d 100644
> --- a/src/mesa/main/texcompress_etc.c
> +++ b/src/mesa/main/texcompress_etc.c
> @@ -459,6 +459,20 @@ etc2_rgb8_fetch_texel(const struct etc2_block *block,
> }
> }
>
> +/**
> + * Convert from sRGB color space to linear color space, using the
> + * formula from the GL 3.0 spec, section 4.1.8 (sRGB Texture Color
> + * Conversion).
> + */
> +static float
> +decode_srgb(float cs)
> +{
> + if (cs <= 0.0405)
> + return cs / 12.92;
> + else
> + return pow((cs + 0.055) / 1.055, 2.4);
> +}
> +
Isn't there already some code for sRGB conversion? It seems like there
should be to support GL_SRGB8 textures.
> static void
> etc2_unpack_rgb8(uint8_t *dst_row,
> unsigned dst_stride,
> @@ -493,6 +507,46 @@ etc2_unpack_rgb8(uint8_t *dst_row,
> }
> }
>
> +static void
> +etc2_unpack_srgb8(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);
> +
> + 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);
> + dst[3] = 255;
> +
> + /* sRGB color space to linear color space conversion */
> + dst[0] = FLOAT_TO_UBYTE(decode_srgb(UBYTE_TO_FLOAT(dst[0])));
> + dst[1] = FLOAT_TO_UBYTE(decode_srgb(UBYTE_TO_FLOAT(dst[1])));
> + dst[2] = FLOAT_TO_UBYTE(decode_srgb(UBYTE_TO_FLOAT(dst[2])));
> + dst[3] = FLOAT_TO_UBYTE(decode_srgb(1.0f));
> +
> + dst += comps;
> + }
> + }
> + src += bs;
> + }
> +
> + src_row += src_stride;
> + }
> +}
> +
> /* ETC2 texture formats are valid in glCompressedTexImage2D and
> * glCompressedTexSubImage2D functions */
> GLboolean
> @@ -503,6 +557,14 @@ _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
> return GL_FALSE;
> }
>
> +GLboolean
> +_mesa_texstore_etc2_srgb8(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)
> @@ -523,9 +585,30 @@ _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
> texel[ACOMP] = 1.0f;
> }
>
> +void
> +_mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image *texImage,
> + GLint i, GLint j, GLint k, GLfloat *texel)
> +{
> + struct etc2_block block;
> + GLubyte dst[3];
> + const GLubyte *src;
> +
> + 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);
> +
> + texel[RCOMP] = decode_srgb(UBYTE_TO_FLOAT(dst[0]));
> + texel[GCOMP] = decode_srgb(UBYTE_TO_FLOAT(dst[1]));
> + texel[BCOMP] = decode_srgb(UBYTE_TO_FLOAT(dst[2]));
> + texel[ACOMP] = decode_srgb(1.0f);
> +}
>
> /**
> - * Decode texture data in format `MESA_FORMAT_ETC2_RGB8`
> + * Decode texture data in any one of following formats:
> + * `MESA_FORMAT_ETC2_RGB8`
> + * `MESA_FORMAT_ETC2_SRGB8`
> *
> * 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.
> @@ -544,7 +627,12 @@ _mesa_unpack_etc2_format(uint8_t *dst_row,
> unsigned src_height,
> gl_format format)
> {
> - etc2_unpack_rgb8(dst_row, dst_stride,
> - src_row, src_stride,
> - src_width, src_height);
> + if (format == MESA_FORMAT_ETC2_RGB8)
> + etc2_unpack_rgb8(dst_row, dst_stride,
> + src_row, src_stride,
> + src_width, src_height);
> + else if (format == MESA_FORMAT_ETC2_SRGB8)
> + etc2_unpack_srgb8(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 2508f5f..1dc1d5a 100644
> --- a/src/mesa/main/texcompress_etc.h
> +++ b/src/mesa/main/texcompress_etc.h
> @@ -37,6 +37,9 @@ _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS);
> GLboolean
> _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS);
>
> +GLboolean
> +_mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS);
> +
> void
> _mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage,
> GLint i, GLint j, GLint k, GLfloat *texel);
> @@ -44,6 +47,10 @@ void
> _mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
> GLint i, GLint j, GLint k, GLfloat *texel);
> void
> +_mesa_fetch_texel_2d_f_etc2_srgb8(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