Add and implement glDrawBuffersEXT entry point to libGLESv2.

TRAC #22657

Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Author: Jamie Madill

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@2017 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 2025b1d..f84a597 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -6960,6 +6960,62 @@
     }
 }
 
+void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+    EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
+
+    try
+    {
+        gl::Context *context = gl::getNonLostContext();
+
+        if (context)
+        {
+            if (n < 0 || (unsigned int)n > context->getMaximumRenderTargets())
+            {
+                return gl::error(GL_INVALID_VALUE);
+            }
+
+            if (context->getDrawFramebufferHandle() == 0)
+            {
+                if (n > 1)
+                {
+                    return gl::error(GL_INVALID_OPERATION);
+                }
+
+                if (n == 1)
+                {
+                    if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
+                    {
+                        return gl::error(GL_INVALID_OPERATION);
+                    }
+                }
+            }
+            else
+            {
+                for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
+                {
+                    const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
+                    if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
+                    {
+                        return gl::error(GL_INVALID_OPERATION);
+                    }
+                }
+            }
+
+            gl::Framebuffer *framebuffer = context->getDrawFramebuffer();
+
+            for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
+            {
+                framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]);
+            }
+        }
+    }
+    catch (std::bad_alloc&)
+    {
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+}
+
 __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
 {
     struct Extension
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index a478389..cf7d607 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -825,8 +825,13 @@
 
     for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        if (framebuffer->getColorbufferType(colorAttachment) != GL_NONE)
+        const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment);
+
+        if (framebuffer->getColorbufferType(colorAttachment) != GL_NONE && drawBufferState != GL_NONE)
         {
+            // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order)
+            ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
+
             gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(colorAttachment);
 
             if (!colorbuffer)