Revert "Implement EXT_discard_framebuffer in D3D11 renderer"

Causes failures in video related WebGL tests.  Either there is a bug in the implementation or how chrome is using it.

This reverts commit b13daa8f79f4d16a990d968d7d2c04da6b72d302.

Change-Id: Ic0d74840c664bf4de18d85cc3ff7f7153936d9b0
Reviewed-on: https://chromium-review.googlesource.com/262715
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Caps.cpp b/src/libANGLE/Caps.cpp
index 9bad659..086d0a0 100644
--- a/src/libANGLE/Caps.cpp
+++ b/src/libANGLE/Caps.cpp
@@ -133,7 +133,6 @@
       fragDepth(false),
       textureUsage(false),
       translatedShaderSource(false),
-      discardFramebuffer(false),
       colorBufferFloat(false)
 {
 }
@@ -183,7 +182,6 @@
     InsertExtensionString("GL_EXT_frag_depth",                 fragDepth,                &extensionStrings);
     InsertExtensionString("GL_ANGLE_texture_usage",            textureUsage,             &extensionStrings);
     InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource,   &extensionStrings);
-    InsertExtensionString("GL_EXT_discard_framebuffer",        discardFramebuffer,       &extensionStrings);
     InsertExtensionString("GL_EXT_color_buffer_float",         colorBufferFloat,         &extensionStrings);
 
     return extensionStrings;
diff --git a/src/libANGLE/Caps.h b/src/libANGLE/Caps.h
index bc89521..37a6342 100644
--- a/src/libANGLE/Caps.h
+++ b/src/libANGLE/Caps.h
@@ -209,9 +209,6 @@
     // GL_ANGLE_translated_shader_source
     bool translatedShaderSource;
 
-    // GL_EXT_discard_framebuffer
-    bool discardFramebuffer;
-
     // ES3 Extension support
 
     // GL_EXT_color_buffer_float
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index 1b02d06..fb7a2de 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -461,11 +461,6 @@
     return mImpl->checkStatus();
 }
 
-Error Framebuffer::discard(size_t count, const GLenum *attachments)
-{
-    return mImpl->discard(count, attachments);
-}
-
 Error Framebuffer::invalidate(size_t count, const GLenum *attachments)
 {
     return mImpl->invalidate(count, attachments);
diff --git a/src/libANGLE/Framebuffer.h b/src/libANGLE/Framebuffer.h
index ae4f54b..ab91a11 100644
--- a/src/libANGLE/Framebuffer.h
+++ b/src/libANGLE/Framebuffer.h
@@ -112,7 +112,6 @@
     GLenum checkStatus(const gl::Data &data) const;
     bool hasValidDepthStencil() const;
 
-    Error discard(size_t count, const GLenum *attachments);
     Error invalidate(size_t count, const GLenum *attachments);
     Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area);
 
diff --git a/src/libANGLE/renderer/FramebufferImpl.h b/src/libANGLE/renderer/FramebufferImpl.h
index 7626d42..8e296b8 100644
--- a/src/libANGLE/renderer/FramebufferImpl.h
+++ b/src/libANGLE/renderer/FramebufferImpl.h
@@ -39,7 +39,6 @@
     virtual void setDrawBuffers(size_t count, const GLenum *buffers) = 0;
     virtual void setReadBuffer(GLenum buffer) = 0;
 
-    virtual gl::Error discard(size_t count, const GLenum *attachments) = 0;
     virtual gl::Error invalidate(size_t count, const GLenum *attachments) = 0;
     virtual gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) = 0;
 
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index bf9a17e..5bb9681 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -161,6 +161,18 @@
 {
 }
 
+gl::Error FramebufferD3D::invalidate(size_t, const GLenum *)
+{
+    // No-op in D3D
+    return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error FramebufferD3D::invalidateSub(size_t, const GLenum *, const gl::Rectangle &)
+{
+    // No-op in D3D
+    return gl::Error(GL_NO_ERROR);
+}
+
 gl::Error FramebufferD3D::clear(const gl::State &state, GLbitfield mask)
 {
     ClearParameters clearParams = GetClearParameters(state, mask);
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.h b/src/libANGLE/renderer/d3d/FramebufferD3D.h
index 8285f5a..ffe1415 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.h
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.h
@@ -85,6 +85,9 @@
     void setDrawBuffers(size_t count, const GLenum *buffers) override;
     void setReadBuffer(GLenum buffer) override;
 
+    gl::Error invalidate(size_t count, const GLenum *attachments) override;
+    gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
+
     gl::Error clear(const gl::State &state, GLbitfield mask) override;
     gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) override;
     gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) override;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
index c47277d..ab2a902 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -132,159 +132,6 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-gl::Error Framebuffer11::invalidate(size_t count, const GLenum *attachments)
-{
-    return invalidateBase(count, attachments, false);
-}
-
-gl::Error Framebuffer11::discard(size_t count, const GLenum *attachments)
-{
-    return invalidateBase(count, attachments, true);
-}
-
-gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const
-{
-    ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
-
-    if (!deviceContext1)
-    {
-        // DiscardView() is only supported on ID3D11DeviceContext1
-        return gl::Error(GL_NO_ERROR);
-    }
-
-    bool foundDepth = false;
-    bool foundStencil = false;
-
-    for (size_t i = 0; i < count; ++i)
-    {
-        switch (attachments[i])
-        {
-          // Handle depth and stencil attachments. Defer discarding until later.
-          case GL_DEPTH_STENCIL_ATTACHMENT:
-            foundDepth = true;
-            foundStencil = true;
-            break;
-          case GL_DEPTH_EXT:
-          case GL_DEPTH_ATTACHMENT:
-            foundDepth = true;
-            break;
-          case GL_STENCIL_EXT:
-          case GL_STENCIL_ATTACHMENT:
-            foundStencil = true;
-            break;
-          default:
-            {
-                // Handle color attachments
-                ASSERT((attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15) ||
-                       (attachments[i] == GL_COLOR));
-
-                RenderTarget11 *renderTarget = nullptr;
-                ID3D11View *colorView = nullptr;
-                gl::Error error(GL_NO_ERROR);
-                size_t colorAttachmentID = 0;
-
-                if (attachments[i] == GL_COLOR)
-                {
-                    colorAttachmentID = 0;
-                }
-                else
-                {
-                    colorAttachmentID = attachments[i] - GL_COLOR_ATTACHMENT0;
-                }
-
-                if (mData.mColorAttachments[colorAttachmentID])
-                {
-                    error = d3d11::GetAttachmentRenderTarget(mData.mColorAttachments[colorAttachmentID], &renderTarget);
-                    if (error.isError())
-                    {
-                        return error;
-                    }
-
-                    colorView = renderTarget->getRenderTargetView();
-
-                    if (colorView != nullptr)
-                    {
-                        deviceContext1->DiscardView(colorView);
-                    }
-                }
-
-                break;
-            }
-        }
-    }
-
-    bool discardDepth = false;
-    bool discardStencil = false;
-
-    // The D3D11 renderer uses the same view for depth and stencil buffers, so we must be careful.
-    if (useEXTBehavior)
-    {
-        // In the extension, if the app discards only one of the depth and stencil attachments, but
-        // those are backed by the same packed_depth_stencil buffer, then both images become undefined.
-        discardDepth = foundDepth;
-
-        // Don't bother discarding the stencil buffer if the depth buffer will already do it
-        discardStencil = foundStencil && (!discardDepth || mData.mDepthAttachment == nullptr);
-    }
-    else
-    {
-        // In ES 3.0.4, if a specified attachment has base internal format DEPTH_STENCIL but the
-        // attachments list does not include DEPTH_STENCIL_ATTACHMENT or both DEPTH_ATTACHMENT and
-        // STENCIL_ATTACHMENT, then only the specified portion of every pixel in the subregion of pixels
-        // of the DEPTH_STENCIL buffer may be invalidated, and the other portion must be preserved.
-        discardDepth = (foundDepth && foundStencil) || (foundDepth && (mData.mStencilAttachment == nullptr));
-        discardStencil = (foundStencil && (mData.mDepthAttachment == nullptr));
-    }
-
-    if (discardDepth && mData.mDepthAttachment)
-    {
-        RenderTarget11 *renderTarget = nullptr;
-        ID3D11View *depthView = nullptr;
-        gl::Error error(GL_NO_ERROR);
-
-        error = d3d11::GetAttachmentRenderTarget(mData.mDepthAttachment, &renderTarget);
-        if (error.isError())
-        {
-            return error;
-        }
-
-        depthView = renderTarget->getDepthStencilView();
-
-        if (depthView != nullptr)
-        {
-            deviceContext1->DiscardView(depthView);
-        }
-    }
-
-    if (discardStencil && mData.mStencilAttachment)
-    {
-        RenderTarget11 *renderTarget = nullptr;
-        ID3D11View *stencilView = nullptr;
-        gl::Error error(GL_NO_ERROR);
-
-        error = d3d11::GetAttachmentRenderTarget(mData.mStencilAttachment, &renderTarget);
-        if (error.isError())
-        {
-            return error;
-        }
-
-        stencilView = renderTarget->getDepthStencilView();
-
-        if (stencilView != nullptr)
-        {
-            deviceContext1->DiscardView(stencilView);
-        }
-    }
-
-    return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Framebuffer11::invalidateSub(size_t, const GLenum *, const gl::Rectangle &)
-{
-    // A no-op implementation conforms to the spec, so don't call UNIMPLEMENTED()
-    return gl::Error(GL_NO_ERROR);
-}
-
 gl::Error Framebuffer11::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const
 {
     ID3D11Texture2D *colorBufferTexture = NULL;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
index dfadd58..07fa480 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
@@ -21,10 +21,6 @@
     Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer);
     virtual ~Framebuffer11();
 
-    gl::Error discard(size_t count, const GLenum *attachments) override;
-    gl::Error invalidate(size_t count, const GLenum *attachments) override;
-    gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
-
     // Invalidate the cached swizzles of all bound texture attachments.
     gl::Error invalidateSwizzles() const;
 
@@ -38,7 +34,6 @@
                    bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
                    const gl::Framebuffer *sourceFramebuffer) override;
 
-    gl::Error invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const;
 
     GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index ba27b58..1444d15 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -1098,7 +1098,6 @@
     extensions->shaderTextureLOD = GetShaderTextureLODSupport(featureLevel);
     extensions->fragDepth = true;
     extensions->textureUsage = true; // This could be false since it has no effect in D3D11
-    extensions->discardFramebuffer = true;
     extensions->translatedShaderSource = true;
 }
 
diff --git a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
index c5411af..dbdfc6d 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
@@ -32,24 +32,6 @@
 {
 }
 
-gl::Error Framebuffer9::discard(size_t, const GLenum *)
-{
-    // No-op in D3D9
-    return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Framebuffer9::invalidate(size_t, const GLenum *)
-{
-    // No-op in D3D9
-    return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Framebuffer9::invalidateSub(size_t, const GLenum *, const gl::Rectangle &)
-{
-    // No-op in D3D9
-    return gl::Error(GL_NO_ERROR);
-}
-
 gl::Error Framebuffer9::clear(const gl::State &state, const ClearParameters &clearParams)
 {
     const gl::FramebufferAttachment *colorAttachment = mData.mColorAttachments[0];
diff --git a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
index 223259d..292118e 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
@@ -21,10 +21,6 @@
     Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer);
     virtual ~Framebuffer9();
 
-    gl::Error discard(size_t count, const GLenum *attachments) override;
-    gl::Error invalidate(size_t count, const GLenum *attachments) override;
-    gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
-
   private:
     gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override;
 
diff --git a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
index 6e31e9b..c9711ac 100644
--- a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -536,7 +536,6 @@
     extensions->fragDepth = true;
     extensions->textureUsage = true;
     extensions->translatedShaderSource = true;
-    extensions->discardFramebuffer = false; // It would be valid to set this to true, since glDiscardFramebufferEXT is just a hint
     extensions->colorBufferFloat = false;
 }
 
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.cpp b/src/libANGLE/renderer/gl/FramebufferGL.cpp
index f5ca3fe..2679c99 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -51,12 +51,6 @@
     //UNIMPLEMENTED();
 }
 
-gl::Error FramebufferGL::discard(size_t count, const GLenum *attachments)
-{
-    UNIMPLEMENTED();
-    return gl::Error(GL_INVALID_OPERATION);
-}
-
 gl::Error FramebufferGL::invalidate(size_t count, const GLenum *attachments)
 {
     UNIMPLEMENTED();
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.h b/src/libANGLE/renderer/gl/FramebufferGL.h
index 89d7088..9a43194 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.h
+++ b/src/libANGLE/renderer/gl/FramebufferGL.h
@@ -28,7 +28,6 @@
     void setDrawBuffers(size_t count, const GLenum *buffers) override;
     void setReadBuffer(GLenum buffer) override;
 
-    gl::Error discard(size_t count, const GLenum *attachments) override;
     gl::Error invalidate(size_t count, const GLenum *attachments) override;
     gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
 
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index f5e89ce..76232fd 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -1848,62 +1848,4 @@
     return ValidateSizedGetUniform(context, program, location, bufSize);
 }
 
-bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei numAttachments,
-                                    const GLenum *attachments, bool defaultFramebuffer)
-{
-    if (numAttachments < 0)
-    {
-        context->recordError(Error(GL_INVALID_VALUE, "numAttachments must not be less than zero"));
-        return false;
-    }
-
-    for (GLsizei i = 0; i < numAttachments; ++i)
-    {
-        if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
-        {
-            if (defaultFramebuffer)
-            {
-                context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment when the default framebuffer is bound"));
-                return false;
-            }
-
-            if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
-            {
-                context->recordError(Error(GL_INVALID_OPERATION,
-                                           "Requested color attachment is greater than the maximum supported color attachments"));
-                return false;
-            }
-        }
-        else
-        {
-            switch (attachments[i])
-            {
-              case GL_DEPTH_ATTACHMENT:
-              case GL_STENCIL_ATTACHMENT:
-              case GL_DEPTH_STENCIL_ATTACHMENT:
-                if (defaultFramebuffer)
-                {
-                    context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment when the default framebuffer is bound"));
-                    return false;
-                }
-                break;
-              case GL_COLOR:
-              case GL_DEPTH:
-              case GL_STENCIL:
-                if (!defaultFramebuffer)
-                {
-                    context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment when the default framebuffer is not bound"));
-                    return false;
-                }
-                break;
-              default:
-                context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment"));
-                return false;
-            }
-        }
-    }
-
-    return true;
-}
-
 }
diff --git a/src/libANGLE/validationES.h b/src/libANGLE/validationES.h
index 8f4ad68..b0ccd8e 100644
--- a/src/libANGLE/validationES.h
+++ b/src/libANGLE/validationES.h
@@ -89,9 +89,6 @@
 bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
 bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params);
 
-bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei numAttachments,
-                                    const GLenum *attachments, bool defaultFramebuffer);
-
 }
 
 #endif // LIBANGLE_VALIDATION_ES_H_
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index de36dbc..9eece1b 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -879,22 +879,4 @@
     return true;
 }
 
-bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments,
-                                   const GLenum *attachments)
-{
-    bool defaultFramebuffer = false;
-
-    switch (target)
-    {
-      case GL_FRAMEBUFFER:
-        defaultFramebuffer = (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
-        break;
-      default:
-        context->recordError(Error(GL_INVALID_ENUM, "Invalid framebuffer target"));
-        return false;
-    }
-
-    return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer);
-}
-
 }
diff --git a/src/libANGLE/validationES2.h b/src/libANGLE/validationES2.h
index e9e9b51..b9c1fd3 100644
--- a/src/libANGLE/validationES2.h
+++ b/src/libANGLE/validationES2.h
@@ -29,9 +29,6 @@
 
 bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type);
 
-bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments,
-                                   const GLenum *attachments);
-
 }
 
 #endif // LIBANGLE_VALIDATION_ES2_H_
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index 07ad075..e141bb6 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -1132,15 +1132,9 @@
     return true;
 }
 
-bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numAttachments,
-                                   const GLenum *attachments)
+bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
+                                             const GLenum* attachments)
 {
-    if (context->getClientVersion() < 3)
-    {
-        context->recordError(Error(GL_INVALID_OPERATION, "Operation only supported on ES 3.0 and above"));
-        return false;
-    }
-
     bool defaultFramebuffer = false;
 
     switch (target)
@@ -1153,11 +1147,56 @@
         defaultFramebuffer = context->getState().getReadFramebuffer()->id() == 0;
         break;
       default:
-        context->recordError(Error(GL_INVALID_ENUM, "Invalid framebuffer target"));
-        return false;
+          context->recordError(Error(GL_INVALID_ENUM));
+          return false;
     }
 
-    return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer);
+    for (int i = 0; i < numAttachments; ++i)
+    {
+        if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
+        {
+            if (defaultFramebuffer)
+            {
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
+            }
+
+            if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
+            {
+                context->recordError(Error(GL_INVALID_OPERATION));
+                return false;
+            }
+        }
+        else
+        {
+            switch (attachments[i])
+            {
+              case GL_DEPTH_ATTACHMENT:
+              case GL_STENCIL_ATTACHMENT:
+              case GL_DEPTH_STENCIL_ATTACHMENT:
+                if (defaultFramebuffer)
+                {
+                    context->recordError(Error(GL_INVALID_ENUM));
+                    return false;
+                }
+                break;
+              case GL_COLOR:
+              case GL_DEPTH:
+              case GL_STENCIL:
+                if (!defaultFramebuffer)
+                {
+                    context->recordError(Error(GL_INVALID_ENUM));
+                    return false;
+                }
+                break;
+              default:
+                context->recordError(Error(GL_INVALID_ENUM));
+                return false;
+            }
+        }
+    }
+
+    return true;
 }
 
 bool ValidateClearBuffer(Context *context)
diff --git a/src/libANGLE/validationES3.h b/src/libANGLE/validationES3.h
index e49f9d3..517cb5d 100644
--- a/src/libANGLE/validationES3.h
+++ b/src/libANGLE/validationES3.h
@@ -35,8 +35,8 @@
 bool ValidateES3RenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples,
                                               GLenum internalformat, GLsizei width, GLsizei height);
 
-bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numAttachments,
-                                   const GLenum *attachments);
+bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
+                                             const GLenum* attachments);
 
 bool ValidateClearBuffer(Context *context);
 
diff --git a/src/libGLESv2/entry_points_egl.cpp b/src/libGLESv2/entry_points_egl.cpp
index 998b64b..2630e30 100644
--- a/src/libGLESv2/entry_points_egl.cpp
+++ b/src/libGLESv2/entry_points_egl.cpp
@@ -1107,7 +1107,6 @@
         { "glUnmapBufferOES", (__eglMustCastToProperFunctionPointerType)gl::UnmapBufferOES },
         { "glMapBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)gl::MapBufferRangeEXT },
         { "glFlushMappedBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)gl::FlushMappedBufferRangeEXT },
-        { "glDiscardFramebufferEXT", (__eglMustCastToProperFunctionPointerType)gl::DiscardFramebufferEXT },
         { "", NULL },
     };
 
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
index 7a50e2b..e34242e 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -682,38 +682,6 @@
     }
 }
 
-void GL_APIENTRY DiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments)
-{
-    EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, attachments = 0x%0.8p)", target, numAttachments, attachments);
-
-    Context *context = GetValidGlobalContext();
-    if (context)
-    {
-        if (!context->getExtensions().discardFramebuffer)
-        {
-            context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
-            return;
-        }
-
-        if (!ValidateDiscardFramebufferEXT(context, target, numAttachments, attachments))
-        {
-            return;
-        }
-
-        Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
-        ASSERT(framebuffer);
-
-        // The specification isn't clear what should be done when the framebuffer isn't complete.
-        // We leave it up to the framebuffer implementation to decide what to do.
-        Error error = framebuffer->discard(numAttachments, attachments);
-        if (error.isError())
-        {
-            context->recordError(error);
-            return;
-        }
-    }
-}
-
 void GL_APIENTRY TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
                    GLint border, GLenum format, GLenum type, const GLvoid* pixels)
 {
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.h b/src/libGLESv2/entry_points_gles_2_0_ext.h
index d4f5f6d..816519f 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.h
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.h
@@ -22,9 +22,6 @@
 // GL_ANGLE_framebuffer_multisample
 ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
 
-// GL_EXT_discard_framebuffer
-ANGLE_EXPORT void GL_APIENTRY DiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments);
-
 // GL_NV_fence
 ANGLE_EXPORT void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint* fences);
 ANGLE_EXPORT void GL_APIENTRY GenFencesNV(GLsizei n, GLuint* fences);
diff --git a/src/libGLESv2/entry_points_gles_3_0.cpp b/src/libGLESv2/entry_points_gles_3_0.cpp
index ca55496..5300282 100644
--- a/src/libGLESv2/entry_points_gles_3_0.cpp
+++ b/src/libGLESv2/entry_points_gles_3_0.cpp
@@ -3189,7 +3189,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!ValidateInvalidateFramebuffer(context, target, numAttachments, attachments))
+        if (context->getClientVersion() < 3)
+        {
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
         {
             return;
         }
@@ -3218,7 +3224,13 @@
     Context *context = GetValidGlobalContext();
     if (context)
     {
-        if (!ValidateInvalidateFramebuffer(context, target, numAttachments, attachments))
+        if (context->getClientVersion() < 3)
+        {
+            context->recordError(Error(GL_INVALID_OPERATION));
+            return;
+        }
+
+        if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
         {
             return;
         }
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index d4386eb..e69e04a 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -1256,11 +1256,6 @@
     return gl::RenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);
 }
 
-void GL_APIENTRY glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments)
-{
-    return gl::DiscardFramebufferEXT(target, numAttachments, attachments);
-}
-
 void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
 {
     return gl::DeleteFencesNV(n, fences);
diff --git a/src/libGLESv2/libGLESv2.def b/src/libGLESv2/libGLESv2.def
index 038e496..54f396d 100644
--- a/src/libGLESv2/libGLESv2.def
+++ b/src/libGLESv2/libGLESv2.def
@@ -177,7 +177,6 @@
     glGetBufferPointervOES          @287
     glMapBufferRangeEXT             @288
     glFlushMappedBufferRangeEXT     @289
-    glDiscardFramebufferEXT         @293
 
     ; GLES 3.0 Functions
     glReadBuffer                    @180
diff --git a/src/tests/angle_end2end_tests.gypi b/src/tests/angle_end2end_tests.gypi
index 601ae3a..7e32b46 100644
--- a/src/tests/angle_end2end_tests.gypi
+++ b/src/tests/angle_end2end_tests.gypi
@@ -24,7 +24,6 @@
             '<(angle_path)/src/tests/end2end_tests/CompressedTextureTest.cpp',
             '<(angle_path)/src/tests/end2end_tests/CubeMapTextureTest.cpp',
             '<(angle_path)/src/tests/end2end_tests/DepthStencilFormatsTest.cpp',
-            '<(angle_path)/src/tests/end2end_tests/DiscardFramebufferEXTTest.cpp',
             '<(angle_path)/src/tests/end2end_tests/DrawBuffersTest.cpp',
             '<(angle_path)/src/tests/end2end_tests/FramebufferFormatsTest.cpp',
             '<(angle_path)/src/tests/end2end_tests/GLSLTest.cpp',
diff --git a/src/tests/end2end_tests/DiscardFramebufferEXTTest.cpp b/src/tests/end2end_tests/DiscardFramebufferEXTTest.cpp
deleted file mode 100644
index ff9c8ce..0000000
--- a/src/tests/end2end_tests/DiscardFramebufferEXTTest.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-#include "ANGLETest.h"
-
-// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
-ANGLE_TYPED_TEST_CASE(DiscardFramebufferEXTTest, ES2_D3D9, ES2_D3D11, ES2_D3D11_FL9_3);
-
-template<typename T>
-class DiscardFramebufferEXTTest : public ANGLETest
-{
-protected:
-    DiscardFramebufferEXTTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
-    {
-        setWindowWidth(256);
-        setWindowHeight(256);
-        setConfigRedBits(8);
-        setConfigGreenBits(8);
-        setConfigBlueBits(8);
-        setConfigAlphaBits(8);
-        setConfigDepthBits(24);
-        setConfigStencilBits(8);
-    }
-
-    T fixtureType;
-};
-
-TYPED_TEST(DiscardFramebufferEXTTest, ExtensionEnabled)
-{
-    EGLPlatformParameters platform = fixtureType.GetPlatform();
-
-    if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
-    {
-        EXPECT_TRUE(extensionEnabled("EXT_discard_framebuffer"));
-    }
-    else
-    {
-        // Other platforms don't currently implement this extension
-        EXPECT_FALSE(extensionEnabled("EXT_discard_framebuffer"));
-    }
-}
-
-TYPED_TEST(DiscardFramebufferEXTTest, DefaultFramebuffer)
-{
-    if (!extensionEnabled("EXT_discard_framebuffer"))
-    {
-        return;
-    }
-
-    // These should succeed on the default framebuffer
-    const GLenum discards1[] = { GL_COLOR_EXT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards1);
-    EXPECT_GL_NO_ERROR();
-
-    const GLenum discards2[] = { GL_DEPTH_EXT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards2);
-    EXPECT_GL_NO_ERROR();
-
-    const GLenum discards3[] = { GL_STENCIL_EXT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards3);
-    EXPECT_GL_NO_ERROR();
-
-    const GLenum discards4[] = { GL_STENCIL_EXT, GL_COLOR_EXT, GL_DEPTH_EXT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, discards4);
-    EXPECT_GL_NO_ERROR();
-
-    // These should fail on the default framebuffer
-    const GLenum discards5[] = { GL_COLOR_ATTACHMENT0 };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards5);
-    EXPECT_GL_ERROR(GL_INVALID_ENUM);
-
-    const GLenum discards6[] = { GL_DEPTH_ATTACHMENT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards6);
-    EXPECT_GL_ERROR(GL_INVALID_ENUM);
-
-    const GLenum discards7[] = { GL_STENCIL_ATTACHMENT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards7);
-    EXPECT_GL_ERROR(GL_INVALID_ENUM);
-}
-
-TYPED_TEST(DiscardFramebufferEXTTest, NonDefaultFramebuffer)
-{
-    if (!extensionEnabled("EXT_discard_framebuffer"))
-    {
-        return;
-    }
-
-    GLuint tex2D;
-    GLuint framebuffer;
-
-    // Create a basic off-screen framebuffer
-    // Don't create a depth/stencil texture, to ensure that also works correctly
-    glGenTextures(1, &tex2D);
-    glGenFramebuffers(1, &framebuffer);
-    glBindTexture(GL_TEXTURE_2D, tex2D);
-    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0);
-    ASSERT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
-
-    // These should fail on the non-default framebuffer
-    const GLenum discards1[] = { GL_COLOR_EXT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards1);
-    EXPECT_GL_ERROR(GL_INVALID_ENUM);
-
-    const GLenum discards2[] = { GL_DEPTH_EXT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards2);
-    EXPECT_GL_ERROR(GL_INVALID_ENUM);
-
-    const GLenum discards3[] = { GL_STENCIL_EXT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards3);
-    EXPECT_GL_ERROR(GL_INVALID_ENUM);
-
-    const GLenum discards4[] = { GL_STENCIL_EXT, GL_COLOR_EXT, GL_DEPTH_EXT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, discards4);
-    EXPECT_GL_ERROR(GL_INVALID_ENUM);
-
-    // These should succeed on the non-default framebuffer
-    const GLenum discards5[] = { GL_COLOR_ATTACHMENT0 };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards5);
-    EXPECT_GL_NO_ERROR();
-
-    const GLenum discards6[] = { GL_DEPTH_ATTACHMENT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards6);
-    EXPECT_GL_NO_ERROR();
-
-    const GLenum discards7[] = { GL_STENCIL_ATTACHMENT };
-    glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards7);
-    EXPECT_GL_NO_ERROR();
-}