diff options
Diffstat (limited to 'mesalib/src/mesa/main/texcompress_etc.c')
-rw-r--r-- | mesalib/src/mesa/main/texcompress_etc.c | 356 |
1 files changed, 194 insertions, 162 deletions
diff --git a/mesalib/src/mesa/main/texcompress_etc.c b/mesalib/src/mesa/main/texcompress_etc.c index 73d2fa4fe..7ad4ddeb6 100644 --- a/mesalib/src/mesa/main/texcompress_etc.c +++ b/mesalib/src/mesa/main/texcompress_etc.c @@ -43,9 +43,9 @@ #include "texcompress_etc.h" #include "texstore.h" #include "macros.h" -#include "swrast/s_context.h" #include "format_unpack.h" + struct etc2_block { int distance; uint64_t pixel_indices[2]; @@ -113,25 +113,6 @@ _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS) 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) @@ -468,7 +449,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) { @@ -756,10 +737,10 @@ etc2_unpack_srgb8(uint8_t *dst_row, } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -792,10 +773,10 @@ etc2_unpack_rgba8(uint8_t *dst_row, } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -836,10 +817,10 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row, } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -871,10 +852,10 @@ etc2_unpack_r11(uint8_t *dst_row, } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -919,10 +900,10 @@ etc2_unpack_rg11(uint8_t *dst_row, } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -955,10 +936,10 @@ etc2_unpack_signed_r11(uint8_t *dst_row, } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -1003,10 +984,10 @@ etc2_unpack_signed_rg11(uint8_t *dst_row, } } src += bs; - } + } src_row += src_stride; - } + } } static void @@ -1166,16 +1147,112 @@ _mesa_texstore_etc2_srgb8_punchthrough_alpha1(TEXSTORE_PARAMS) 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, + gl_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, const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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, const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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 */); @@ -1188,16 +1265,16 @@ _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, const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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 */); @@ -1210,16 +1287,16 @@ _mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image *texImage, 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, const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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); @@ -1230,18 +1307,16 @@ _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, const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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); @@ -1252,16 +1327,16 @@ _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct 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, const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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); @@ -1272,18 +1347,16 @@ _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, const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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); @@ -1299,16 +1372,16 @@ _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, const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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); @@ -1319,16 +1392,16 @@ _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, const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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); @@ -1344,18 +1417,17 @@ _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, + const GLuint imageOffsets[], + GLint rowStride, GLint i, GLint j, GLint k, + 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 */); @@ -1367,18 +1439,18 @@ _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, + const GLuint imageOffsets[], + GLint rowStride, + GLint i, GLint j, GLint k, + 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 */); @@ -1390,74 +1462,34 @@ _mesa_fetch_texel_2d_f_etc2_srgb8_punchthrough_alpha1( 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(gl_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; + } } |