mesa/es: Validate glTexImage format, type, and internalFormat in Mesa code rather...
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 27 Jul 2012 02:18:58 +0000 (19:18 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 23 Aug 2012 17:15:31 +0000 (10:15 -0700)
v2: Add proper GLES3 filtering.

v3: Collapse ALPHA, LUMINANCE, and LUMINANCE_ALPHA cases per review
comment from Ken.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/mesa/main/APIspec.xml
src/mesa/main/teximage.c
src/mesa/main/teximage.h

index 1c5be8c2ebad76a97538f16a2b1f499772c3ff36..ffc384c87567dcf4ab643a289dfb5f98e61ae2f4 100644 (file)
                <param name="type" type="GLenum"/>
                <param name="pixels" type="const GLvoid *"/>
        </proto>
-
-       <desc name="internalFormat">
-               <value name="GL_ALPHA"/>
-
-               <desc name="format" error="GL_INVALID_VALUE">
-                       <value name="GL_ALPHA"/>
-               </desc>
-       </desc>
-
-       <desc name="internalFormat">
-               <value name="GL_RGB"/>
-
-               <desc name="format" error="GL_INVALID_VALUE">
-                       <value name="GL_RGB"/>
-               </desc>
-       </desc>
-
-       <desc name="internalFormat">
-               <value name="GL_RGBA"/>
-
-               <desc name="format" error="GL_INVALID_VALUE">
-                       <value name="GL_RGBA"/>
-               </desc>
-       </desc>
-
-       <desc name="internalFormat">
-               <value name="GL_LUMINANCE"/>
-
-               <desc name="format" error="GL_INVALID_VALUE">
-                       <value name="GL_LUMINANCE"/>
-               </desc>
-       </desc>
-
-       <desc name="internalFormat">
-               <value name="GL_LUMINANCE_ALPHA"/>
-
-               <desc name="format" error="GL_INVALID_VALUE">
-                       <value name="GL_LUMINANCE_ALPHA"/>
-               </desc>
-       </desc>
-
-       <desc name="internalFormat" category="OES_depth_texture">
-               <value name="GL_DEPTH_COMPONENT"/>
-
-               <desc name="format" error="GL_INVALID_VALUE">
-                       <value name="GL_DEPTH_COMPONENT"/>
-               </desc>
-       </desc>
-
-       <desc name="internalFormat" category="OES_packed_depth_stencil">
-               <value name="GL_DEPTH_STENCIL_OES"/>
-
-               <desc name="format" error="GL_INVALID_VALUE">
-                       <value name="GL_DEPTH_STENCIL_OES"/>
-               </desc>
-       </desc>
-
-       <desc name="internalFormat" category="EXT_texture_format_BGRA8888">
-               <value name="GL_BGRA_EXT"/>
-
-               <desc name="format" error="GL_INVALID_VALUE">
-                       <value name="GL_BGRA_EXT"/>
-               </desc>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_ALPHA"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-               </desc>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_RGB"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_UNSIGNED_SHORT_5_6_5"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-               </desc>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_RGBA"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_UNSIGNED_SHORT_4_4_4_4"/>
-                       <value name="GL_UNSIGNED_SHORT_5_5_5_1"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-                       <value name="GL_UNSIGNED_INT_2_10_10_10_REV_EXT" category="EXT_texture_type_2_10_10_10_REV"/>
-               </desc>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_LUMINANCE"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-               </desc>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_LUMINANCE_ALPHA"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-               </desc>
-       </desc>
-
-       <desc name="format" category="OES_depth_texture">
-               <value name="GL_DEPTH_COMPONENT"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_SHORT"/>
-                       <value name="GL_UNSIGNED_INT"/>
-               </desc>
-       </desc>
-
-       <desc name="format" category="OES_packed_depth_stencil">
-               <value name="GL_DEPTH_STENCIL_OES"/>
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_INT_24_8_OES"/>
-               </desc>
-       </desc>
-
-       <desc name="format" category="EXT_texture_format_BGRA8888">
-               <value name="GL_BGRA_EXT"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-               </desc>
-       </desc>
 </template>
 
 <template name="TexEnv">
                <param name="pixels" type="const GLvoid *"/>
        </proto>
 
-       <desc name="internalFormat">
-               <value name="GL_ALPHA"/>
-               <value name="GL_RGB"/>
-               <value name="GL_RGBA"/>
-               <value name="GL_LUMINANCE"/>
-               <value name="GL_LUMINANCE_ALPHA"/>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_ALPHA"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-               </desc>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_RGB"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_UNSIGNED_SHORT_5_6_5"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-               </desc>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_RGBA"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_UNSIGNED_SHORT_4_4_4_4"/>
-                       <value name="GL_UNSIGNED_SHORT_5_5_5_1"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-                       <value name="GL_UNSIGNED_INT_2_10_10_10_REV_EXT" category="EXT_texture_type_2_10_10_10_REV"/>
-               </desc>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_LUMINANCE"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-               </desc>
-       </desc>
-
-       <desc name="format">
-               <value name="GL_LUMINANCE_ALPHA"/>
-
-               <desc name="type" error="GL_INVALID_OPERATION">
-                       <value name="GL_UNSIGNED_BYTE"/>
-                       <value name="GL_FLOAT" category="OES_texture_float"/>
-                       <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/>
-               </desc>
-       </desc>
 </template>
 
 <template name="TexSubImage3D">
index d9f0c7d84b5e3f3ba851a3deb421c45cdaa47292..e22881ce6c9a9a36f5b35a2f0f5f298e1b66cdd9 100644 (file)
 #include "glformats.h"
 
 
+/* Inexplicably, GL_HALF_FLOAT_OES has a different value than GL_HALF_FLOAT.
+ */
+#ifndef GL_HALF_FLOAT_OES
+#define GL_HALF_FLOAT_OES 0x8D61
+#endif
+
 /**
  * State changes which we care about for glCopyTex[Sub]Image() calls.
  * In particular, we care about pixel transfer state and buffer state
@@ -1552,6 +1558,68 @@ mutable_tex_object(struct gl_context *ctx, GLenum target)
 }
 
 
+GLenum
+_mesa_es_error_check_format_and_type(GLenum format, GLenum type,
+                                     unsigned dimensions)
+{
+   bool type_valid = true;
+
+   switch (format) {
+   case GL_ALPHA:
+   case GL_LUMINANCE:
+   case GL_LUMINANCE_ALPHA:
+      type_valid = (type == GL_UNSIGNED_BYTE
+                    || type == GL_FLOAT
+                    || type == GL_HALF_FLOAT_OES);
+      break;
+
+   case GL_RGB:
+      type_valid = (type == GL_UNSIGNED_BYTE
+                    || type == GL_UNSIGNED_SHORT_5_6_5
+                    || type == GL_FLOAT
+                    || type == GL_HALF_FLOAT_OES);
+      break;
+
+   case GL_RGBA:
+      type_valid = (type == GL_UNSIGNED_BYTE
+                    || type == GL_UNSIGNED_SHORT_4_4_4_4
+                    || type == GL_UNSIGNED_SHORT_5_5_5_1
+                    || type == GL_FLOAT
+                    || type == GL_HALF_FLOAT_OES
+                    || type == GL_UNSIGNED_INT_2_10_10_10_REV);
+      break;
+
+   case GL_DEPTH_COMPONENT:
+      /* This format is filtered against invalid dimensionalities elsewhere.
+       */
+      type_valid = (type == GL_UNSIGNED_SHORT
+                    || type == GL_UNSIGNED_INT);
+      break;
+
+   case GL_DEPTH_STENCIL:
+      /* This format is filtered against invalid dimensionalities elsewhere.
+       */
+      type_valid = (type == GL_UNSIGNED_INT_24_8);
+      break;
+
+   case GL_BGRA_EXT:
+      type_valid = (type == GL_UNSIGNED_BYTE);
+
+      /* This feels like a bug in the EXT_texture_format_BGRA8888 spec, but
+       * the format does not appear to be allowed for 3D textures in OpenGL
+       * ES.
+       */
+      if (dimensions != 2)
+         return GL_INVALID_VALUE;
+
+      break;
+
+   default:
+      return GL_INVALID_VALUE;
+   }
+
+   return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION;
+}
 
 /**
  * Test the glTexImage[123]D() parameters for errors.
@@ -1623,6 +1691,32 @@ texture_error_check( struct gl_context *ctx,
       return GL_TRUE;
    }
 
+   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
+    * combinations of format, internalFormat, and type that can be used.
+    * Formats and types that require additional extensions (e.g., GL_FLOAT
+    * requires GL_OES_texture_float) are filtered elsewhere.
+    */
+   if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
+      if (format != internalFormat) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glTexImage%dD(format = %s, internalFormat = %s)",
+                     dimensions,
+                     _mesa_lookup_enum_by_nr(format),
+                     _mesa_lookup_enum_by_nr(internalFormat));
+         return GL_TRUE;
+      }
+
+      err = _mesa_es_error_check_format_and_type(format, type, dimensions);
+      if (err != GL_NO_ERROR) {
+         _mesa_error(ctx, err,
+                     "glTexImage%dD(format = %s, type = %s)",
+                     dimensions,
+                     _mesa_lookup_enum_by_nr(format),
+                     _mesa_lookup_enum_by_nr(type));
+         return GL_TRUE;
+      }
+   }
+
    /* Do this simple check before calling the TestProxyTexImage() function */
    if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
       sizeOK = (width == height);
index 66a0c88950b9cdaaf0c1b827fdbbe32d8e5d1d91..739c5dda13248ec8fa721225d951095a6e694c34 100644 (file)
@@ -140,6 +140,10 @@ _mesa_tex_target_to_face(GLenum target);
 extern GLint
 _mesa_get_texture_dimensions(GLenum target);
 
+extern GLenum
+_mesa_es_error_check_format_and_type(GLenum format, GLenum type,
+                                     unsigned dimensions);
+
 /**
  * Lock a texture for updating.  See also _mesa_lock_context_textures().
  */