From d4a38e86d4b4d66cca20ee63222f940cb73fa709 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 28 Nov 2011 16:57:02 +0800 Subject: [PATCH] mesa: add support for GL_OES_compressed_ETC1_RGB8_texture Add support for GL_OES_compressed_ETC1_RGB8_texture to core mesa. There is no driver support yet. Unlike desktop GL compressed texture formats, GLES compressed texture formats usually can only be used with glCompressedTexImage2D. All other gl*Tex*Image* functions are updated to check for that. Reviewed-by: Brian Paul --- src/mesa/main/APIspec.xml | 2 ++ src/mesa/main/extensions.c | 1 + src/mesa/main/format_unpack.c | 8 ++++++ src/mesa/main/formats.c | 16 +++++++++++ src/mesa/main/formats.h | 2 ++ src/mesa/main/glheader.h | 4 +++ src/mesa/main/image.c | 3 +++ src/mesa/main/mtypes.h | 1 + src/mesa/main/texcompress.c | 22 +++++++++++++++ src/mesa/main/texformat.c | 10 +++++++ src/mesa/main/teximage.c | 51 +++++++++++++++++++++++++++++++++++ src/mesa/main/texstore.c | 2 ++ src/mesa/swrast/s_texfetch.c | 8 ++++++ 13 files changed, 130 insertions(+) diff --git a/src/mesa/main/APIspec.xml b/src/mesa/main/APIspec.xml index 99c726c83ad..eeae599298f 100644 --- a/src/mesa/main/APIspec.xml +++ b/src/mesa/main/APIspec.xml @@ -3806,6 +3806,7 @@ + @@ -4105,6 +4106,7 @@ + diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 8ebc0513997..b02a49de46e 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -219,6 +219,7 @@ static const struct extension extension_table[] = { { "GL_OES_blend_func_separate", o(EXT_blend_func_separate), ES1, 2009 }, { "GL_OES_blend_subtract", o(dummy_true), ES1, 2009 }, { "GL_OES_byte_coordinates", o(dummy_true), ES1, 2002 }, + { "GL_OES_compressed_ETC1_RGB8_texture", o(OES_compressed_ETC1_RGB8_texture), ES1 | ES2, 2005 }, { "GL_OES_compressed_paletted_texture", o(dummy_true), ES1, 2003 }, { "GL_OES_depth24", o(EXT_framebuffer_object), ES1 | ES2, 2005 }, { "GL_OES_depth32", o(dummy_false), DISABLE, 2005 }, diff --git a/src/mesa/main/format_unpack.c b/src/mesa/main/format_unpack.c index b4e4ac4bb78..7da95465b4e 100644 --- a/src/mesa/main/format_unpack.c +++ b/src/mesa/main/format_unpack.c @@ -1289,6 +1289,12 @@ unpack_SIGNED_LA_LATC2(const void *src, GLfloat dst[][4], GLuint n) /* XXX to do */ } +static void +unpack_ETC1_RGB8(const void *src, GLfloat dst[][4], GLuint n) +{ + /* XXX to do */ +} + static void unpack_SIGNED_A8(const void *src, GLfloat dst[][4], GLuint n) { @@ -1536,6 +1542,8 @@ get_unpack_rgba_function(gl_format format) table[MESA_FORMAT_LA_LATC2] = unpack_LA_LATC2; table[MESA_FORMAT_SIGNED_LA_LATC2] = unpack_SIGNED_LA_LATC2; + table[MESA_FORMAT_ETC1_RGB8] = unpack_ETC1_RGB8; + table[MESA_FORMAT_SIGNED_A8] = unpack_SIGNED_A8; table[MESA_FORMAT_SIGNED_L8] = unpack_SIGNED_L8; table[MESA_FORMAT_SIGNED_AL88] = unpack_SIGNED_AL88; diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 873fedc6539..4b163d16289 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -1386,6 +1386,16 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = 4, 4, 16 /* 16 bytes per 4x4 block */ }, + { + MESA_FORMAT_ETC1_RGB8, + "MESA_FORMAT_ETC1_RGB8", + GL_RGB, + GL_UNSIGNED_NORMALIZED, + 8, 8, 8, 0, + 0, 0, 0, 0, 0, + 4, 4, 8 /* 8 bytes per 4x4 block */ + }, + /* Signed formats from EXT_texture_snorm that are not in GL3.1 */ { MESA_FORMAT_SIGNED_A8, @@ -1790,6 +1800,8 @@ _mesa_get_uncompressed_format(gl_format format) return MESA_FORMAT_AL88; case MESA_FORMAT_SIGNED_LA_LATC2: return MESA_FORMAT_SIGNED_AL88; + case MESA_FORMAT_ETC1_RGB8: + return MESA_FORMAT_RGB888; default: #ifdef DEBUG assert(!_mesa_is_format_compressed(format)); @@ -2240,6 +2252,7 @@ _mesa_format_to_type_and_comps(gl_format format, case MESA_FORMAT_SIGNED_L_LATC1: case MESA_FORMAT_LA_LATC2: case MESA_FORMAT_SIGNED_LA_LATC2: + case MESA_FORMAT_ETC1_RGB8: /* XXX generate error instead? */ *datatype = GL_UNSIGNED_BYTE; *comps = 0; @@ -2777,6 +2790,9 @@ _mesa_format_matches_format_and_type(gl_format gl_format, case MESA_FORMAT_SIGNED_LA_LATC2: return GL_FALSE; + case MESA_FORMAT_ETC1_RGB8: + return GL_FALSE; + case MESA_FORMAT_SIGNED_A8: case MESA_FORMAT_SIGNED_L8: case MESA_FORMAT_SIGNED_AL88: diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h index b22b07338b3..fc2bb9ac5d6 100644 --- a/src/mesa/main/formats.h +++ b/src/mesa/main/formats.h @@ -250,6 +250,8 @@ typedef enum MESA_FORMAT_SIGNED_LA_LATC2, /*@}*/ + MESA_FORMAT_ETC1_RGB8, + MESA_FORMAT_SIGNED_A8, /* AAAA AAAA */ MESA_FORMAT_SIGNED_L8, /* LLLL LLLL */ MESA_FORMAT_SIGNED_AL88, /* AAAA AAAA LLLL LLLL */ diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h index 7980111b52b..315232371ed 100644 --- a/src/mesa/main/glheader.h +++ b/src/mesa/main/glheader.h @@ -139,6 +139,10 @@ typedef void *GLeglImageOES; #define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 #endif +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + /** * Internal token to represent a GLSL shader program (a collection of diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 446d52e2559..b266e26c679 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -741,6 +741,7 @@ _mesa_is_color_format(GLenum format) case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI: + case GL_ETC1_RGB8_OES: /* generic integer formats */ case GL_RED_INTEGER_EXT: case GL_GREEN_INTEGER_EXT: @@ -1050,6 +1051,8 @@ _mesa_is_compressed_format(struct gl_context *ctx, GLenum format) return ctx->Extensions.EXT_texture_compression_latc; case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI: return ctx->Extensions.ATI_texture_compression_3dc; + case GL_ETC1_RGB8_OES: + return ctx->Extensions.OES_compressed_ETC1_RGB8_texture; #if FEATURE_ES case GL_PALETTE4_RGB8_OES: case GL_PALETTE4_RGBA8_OES: diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 08cd80a7f1a..33b00c68000 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2979,6 +2979,7 @@ struct gl_extensions GLboolean OES_EGL_image; GLboolean OES_draw_texture; GLboolean OES_EGL_image_external; + GLboolean OES_compressed_ETC1_RGB8_texture; GLboolean extension_sentinel; /** The extension string */ const GLubyte *String; diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index 0458b9b689e..5045aef06cc 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -40,6 +40,7 @@ #include "texcompress_fxt1.h" #include "texcompress_rgtc.h" #include "texcompress_s3tc.h" +#include "texcompress_etc.h" #include "swrast/s_context.h" @@ -90,6 +91,7 @@ _mesa_gl_compressed_format_base_format(GLenum format) case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGB_FXT1_3DFX: case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_ETC1_RGB8_OES: return GL_RGB; case GL_COMPRESSED_RGBA: @@ -264,6 +266,15 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats) } } + if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) { + if (formats) { + formats[n++] = GL_ETC1_RGB8_OES; + } + else { + n += 1; + } + } + #if FEATURE_ES1 if (ctx->API == API_OPENGLES) { if (formats) { @@ -341,6 +352,9 @@ _mesa_glenum_to_compressed_format(GLenum format) case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: return MESA_FORMAT_SIGNED_LA_LATC2; + case GL_ETC1_RGB8_OES: + return MESA_FORMAT_ETC1_RGB8; + default: return MESA_FORMAT_NONE; } @@ -406,6 +420,9 @@ _mesa_compressed_format_to_glenum(struct gl_context *ctx, GLuint mesaFormat) case MESA_FORMAT_SIGNED_LA_LATC2: return GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT; + case MESA_FORMAT_ETC1_RGB8: + return GL_ETC1_RGB8_OES; + default: _mesa_problem(ctx, "Unexpected mesa texture format in" " _mesa_compressed_format_to_glenum()"); @@ -515,6 +532,11 @@ _mesa_decompress_image(gl_format format, GLuint width, GLuint height, fetch = _mesa_fetch_texel_2d_f_signed_la_latc2; break; + /* ETC1 formats */ + case MESA_FORMAT_ETC1_RGB8: + fetch = _mesa_fetch_texel_2d_f_etc1_rgb8; + break; + default: _mesa_problem(NULL, "Unexpected format in _mesa_decompress_image()"); return; diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index 6d8e272ba08..868913873e6 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -919,6 +919,16 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, } } + if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) { + switch (internalFormat) { + case GL_ETC1_RGB8_OES: + RETURN_IF_SUPPORTED(MESA_FORMAT_ETC1_RGB8); + break; + default: + ; /* fallthrough */ + } + } + _mesa_problem(ctx, "unexpected format %s in _mesa_choose_tex_format()", _mesa_lookup_enum_by_nr(internalFormat)); return MESA_FORMAT_NONE; diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 2bc7abdc247..2bdcedc8c13 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -493,6 +493,15 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) } } + if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) { + switch (internalFormat) { + case GL_ETC1_RGB8_OES: + return GL_RGB; + default: + ; /* fallthrough */ + } + } + if (ctx->API == API_OPENGLES) { switch (internalFormat) { case GL_PALETTE4_RGB8_OES: @@ -1292,6 +1301,20 @@ legal_texture_size(struct gl_context *ctx, gl_format format, } +/** + * Return true if the format is only valid for glCompressedTexImage. + */ +static GLboolean +compressedteximage_only_format(const struct gl_context *ctx, GLenum format) +{ + switch (format) { + case GL_ETC1_RGB8_OES: + return GL_TRUE; + default: + return GL_FALSE; + } +} + /** * Helper function to determine whether a target and specific compression @@ -1639,6 +1662,11 @@ texture_error_check( struct gl_context *ctx, "glTexImage%dD(target)", dimensions); return GL_TRUE; } + if (compressedteximage_only_format(ctx, internalFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexImage%dD(no compression for format)", dimensions); + return GL_TRUE; + } if (border != 0) { if (!isProxy) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -1793,6 +1821,12 @@ subtexture_error_check2( struct gl_context *ctx, GLuint dimensions, if (_mesa_is_format_compressed(destTex->TexFormat)) { GLuint bw, bh; + if (compressedteximage_only_format(ctx, destTex->InternalFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexSubImage%dD(no compression for format)", dimensions); + return GL_TRUE; + } + /* do tests which depend on compression block size */ _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh); @@ -1922,6 +1956,11 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, "glCopyTexImage%dD(target)", dimensions); return GL_TRUE; } + if (compressedteximage_only_format(ctx, internalFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%dD(no compression for format)", dimensions); + return GL_TRUE; + } if (border != 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexImage%dD(border!=0)", dimensions); @@ -2061,6 +2100,11 @@ copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions, } if (_mesa_is_format_compressed(teximage->TexFormat)) { + if (compressedteximage_only_format(ctx, teximage->InternalFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexSubImage%dD(no compression for format)", dimensions); + return GL_TRUE; + } /* offset must be multiple of 4 */ if ((xoffset & 3) || (yoffset & 3)) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -3244,6 +3288,13 @@ compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, return GL_TRUE; } + if (compressedteximage_only_format(ctx, format)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage%uD(format=0x%x cannot be updated)" + , dims, format); + return GL_TRUE; + } + if (((width == 1 || width == 2) && width != (GLsizei) texImage->Width) || (width > (GLsizei) texImage->Width)) { diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 0079590775c..1e1c749679d 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -67,6 +67,7 @@ #include "texcompress_fxt1.h" #include "texcompress_rgtc.h" #include "texcompress_s3tc.h" +#include "texcompress_etc.h" #include "teximage.h" #include "texstore.h" #include "enums.h" @@ -4437,6 +4438,7 @@ _mesa_get_texstore_func(gl_format format) table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1; table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2; table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2; + table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8; table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8; table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8; table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88; diff --git a/src/mesa/swrast/s_texfetch.c b/src/mesa/swrast/s_texfetch.c index ab7cfb50f94..158752d736b 100644 --- a/src/mesa/swrast/s_texfetch.c +++ b/src/mesa/swrast/s_texfetch.c @@ -39,6 +39,7 @@ #include "main/texcompress_fxt1.h" #include "main/texcompress_s3tc.h" #include "main/texcompress_rgtc.h" +#include "main/texcompress_etc.h" #include "main/teximage.h" #include "s_context.h" #include "s_texfetch.h" @@ -1177,6 +1178,13 @@ texfetch_funcs[MESA_FORMAT_COUNT] = NULL, NULL }, + { + MESA_FORMAT_ETC1_RGB8, + NULL, + _mesa_fetch_texel_2d_f_etc1_rgb8, + NULL, + NULL + }, { MESA_FORMAT_SIGNED_A8, fetch_texel_1d_signed_a8, -- 2.30.2