Mesa (main): mesa: check for valid internalformat with glTex[Sub]Image
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Mar 11 10:26:18 UTC 2022
Module: Mesa
Branch: main
Commit: 2a14baab855b349dbd5f4acaef8021eca314022a
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2a14baab855b349dbd5f4acaef8021eca314022a
Author: Tapani Pälli <tapani.palli at intel.com>
Date: Thu Jul 29 19:11:30 2021 +0300
mesa: check for valid internalformat with glTex[Sub]Image
This changes our error handling to be compatible with upcoming
specification change that unifies glTex[Sub]Image error handling
between OpenGL ES 2.0 vs ES 3.0+ specifications, see:
https://gitlab.khronos.org/opengl/API/-/issues/147
OpenGL ES 2.0.25 spec states:
"Specifying a value for internalformat that is not one of
the above values generates the error INVALID_VALUE. If
internalformat does not match format, the error
INVALID_OPERATION is generated."
This fixes following new tests:
KHR-GLES31.core.compressed_format.*
KHR-GLES32.core.compressed_format.*
v2: GL_INVALID_OPERATION -> GL_INVALID_VALUE in extension
checks, remove (now overlapping) extension checks from
_mesa_gles_error_check_format_and_type (Eric Anholt)
v3: take GLES version in to account in internalformat checks
Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12936>
---
src/mesa/main/glformats.c | 264 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 211 insertions(+), 53 deletions(-)
diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c
index 9ef771de105..068c01855a0 100644
--- a/src/mesa/main/glformats.c
+++ b/src/mesa/main/glformats.c
@@ -2794,6 +2794,174 @@ gles_effective_internal_format_for_format_and_type(GLenum format,
return GL_NONE;
}
+/**
+ * Error checking if internalformat for glTex[Sub]Image is valid
+ * within OpenGL ES 3.2 (or introduced by an ES extension).
+ *
+ * Note, further checks in _mesa_gles_error_check_format_and_type
+ * are required for complete checking between format and type.
+ */
+static GLenum
+_mesa_gles_check_internalformat(const struct gl_context *ctx,
+ GLenum internalFormat)
+{
+ switch (internalFormat) {
+ /* OpenGL ES 2.0 */
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+
+ /* GL_OES_depth_texture */
+ case GL_DEPTH_COMPONENT:
+
+ /* GL_EXT_texture_format_BGRA8888 */
+ case GL_BGRA:
+
+ /* GL_OES_required_internalformat */
+ case GL_RGB565:
+ case GL_RGB8:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ case GL_DEPTH24_STENCIL8:
+ case GL_RGB10_EXT:
+ case GL_RGB10_A2_EXT:
+ case GL_ALPHA8:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE4_ALPHA4:
+ return GL_NO_ERROR;
+
+ case GL_R8:
+ case GL_RG8:
+ case GL_RED:
+ case GL_RG:
+ if (!_mesa_has_rg_textures(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ /* GL_OES_texture_stencil8 */
+ case GL_STENCIL_INDEX8:
+ if (!_mesa_has_OES_texture_stencil8(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ case GL_COMPRESSED_RGBA_BPTC_UNORM:
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
+ if (!_mesa_has_EXT_texture_compression_bptc(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ case GL_COMPRESSED_RED_RGTC1:
+ case GL_COMPRESSED_SIGNED_RED_RGTC1:
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ if (!_mesa_has_EXT_texture_compression_rgtc(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ if (!_mesa_has_EXT_texture_compression_s3tc(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ if (!_mesa_has_EXT_texture_compression_s3tc_srgb(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ case GL_R16:
+ case GL_RG16:
+ case GL_RGB16:
+ case GL_RGBA16:
+ if (!_mesa_has_EXT_texture_norm16(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ case GL_R16_SNORM:
+ case GL_RG16_SNORM:
+ case GL_RGB16_SNORM:
+ case GL_RGBA16_SNORM:
+ if (!_mesa_has_EXT_texture_norm16(ctx) &&
+ !_mesa_has_EXT_texture_snorm(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ case GL_SR8_EXT:
+ if (!_mesa_has_EXT_texture_sRGB_R8(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ case GL_SRG8_EXT:
+ if (!_mesa_has_EXT_texture_sRGB_RG8(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+
+ /* OpenGL ES 3.0 */
+ case GL_SRGB8_ALPHA8:
+ case GL_RGBA8_SNORM:
+ case GL_RGBA16F:
+ case GL_RGBA32F:
+ case GL_RGBA8UI:
+ case GL_RGBA8I:
+ case GL_RGBA16UI:
+ case GL_RGBA16I:
+ case GL_RGBA32UI:
+ case GL_RGBA32I:
+ case GL_RGB10_A2UI:
+ case GL_SRGB8:
+ case GL_RGB8_SNORM:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
+ case GL_RGB16F:
+ case GL_RGB32F:
+ case GL_RGB8UI:
+ case GL_RGB8I:
+ case GL_RGB16UI:
+ case GL_RGB16I:
+ case GL_RGB32UI:
+ case GL_RGB32I:
+ case GL_RG8_SNORM:
+ case GL_RG16F:
+ case GL_RG32F:
+ case GL_RG8UI:
+ case GL_RG8I:
+ case GL_RG16UI:
+ case GL_RG16I:
+ case GL_RG32UI:
+ case GL_RG32I:
+ case GL_R8_SNORM:
+ case GL_R16F:
+ case GL_R32F:
+ case GL_R8UI:
+ case GL_R8I:
+ case GL_R16UI:
+ case GL_R16I:
+ case GL_R32UI:
+ case GL_R32I:
+ case GL_DEPTH_COMPONENT32F:
+ case GL_DEPTH32F_STENCIL8:
+ if (!_mesa_is_gles3(ctx))
+ return GL_INVALID_VALUE;
+ return GL_NO_ERROR;
+ default:
+ return GL_INVALID_VALUE;
+ }
+}
+
/**
* Do error checking of format/type combinations for OpenGL ES 3
* glTex[Sub]Image, or ES1/ES2 with GL_OES_required_internalformat.
@@ -2848,14 +3016,22 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
/* The GLES variant of EXT_texture_compression_s3tc is very vague and
* doesn't list valid types. Just do exactly what the spec says.
*/
- if (_mesa_has_EXT_texture_compression_s3tc(ctx) &&
- (internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
- internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
- internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
- internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT))
+ if (internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
+ internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
+ internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
return format == GL_RGB || format == GL_RGBA ? GL_NO_ERROR :
GL_INVALID_OPERATION;
+ /* Before checking for the combination, verify that
+ * given internalformat is legal for OpenGL ES.
+ */
+ GLenum internal_format_error =
+ _mesa_gles_check_internalformat(ctx, internalFormat);
+
+ if (internal_format_error != GL_NO_ERROR)
+ return internal_format_error;
+
switch (format) {
case GL_BGRA_EXT:
if (type != GL_UNSIGNED_BYTE ||
@@ -2887,8 +3063,6 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
break;
case GL_COMPRESSED_RGBA_BPTC_UNORM:
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
- if (!_mesa_has_EXT_texture_compression_bptc(ctx))
- return GL_INVALID_OPERATION;
break;
default:
return GL_INVALID_OPERATION;
@@ -2901,13 +3075,12 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
break;
case GL_UNSIGNED_SHORT:
- if (!_mesa_has_EXT_texture_norm16(ctx) || internalFormat != GL_RGBA16)
+ if (internalFormat != GL_RGBA16)
return GL_INVALID_OPERATION;
break;
case GL_SHORT:
- if (!_mesa_has_EXT_texture_norm16(ctx) ||
- internalFormat != GL_RGBA16_SNORM)
+ if (internalFormat != GL_RGBA16_SNORM)
return GL_INVALID_OPERATION;
break;
@@ -3041,13 +3214,12 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
break;
case GL_UNSIGNED_SHORT:
- if (!_mesa_has_EXT_texture_norm16(ctx) || internalFormat != GL_RGB16)
+ if (internalFormat != GL_RGB16)
return GL_INVALID_OPERATION;
break;
case GL_SHORT:
- if (!_mesa_has_EXT_texture_norm16(ctx) ||
- internalFormat != GL_RGB16_SNORM)
+ if (internalFormat != GL_RGB16_SNORM)
return GL_INVALID_OPERATION;
break;
@@ -3095,8 +3267,6 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
break;
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
- if (!_mesa_has_EXT_texture_compression_bptc(ctx))
- return GL_INVALID_OPERATION;
break;
case GL_RGB:
if (!_mesa_has_OES_texture_float(ctx) || internalFormat != format)
@@ -3179,29 +3349,25 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
return GL_INVALID_OPERATION;
switch (type) {
case GL_UNSIGNED_BYTE:
- if (internalFormat == GL_RG8 ||
- (_mesa_has_EXT_texture_compression_rgtc(ctx) &&
- internalFormat == GL_COMPRESSED_RED_GREEN_RGTC2_EXT) ||
- (_mesa_has_EXT_texture_sRGB_RG8(ctx) &&
- internalFormat == GL_SRG8_EXT))
- break;
- return GL_INVALID_OPERATION;
+ if (internalFormat != GL_RG8 &&
+ internalFormat != GL_COMPRESSED_RED_GREEN_RGTC2_EXT &&
+ internalFormat != GL_SRG8_EXT)
+ return GL_INVALID_OPERATION;
+ break;
case GL_BYTE:
if (internalFormat != GL_RG8_SNORM &&
- (!_mesa_has_EXT_texture_compression_rgtc(ctx) ||
- internalFormat != GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT))
+ internalFormat != GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT)
return GL_INVALID_OPERATION;
break;
case GL_UNSIGNED_SHORT:
- if (!_mesa_has_EXT_texture_norm16(ctx) || internalFormat != GL_RG16)
+ if (internalFormat != GL_RG16)
return GL_INVALID_OPERATION;
break;
case GL_SHORT:
- if (!_mesa_has_EXT_texture_norm16(ctx) ||
- internalFormat != GL_RG16_SNORM)
+ if (internalFormat != GL_RG16_SNORM)
return GL_INVALID_OPERATION;
break;
@@ -3213,8 +3379,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
return GL_INVALID_OPERATION;
break;
case GL_RG:
- if (!_mesa_has_rg_textures(ctx) ||
- !_mesa_has_OES_texture_half_float(ctx))
+ if (!_mesa_has_OES_texture_half_float(ctx))
return GL_INVALID_OPERATION;
break;
default:
@@ -3228,8 +3393,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
case GL_RG32F:
break;
case GL_RG:
- if (!_mesa_has_rg_textures(ctx) ||
- !_mesa_has_OES_texture_float(ctx))
+ if (!_mesa_has_OES_texture_float(ctx))
return GL_INVALID_OPERATION;
break;
default:
@@ -3286,29 +3450,26 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
return GL_INVALID_OPERATION;
switch (type) {
case GL_UNSIGNED_BYTE:
- if (internalFormat == GL_R8 ||
- ((internalFormat == GL_SR8_EXT) &&
- _mesa_has_EXT_texture_sRGB_R8(ctx)) ||
- (internalFormat == GL_COMPRESSED_RED_RGTC1_EXT &&
- _mesa_has_EXT_texture_compression_rgtc(ctx)))
- break;
- return GL_INVALID_OPERATION;
+ if (internalFormat != GL_R8 &&
+ internalFormat != GL_SR8_EXT &&
+ internalFormat != GL_COMPRESSED_RED_RGTC1_EXT) {
+ return GL_INVALID_OPERATION;
+ }
+ break;
case GL_BYTE:
if (internalFormat != GL_R8_SNORM &&
- (!_mesa_has_EXT_texture_compression_rgtc(ctx) ||
- internalFormat != GL_COMPRESSED_SIGNED_RED_RGTC1_EXT))
+ internalFormat != GL_COMPRESSED_SIGNED_RED_RGTC1_EXT)
return GL_INVALID_OPERATION;
break;
case GL_UNSIGNED_SHORT:
- if (!_mesa_has_EXT_texture_norm16(ctx) || internalFormat != GL_R16)
+ if (internalFormat != GL_R16)
return GL_INVALID_OPERATION;
break;
case GL_SHORT:
- if (!_mesa_has_EXT_texture_norm16(ctx) ||
- internalFormat != GL_R16_SNORM)
+ if (internalFormat != GL_R16_SNORM)
return GL_INVALID_OPERATION;
break;
@@ -3321,8 +3482,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
break;
case GL_RG:
case GL_RED:
- if (!_mesa_has_rg_textures(ctx) ||
- !_mesa_has_OES_texture_half_float(ctx))
+ if (!_mesa_has_OES_texture_half_float(ctx))
return GL_INVALID_OPERATION;
break;
default:
@@ -3336,8 +3496,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
case GL_R32F:
break;
case GL_RED:
- if (!_mesa_has_rg_textures(ctx) ||
- !_mesa_has_OES_texture_float(ctx))
+ if (!_mesa_has_OES_texture_float(ctx))
return GL_INVALID_OPERATION;
break;
default:
@@ -3392,8 +3551,8 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
case GL_DEPTH_COMPONENT:
switch (type) {
case GL_UNSIGNED_SHORT:
- if (internalFormat != GL_DEPTH_COMPONENT
- && internalFormat != GL_DEPTH_COMPONENT16)
+ if (internalFormat != GL_DEPTH_COMPONENT &&
+ internalFormat != GL_DEPTH_COMPONENT16)
return GL_INVALID_OPERATION;
break;
@@ -3421,8 +3580,8 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
case GL_DEPTH_STENCIL:
switch (type) {
case GL_UNSIGNED_INT_24_8:
- if (internalFormat != GL_DEPTH_STENCIL
- && internalFormat != GL_DEPTH24_STENCIL8)
+ if (internalFormat != GL_DEPTH_STENCIL &&
+ internalFormat != GL_DEPTH24_STENCIL8)
return GL_INVALID_OPERATION;
break;
@@ -3437,8 +3596,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx,
break;
case GL_STENCIL_INDEX:
- if (!_mesa_has_OES_texture_stencil8(ctx) ||
- type != GL_UNSIGNED_BYTE ||
+ if (type != GL_UNSIGNED_BYTE ||
internalFormat != GL_STENCIL_INDEX8) {
return GL_INVALID_OPERATION;
}
More information about the mesa-commit
mailing list