Validate framebuffer attachment formats.
TRAC #13792
Signed-off-by: Daniel Koch

Author:    Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/trunk@458 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index 39a10b5..0ecd184 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -305,7 +305,14 @@
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        if (IsTextureTarget(mColorbufferType))
+        if (mColorbufferType == GL_RENDERBUFFER)
+        {
+            if (!gl::IsColorRenderable(colorbuffer->getFormat()))
+            {
+                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+            }
+        }
+        else if (IsTextureTarget(mColorbufferType))
         {
             if (IsCompressed(colorbuffer->getFormat()))
             {
@@ -323,6 +330,7 @@
                 return GL_FRAMEBUFFER_UNSUPPORTED;
             }
         }
+        else UNREACHABLE();
 
         width = colorbuffer->getWidth();
         height = colorbuffer->getHeight();
@@ -338,6 +346,11 @@
 
     if (mDepthbufferType != GL_NONE)
     {
+        if (mDepthbufferType != GL_RENDERBUFFER)
+        {
+            return GL_FRAMEBUFFER_UNSUPPORTED;   // Requires GL_OES_depth_texture
+        }
+
         depthbuffer = getDepthbuffer();
 
         if (!depthbuffer)
@@ -368,18 +381,15 @@
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
-        
-        if (IsTextureTarget(mDepthbufferType))
-        {
-            if (IsCompressed(depthbuffer->getFormat()))
-            {
-                return GL_FRAMEBUFFER_UNSUPPORTED;
-            }
-        }
     }
 
     if (mStencilbufferType != GL_NONE)
     {
+        if (mStencilbufferType != GL_RENDERBUFFER)
+        {
+            return GL_FRAMEBUFFER_UNSUPPORTED;
+        }
+
         stencilbuffer = getStencilbuffer();
 
         if (!stencilbuffer)
@@ -410,14 +420,6 @@
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
-        
-        if (IsTextureTarget(mStencilbufferType))
-        {
-            if (IsCompressed(stencilbuffer->getFormat()))
-            {
-                return GL_FRAMEBUFFER_UNSUPPORTED;
-            }
-        }
     }
 
     if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index ea81166..365c0e4 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -2104,7 +2104,7 @@
 Texture::TextureColorbufferProxy::TextureColorbufferProxy(Texture *texture, GLenum target)
   : Colorbuffer(texture), mTexture(texture), mTarget(target)
 {
-    ASSERT(target == GL_TEXTURE_2D || IsCubemapTextureTarget(target));
+    ASSERT(IsTextureTarget(target));
 }
 
 void Texture::TextureColorbufferProxy::addRef() const
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index c986b5e..c67c822 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -4015,18 +4015,8 @@
             return error(GL_INVALID_ENUM);
         }
 
-        switch (internalformat)
+        if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
         {
-          case GL_DEPTH_COMPONENT16:
-          case GL_RGBA4:
-          case GL_RGB5_A1:
-          case GL_RGB565:
-          case GL_STENCIL_INDEX8:
-          case GL_DEPTH24_STENCIL8_OES:
-          case GL_RGB8_OES:
-          case GL_RGBA8_OES:
-            break;
-          default:
             return error(GL_INVALID_ENUM);
         }
 
diff --git a/src/libGLESv2/utilities.cpp b/src/libGLESv2/utilities.cpp
index d0fe398..b20f0a5 100644
--- a/src/libGLESv2/utilities.cpp
+++ b/src/libGLESv2/utilities.cpp
@@ -336,6 +336,69 @@
     }
 }
 
+bool IsColorRenderable(GLenum internalformat)
+{
+    switch (internalformat)
+    {
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGB565:
+      case GL_RGB8_OES:
+      case GL_RGBA8_OES:
+        return true;
+      case GL_DEPTH_COMPONENT16:
+      case GL_STENCIL_INDEX8:
+      case GL_DEPTH24_STENCIL8_OES:
+        return false;
+      default:
+        UNIMPLEMENTED();
+    }
+
+    return false;
+}
+
+bool IsDepthRenderable(GLenum internalformat)
+{
+    switch (internalformat)
+    {
+      case GL_DEPTH_COMPONENT16:
+      case GL_DEPTH24_STENCIL8_OES:
+        return true;
+      case GL_STENCIL_INDEX8:
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGB565:
+      case GL_RGB8_OES:
+      case GL_RGBA8_OES:
+        return false;
+      default:
+        UNIMPLEMENTED();
+    }
+
+    return false;
+}
+
+bool IsStencilRenderable(GLenum internalformat)
+{
+    switch (internalformat)
+    {
+      case GL_STENCIL_INDEX8:
+      case GL_DEPTH24_STENCIL8_OES:
+        return true;
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGB565:
+      case GL_RGB8_OES:
+      case GL_RGBA8_OES:
+      case GL_DEPTH_COMPONENT16:
+        return false;
+      default:
+        UNIMPLEMENTED();
+    }
+
+    return false;
+}
+
 }
 
 namespace es2dx
diff --git a/src/libGLESv2/utilities.h b/src/libGLESv2/utilities.h
index b6c8ce5..cb687b0 100644
--- a/src/libGLESv2/utilities.h
+++ b/src/libGLESv2/utilities.h
@@ -36,6 +36,10 @@
 bool IsTextureTarget(GLenum target);
 bool CheckTextureFormatType(GLenum format, GLenum type);
 
+bool IsColorRenderable(GLenum internalformat);
+bool IsDepthRenderable(GLenum internalformat);
+bool IsStencilRenderable(GLenum internalformat);
+
 }
 
 namespace es2dx