mesa: Fix texture target validation for glFramebufferTexture()
authorPaul Berry <stereotype441@gmail.com>
Wed, 20 Nov 2013 05:47:04 +0000 (21:47 -0800)
committerPaul Berry <stereotype441@gmail.com>
Fri, 22 Nov 2013 02:16:44 +0000 (18:16 -0800)
Previously we were using the code path for validating
glFramebufferTextureLayer().  But glFramebufferTexture() allows
additional texture types.

Fixes piglit tests:
- spec/!OpenGL 3.2/layered-rendering/gl-layer-cube-map
- spec/!OpenGL 3.2/layered-rendering/framebuffertexture

Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
v2: Clarify comment above framebuffer_texture().

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/main/fbobject.c

index e8cf274e973e586a13d6687fecde5cad7c465dd5..dd1310783273c5d1a358775becfdc40642ea3ae2 100644 (file)
@@ -2307,8 +2307,13 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
 /**
  * Common code called by glFramebufferTexture1D/2D/3DEXT() and
  * glFramebufferTextureLayerEXT().
- * Note: glFramebufferTextureLayerEXT() has no textarget parameter so we'll
- * get textarget=0 in that case.
+ *
+ * \param textarget is the textarget that was passed to the
+ * glFramebufferTexture...() function, or 0 if the corresponding function
+ * doesn't have a textarget parameter.
+ *
+ * \param layered is true if this function was called from
+ * glFramebufferTexture(), false otherwise.
  */
 static void
 framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, 
@@ -2343,16 +2348,46 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
       texObj = _mesa_lookup_texture(ctx, texture);
       if (texObj != NULL) {
          if (textarget == 0) {
-            /* If textarget == 0 it means we're being called by
-             * glFramebufferTextureLayer() and textarget is not used.
-             * The only legal texture types for that function are 3D and
-             * 1D/2D arrays textures.
-             */
-            err = (texObj->Target != GL_TEXTURE_3D) &&
-                (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
-                (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) &&
-                (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY) &&
-                (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
+            if (layered) {
+               /* We're being called by glFramebufferTexture() and textarget
+                * is not used.
+                */
+               switch (texObj->Target) {
+               case GL_TEXTURE_3D:
+               case GL_TEXTURE_1D_ARRAY_EXT:
+               case GL_TEXTURE_2D_ARRAY_EXT:
+               case GL_TEXTURE_CUBE_MAP:
+               case GL_TEXTURE_CUBE_MAP_ARRAY:
+               case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+                  err = false;
+                  break;
+               case GL_TEXTURE_1D:
+               case GL_TEXTURE_2D:
+               case GL_TEXTURE_RECTANGLE:
+               case GL_TEXTURE_2D_MULTISAMPLE:
+                  /* These texture types are valid to pass to
+                   * glFramebufferTexture(), but since they aren't layered, it
+                   * is equivalent to calling glFramebufferTexture{1D,2D}().
+                   */
+                  err = false;
+                  layered = false;
+                  textarget = texObj->Target;
+                  break;
+               default:
+                  err = true;
+                  break;
+               }
+            } else {
+               /* We're being called by glFramebufferTextureLayer() and
+                * textarget is not used.  The only legal texture types for
+                * that function are 3D and 1D/2D arrays textures.
+                */
+               err = (texObj->Target != GL_TEXTURE_3D) &&
+                  (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
+                  (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) &&
+                  (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY) &&
+                  (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
+            }
          }
          else {
             /* Make sure textarget is consistent with the texture's type */