[Mesa-dev] [PATCH] mesa: Use the effective internal format instead for validation

Eduardo Lima Mitev elima at igalia.com
Fri Aug 14 04:37:41 PDT 2015


When validating format+type+internalFormat for texture pixel operations
on GLES3, the effective internal format should be used if the one
specified is an unsized internal format. Page 127, section "3.8 Texturing"
of the GLES 3.0.4 spec says:

    "if internalformat is a base internal format, the effective internal
     format is a sized internal format that is derived from the format and
     type for internal use by the GL. Table 3.12 specifies the mapping of
     format and type to effective internal formats. The effective internal
     format is used by the GL for purposes such as texture completeness or
     type checks for CopyTex* commands. In these cases, the GL is required
     to operate as if the effective internal format was used as the
     internalformat when specifying the texture data."

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91582
---
 src/mesa/main/glformats.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/glformats.h |  4 ++++
 src/mesa/main/teximage.c  | 27 ++++++++++++++++++++++++++
 3 files changed, 79 insertions(+)

diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c
index 3eb66da..fd83e9c 100644
--- a/src/mesa/main/glformats.c
+++ b/src/mesa/main/glformats.c
@@ -2824,3 +2824,51 @@ _mesa_format_from_format_and_type(GLenum format, GLenum type)
     */
    unreachable("Unsupported format");
 }
+
+/**
+ * Returns the effective internal format from a texture format and type.
+ * This is used by texture image operations internally for validation, when
+ * the specified internal format is a base (unsized) format.
+ *
+ * \param format the texture format
+ * \param type the texture type
+ */
+GLenum
+_mesa_es3_effective_internal_format_for_format_and_type(GLenum format,
+                                                        GLenum type)
+{
+  switch (format) {
+  case GL_RGBA:
+     switch (type) {
+     case GL_UNSIGNED_BYTE:
+        return GL_RGBA8;
+     case GL_UNSIGNED_SHORT_4_4_4_4:
+        return GL_RGBA4;
+     case GL_UNSIGNED_SHORT_5_5_5_1:
+        return GL_RGB5_A1;
+     }
+     break;
+  case GL_RGB:
+     switch (type) {
+     case GL_UNSIGNED_BYTE:
+        return GL_RGB8;
+     case GL_UNSIGNED_SHORT_5_6_5:
+        return GL_RGB565;
+     }
+     break;
+  case GL_LUMINANCE_ALPHA:
+     if (type == GL_UNSIGNED_BYTE)
+        return GL_LUMINANCE8_ALPHA8;
+  case GL_LUMINANCE:
+     if (type == GL_UNSIGNED_BYTE)
+        return GL_LUMINANCE8;
+  case GL_ALPHA:
+     if (type == GL_UNSIGNED_BYTE)
+        return GL_ALPHA8;
+  default:
+     /* fall through and return NONE */
+     break;
+  }
+
+  return GL_NONE;
+}
diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h
index 419955a..0686c71 100644
--- a/src/mesa/main/glformats.h
+++ b/src/mesa/main/glformats.h
@@ -135,6 +135,10 @@ _mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
 extern uint32_t
 _mesa_format_from_format_and_type(GLenum format, GLenum type);
 
+extern GLenum
+_mesa_es3_effective_internal_format_for_format_and_type(GLenum format,
+                                                        GLenum type);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 3a556a6..c3dea8c 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2111,6 +2111,33 @@ texture_format_error_check_gles(struct gl_context *ctx, GLenum format,
    GLenum err;
 
    if (_mesa_is_gles3(ctx)) {
+      /* Page 127, section "3.8 Texturing" of the GLES 3.0.4 spec says:
+       *
+       *    "if internalformat is a base internal format, the effective
+       *     internal format is a sized internal format that is derived
+       *     from the format and type for internal use by the GL.
+       *     Table 3.12 specifies the mapping of format and type to effective
+       *     internal formats. The effective internal format is used by the GL
+       *     for purposes such as texture completeness or type checks for
+       *     CopyTex* commands. In these cases, the GL is required to operate
+       *     as if the effective internal format was used as the internalformat
+       *     when specifying the texture data."
+       */
+      if (_mesa_is_enum_format_unsized(internalFormat)) {
+         internalFormat =
+            _mesa_es3_effective_internal_format_for_format_and_type(format,
+                                                                    type);
+         if (internalFormat == GL_NONE) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "%s(format = %s, type = %s, effective "
+                        "internalformat = %s)",
+                        callerName, _mesa_enum_to_string(format),
+                        _mesa_enum_to_string(type),
+                        _mesa_enum_to_string(internalFormat));
+            return true;
+         }
+      }
+
       err = _mesa_es3_error_check_format_and_type(ctx, format, type,
                                                   internalFormat);
       if (err != GL_NO_ERROR) {
-- 
2.4.6



More information about the mesa-dev mailing list