X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexcompress_etc.c;h=d4650109857171d6c114ca05fd3370d513b27227;hb=3561d93668234225699734f3cc010defa0fda360;hp=b98ff029a2e465fc88b03f794022e1c22c676bb4;hpb=e06dcbfdc2c90b402cec257fd5e2fc843a7f708f;p=mesa.git diff --git a/src/mesa/main/texcompress_etc.c b/src/mesa/main/texcompress_etc.c index b98ff029a2e..d4650109857 100644 --- a/src/mesa/main/texcompress_etc.c +++ b/src/mesa/main/texcompress_etc.c @@ -38,13 +38,13 @@ */ #include -#include "mfeatures.h" #include "texcompress.h" #include "texcompress_etc.h" #include "texstore.h" #include "macros.h" -#include "swrast/s_context.h" #include "format_unpack.h" +#include "util/format_srgb.h" + struct etc2_block { int distance; @@ -108,30 +108,11 @@ GLboolean _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS) { /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */ - ASSERT(0); + assert(0); return GL_FALSE; } -void -_mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - struct etc1_block block; - GLubyte dst[3]; - const GLubyte *src; - - src = (const GLubyte *) texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; - - etc1_parse_block(&block, src); - etc1_fetch_texel(&block, i % 4, j % 4, dst); - - texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); - texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); - texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); - texel[ACOMP] = 1.0f; -} /** * Decode texture data in format `MESA_FORMAT_ETC1_RGB8` to @@ -231,7 +212,7 @@ etc2_base_color1_h_mode(const uint8_t *in, GLuint index) break; } return ((x << 4) | (x & 0xf)); - } +} static uint8_t etc2_base_color2_h_mode(const uint8_t *in, GLuint index) @@ -253,7 +234,7 @@ etc2_base_color2_h_mode(const uint8_t *in, GLuint index) break; } return ((x << 4) | (x & 0xf)); - } +} static uint8_t etc2_base_color_o_planar(const uint8_t *in, GLuint index) @@ -411,9 +392,10 @@ etc2_rgb8_parse_block(struct etc2_block *block, } } else if (G_plus_dG < 0 || G_plus_dG > 31){ + int base_color_1_value, base_color_2_value; + /* H mode */ block->is_h_mode = true; - int base_color_1_value, base_color_2_value; for(i = 0; i < 3; i++) { block->base_colors[0][i] = etc2_base_color1_h_mode(src, i); @@ -448,8 +430,7 @@ etc2_rgb8_parse_block(struct etc2_block *block, block->is_planar_mode = true; /* opaque bit must be set in planar mode */ - if (!block->opaque) - block->opaque = true; + block->opaque = true; for (i = 0; i < 3; i++) { block->base_colors[0][i] = etc2_base_color_o_planar(src, i); @@ -467,7 +448,7 @@ etc2_rgb8_parse_block(struct etc2_block *block, */ block->base_colors[0][i] = etc1_base_color_diff_hi(src[i]); block->base_colors[1][i] = etc1_base_color_diff_lo(src[i]); - } + } } if (block->is_ind_mode || block->is_diff_mode) { @@ -477,10 +458,10 @@ etc2_rgb8_parse_block(struct etc2_block *block, /* 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) ? + block->modifier_tables[0] = (!punchthrough_alpha || block->opaque) ? etc1_modifier_tables[table1_idx] : etc2_modifier_tables_non_opaque[table1_idx]; - block->modifier_tables[1] = (block->opaque || !punchthrough_alpha) ? + block->modifier_tables[1] = (!punchthrough_alpha || block->opaque) ? etc1_modifier_tables[table2_idx] : etc2_modifier_tables_non_opaque[table2_idx]; @@ -698,14 +679,25 @@ etc2_unpack_rgb8(uint8_t *dst_row, for (y = 0; y < height; y += bh) { const uint8_t *src = src_row; + /* + * Destination texture may not be a multiple of four texels in + * height. Compute a safe height to avoid writing outside the texture. + */ + const unsigned h = MIN2(bh, height - y); for (x = 0; x < width; x+= bw) { + /* + * Destination texture may not be a multiple of four texels in + * width. Compute a safe width to avoid writing outside the texture. + */ + const unsigned w = MIN2(bw, width - x); + etc2_rgb8_parse_block(&block, src, false /* punchthrough_alpha */); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, false /* punchthrough_alpha */); dst[3] = 255; @@ -735,17 +727,20 @@ etc2_unpack_srgb8(uint8_t *dst_row, for (y = 0; y < height; y += bh) { const uint8_t *src = src_row; + const unsigned h = MIN2(bh, height - y); for (x = 0; x < width; x+= bw) { + const unsigned w = MIN2(bw, width - x); etc2_rgb8_parse_block(&block, src, false /* punchthrough_alpha */); - for (j = 0; j < bh; j++) { + + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, false /* punchthrough_alpha */); - /* Convert to MESA_FORMAT_SARGB8 */ + /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ tmp = dst[0]; dst[0] = dst[2]; dst[2] = tmp; @@ -755,10 +750,10 @@ etc2_unpack_srgb8(uint8_t *dst_row, } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -779,22 +774,24 @@ etc2_unpack_rgba8(uint8_t *dst_row, for (y = 0; y < height; y += bh) { const uint8_t *src = src_row; + const unsigned h = MIN2(bh, height - y); for (x = 0; x < width; x+= bw) { + const unsigned w = MIN2(bw, width - x); etc2_rgba8_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_rgba8_fetch_texel(&block, i, j, dst); dst += comps; } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -815,17 +812,19 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row, uint8_t tmp; for (y = 0; y < height; y += bh) { + const unsigned h = MIN2(bh, height - y); const uint8_t *src = src_row; for (x = 0; x < width; x+= bw) { + const unsigned w = MIN2(bw, width - x); etc2_rgba8_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_rgba8_fetch_texel(&block, i, j, dst); - /* Convert to MESA_FORMAT_SARGB8 */ + /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ tmp = dst[0]; dst[0] = dst[2]; dst[2] = tmp; @@ -835,10 +834,10 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row, } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -857,23 +856,25 @@ etc2_unpack_r11(uint8_t *dst_row, unsigned x, y, i, j; for (y = 0; y < height; y += bh) { + const unsigned h = MIN2(bh, height - y); const uint8_t *src = src_row; for (x = 0; x < width; x+= bw) { + const unsigned w = MIN2(bw, width - x); etc2_r11_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_r11_fetch_texel(&block, i, j, dst); dst += comps * comp_size; } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -892,16 +893,18 @@ etc2_unpack_rg11(uint8_t *dst_row, unsigned x, y, i, j; for (y = 0; y < height; y += bh) { + const unsigned h = MIN2(bh, height - y); const uint8_t *src = src_row; for (x = 0; x < width; x+= bw) { + const unsigned w = MIN2(bw, width - x); /* red component */ etc2_r11_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_r11_fetch_texel(&block, i, j, dst); dst += comps * comp_size; } @@ -909,19 +912,19 @@ etc2_unpack_rg11(uint8_t *dst_row, /* green component */ etc2_r11_parse_block(&block, src + 8); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_r11_fetch_texel(&block, i, j, dst + comp_size); dst += comps * comp_size; } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -940,24 +943,26 @@ etc2_unpack_signed_r11(uint8_t *dst_row, unsigned x, y, i, j; for (y = 0; y < height; y += bh) { + const unsigned h = MIN2(bh, height - y); const uint8_t *src = src_row; for (x = 0; x < width; x+= bw) { + const unsigned w = MIN2(bw, width - x); etc2_r11_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_signed_r11_fetch_texel(&block, i, j, dst); dst += comps * comp_size; } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -976,16 +981,18 @@ etc2_unpack_signed_rg11(uint8_t *dst_row, unsigned x, y, i, j; for (y = 0; y < height; y += bh) { + const unsigned h = MIN2(bh, height - y); const uint8_t *src = src_row; for (x = 0; x < width; x+= bw) { + const unsigned w = MIN2(bw, width - x); /* red component */ etc2_r11_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_signed_r11_fetch_texel(&block, i, j, dst); dst += comps * comp_size; } @@ -993,19 +1000,19 @@ etc2_unpack_signed_rg11(uint8_t *dst_row, /* green component */ etc2_r11_parse_block(&block, src + 8); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_signed_r11_fetch_texel(&block, i, j, dst + comp_size); dst += comps * comp_size; } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -1021,14 +1028,16 @@ etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row, unsigned x, y, i, j; for (y = 0; y < height; y += bh) { + const unsigned h = MIN2(bh, height - y); const uint8_t *src = src_row; for (x = 0; x < width; x+= bw) { + const unsigned w = MIN2(bw, width - x); etc2_rgb8_parse_block(&block, src, true /* punchthrough_alpha */); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, true /* punchthrough_alpha */); dst += comps; @@ -1056,17 +1065,19 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row, uint8_t tmp; for (y = 0; y < height; y += bh) { + const unsigned h = MIN2(bh, height - y); const uint8_t *src = src_row; for (x = 0; x < width; x+= bw) { + const unsigned w = MIN2(bw, width - x); etc2_rgb8_parse_block(&block, src, true /* punchthrough_alpha */); - for (j = 0; j < bh; j++) { + for (j = 0; j < h; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < w; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, true /* punchthrough_alpha */); - /* Convert to MESA_FORMAT_SARGB8 */ + /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */ tmp = dst[0]; dst[0] = dst[2]; dst[2] = tmp; @@ -1088,7 +1099,7 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row, GLboolean _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } @@ -1096,7 +1107,7 @@ _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS) GLboolean _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } @@ -1104,7 +1115,7 @@ _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS) GLboolean _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } @@ -1112,7 +1123,7 @@ _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS) GLboolean _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } @@ -1120,7 +1131,7 @@ _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS) GLboolean _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } @@ -1128,7 +1139,7 @@ _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS) GLboolean _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } @@ -1136,7 +1147,7 @@ _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS) GLboolean _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } @@ -1144,7 +1155,7 @@ _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS) GLboolean _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } @@ -1152,7 +1163,7 @@ _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS) GLboolean _mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } @@ -1160,21 +1171,116 @@ _mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS) GLboolean _mesa_texstore_etc2_srgb8_punchthrough_alpha1(TEXSTORE_PARAMS) { - ASSERT(0); + assert(0); return GL_FALSE; } + +/** + * Decode texture data in any one of following formats: + * `MESA_FORMAT_ETC2_RGB8` + * `MESA_FORMAT_ETC2_SRGB8` + * `MESA_FORMAT_ETC2_RGBA8_EAC` + * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC` + * `MESA_FORMAT_ETC2_R11_EAC` + * `MESA_FORMAT_ETC2_RG11_EAC` + * `MESA_FORMAT_ETC2_SIGNED_R11_EAC` + * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC` + * `MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1` + * `MESA_FORMAT_ETC2_SRGB8_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. + * + * \param src_width in pixels + * \param src_height in pixels + * \param dst_stride in bytes + */ + void -_mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) +_mesa_unpack_etc2_format(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned src_width, + unsigned src_height, + mesa_format format) +{ + 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); + else if (format == MESA_FORMAT_ETC2_RGBA8_EAC) + etc2_unpack_rgba8(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + else if (format == MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC) + etc2_unpack_srgb8_alpha8(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + else if (format == MESA_FORMAT_ETC2_R11_EAC) + etc2_unpack_r11(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + else if (format == MESA_FORMAT_ETC2_RG11_EAC) + etc2_unpack_rg11(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + else if (format == MESA_FORMAT_ETC2_SIGNED_R11_EAC) + etc2_unpack_signed_r11(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + else if (format == MESA_FORMAT_ETC2_SIGNED_RG11_EAC) + 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); + else if (format == MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1) + etc2_unpack_srgb8_punchthrough_alpha1(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); +} + + + +static void +fetch_etc1_rgb8(const GLubyte *map, + GLint rowStride, GLint i, GLint j, + GLfloat *texel) +{ + struct etc1_block block; + GLubyte dst[3]; + const GLubyte *src; + + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; + + etc1_parse_block(&block, src); + etc1_fetch_texel(&block, i % 4, j % 4, dst); + + texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]); + texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]); + texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]); + texel[ACOMP] = 1.0f; +} + + +static void +fetch_etc2_rgb8(const GLubyte *map, + GLint rowStride, GLint i, GLint j, GLfloat *texel) { struct etc2_block block; uint8_t dst[3]; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; etc2_rgb8_parse_block(&block, src, false /* punchthrough_alpha */); @@ -1187,38 +1293,36 @@ _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) +static void +fetch_etc2_srgb8(const GLubyte *map, + GLint rowStride, GLint i, GLint j, GLfloat *texel) { struct etc2_block block; uint8_t dst[3]; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; etc2_rgb8_parse_block(&block, src, false /* punchthrough_alpha */); etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, false /* punchthrough_alpha */); - texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]); - texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]); - texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); texel[ACOMP] = 1.0f; } -void -_mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) +static void +fetch_etc2_rgba8_eac(const GLubyte *map, + GLint rowStride, GLint i, GLint j, GLfloat *texel) { struct etc2_block block; uint8_t dst[4]; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; etc2_rgba8_parse_block(&block, src); etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst); @@ -1229,38 +1333,34 @@ _mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image *texImag texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); } -void -_mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct - swrast_texture_image *texImage, - GLint i, GLint j, - GLint k, GLfloat *texel) +static void +fetch_etc2_srgb8_alpha8_eac(const GLubyte *map, + GLint rowStride, GLint i, GLint j, GLfloat *texel) { struct etc2_block block; uint8_t dst[4]; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; etc2_rgba8_parse_block(&block, src); etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst); - texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]); - texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]); - texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); } -void -_mesa_fetch_texel_2d_f_etc2_r11_eac(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) +static void +fetch_etc2_r11_eac(const GLubyte *map, + GLint rowStride, GLint i, GLint j, GLfloat *texel) { struct etc2_block block; GLushort dst; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; etc2_r11_parse_block(&block, src); etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst); @@ -1271,18 +1371,15 @@ _mesa_fetch_texel_2d_f_etc2_r11_eac(const struct swrast_texture_image *texImage, texel[ACOMP] = 1.0f; } -void -_mesa_fetch_texel_2d_f_etc2_rg11_eac(const struct - swrast_texture_image *texImage, - GLint i, GLint j, - GLint k, GLfloat *texel) +static void +fetch_etc2_rg11_eac(const GLubyte *map, + GLint rowStride, GLint i, GLint j, GLfloat *texel) { struct etc2_block block; GLushort dst[2]; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; /* red component */ etc2_r11_parse_block(&block, src); @@ -1298,16 +1395,15 @@ _mesa_fetch_texel_2d_f_etc2_rg11_eac(const struct texel[ACOMP] = 1.0f; } -void -_mesa_fetch_texel_2d_f_etc2_signed_r11_eac(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) +static void +fetch_etc2_signed_r11_eac(const GLubyte *map, + GLint rowStride, GLint i, GLint j, GLfloat *texel) { struct etc2_block block; GLushort dst; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; etc2_r11_parse_block(&block, src); etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst); @@ -1318,16 +1414,15 @@ _mesa_fetch_texel_2d_f_etc2_signed_r11_eac(const struct swrast_texture_image *te texel[ACOMP] = 1.0f; } -void -_mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) +static void +fetch_etc2_signed_rg11_eac(const GLubyte *map, + GLint rowStride, GLint i, GLint j, GLfloat *texel) { struct etc2_block block; GLushort dst[2]; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; /* red component */ etc2_r11_parse_block(&block, src); @@ -1343,18 +1438,16 @@ _mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct swrast_texture_image *t texel[ACOMP] = 1.0f; } -void -_mesa_fetch_texel_2d_f_etc2_rgb8_punchthrough_alpha1( - const struct swrast_texture_image *texImage, - GLint i, GLint j, - GLint k, GLfloat *texel) +static void +fetch_etc2_rgb8_punchthrough_alpha1(const GLubyte *map, + GLint rowStride, GLint i, GLint j, + GLfloat *texel) { struct etc2_block block; uint8_t dst[4]; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; + src = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; etc2_rgb8_parse_block(&block, src, true /* punchthrough alpha */); @@ -1366,97 +1459,55 @@ _mesa_fetch_texel_2d_f_etc2_rgb8_punchthrough_alpha1( texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); } -void -_mesa_fetch_texel_2d_f_etc2_srgb8_punchthrough_alpha1( - const struct swrast_texture_image *texImage, - GLint i, GLint j, - GLint k, GLfloat *texel) +static void +fetch_etc2_srgb8_punchthrough_alpha1(const GLubyte *map, + GLint rowStride, + GLint i, GLint j, GLfloat *texel) { struct etc2_block block; uint8_t dst[4]; const uint8_t *src; - src = texImage->Map + - (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8; + src = map + (((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] = _mesa_nonlinear_to_linear(dst[0]); - texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]); - texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); } -/** - * Decode texture data in any one of following formats: - * `MESA_FORMAT_ETC2_RGB8` - * `MESA_FORMAT_ETC2_SRGB8` - * `MESA_FORMAT_ETC2_RGBA8_EAC` - * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC` - * `MESA_FORMAT_ETC2_R11_EAC` - * `MESA_FORMAT_ETC2_RG11_EAC` - * `MESA_FORMAT_ETC2_SIGNED_R11_EAC` - * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC` - * `MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1` - * `MESA_FORMAT_ETC2_SRGB8_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. - * - * \param src_width in pixels - * \param src_height in pixels - * \param dst_stride in bytes - */ -void -_mesa_unpack_etc2_format(uint8_t *dst_row, - unsigned dst_stride, - const uint8_t *src_row, - unsigned src_stride, - unsigned src_width, - unsigned src_height, - gl_format format) +compressed_fetch_func +_mesa_get_etc_fetch_func(mesa_format format) { - 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); - else if (format == MESA_FORMAT_ETC2_RGBA8_EAC) - etc2_unpack_rgba8(dst_row, dst_stride, - src_row, src_stride, - src_width, src_height); - else if (format == MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC) - etc2_unpack_srgb8_alpha8(dst_row, dst_stride, - src_row, src_stride, - src_width, src_height); - else if (format == MESA_FORMAT_ETC2_R11_EAC) - etc2_unpack_r11(dst_row, dst_stride, - src_row, src_stride, - src_width, src_height); - else if (format == MESA_FORMAT_ETC2_RG11_EAC) - etc2_unpack_rg11(dst_row, dst_stride, - src_row, src_stride, - src_width, src_height); - else if (format == MESA_FORMAT_ETC2_SIGNED_R11_EAC) - etc2_unpack_signed_r11(dst_row, dst_stride, - src_row, src_stride, - src_width, src_height); - else if (format == MESA_FORMAT_ETC2_SIGNED_RG11_EAC) - 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); - else if (format == MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1) - etc2_unpack_srgb8_punchthrough_alpha1(dst_row, dst_stride, - src_row, src_stride, - src_width, src_height); + switch (format) { + case MESA_FORMAT_ETC1_RGB8: + return fetch_etc1_rgb8; + case MESA_FORMAT_ETC2_RGB8: + return fetch_etc2_rgb8; + case MESA_FORMAT_ETC2_SRGB8: + return fetch_etc2_srgb8; + case MESA_FORMAT_ETC2_RGBA8_EAC: + return fetch_etc2_rgba8_eac; + case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: + return fetch_etc2_srgb8_alpha8_eac; + case MESA_FORMAT_ETC2_R11_EAC: + return fetch_etc2_r11_eac; + case MESA_FORMAT_ETC2_RG11_EAC: + return fetch_etc2_rg11_eac; + case MESA_FORMAT_ETC2_SIGNED_R11_EAC: + return fetch_etc2_signed_r11_eac; + case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: + return fetch_etc2_signed_rg11_eac; + case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: + return fetch_etc2_rgb8_punchthrough_alpha1; + case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + return fetch_etc2_srgb8_punchthrough_alpha1; + default: + return NULL; + } }