Adding checks in DrawBuffers to return INVALID_ENUM
When a enum is given that is not a BACK, NONE, or COLOR_ATTACHMENTi where
i ranges from 0 to MAX_COLOR_ATTACHMENT, an INVALID_ENUM should be
returned rather than an INVALID_OPERATION.
BUG=angleproject:1148
Change-Id: I3663f897face14f6ba46a15fb982efda6f4f4b05
Reviewed-on: https://chromium-review.googlesource.com/299312
Tryjob-Request: Dian Xiang <dianx@google.com>
Tested-by: Dian Xiang <dianx@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tryjob-Request: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index de36dbc..377c350 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -897,4 +897,68 @@
return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer);
}
+bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs)
+{
+ // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
+ if (n < 0 || static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
+ {
+ context->recordError(
+ Error(GL_INVALID_VALUE, "n must be non-negative and no greater than MAX_DRAW_BUFFERS"));
+ return false;
+ }
+
+ ASSERT(context->getState().getDrawFramebuffer());
+ GLuint frameBufferId = context->getState().getDrawFramebuffer()->id();
+ GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
+
+ // This should come first before the check for the default frame buffer
+ // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
+ // rather than INVALID_OPERATION
+ for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
+ {
+ const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
+
+ if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
+ (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0_EXT ||
+ bufs[colorAttachment] >= maxColorAttachment))
+ {
+ // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
+ // In the 3.0 specs, the error should return GL_INVALID_OPERATION.
+ // When we move to 3.1 specs, we should change the error to be GL_INVALID_ENUM
+ context->recordError(Error(GL_INVALID_OPERATION, "Invalid buffer value"));
+ return false;
+ }
+ else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
+ frameBufferId != 0)
+ {
+ // INVALID_OPERATION-GL is bound to buffer and ith argument
+ // is not COLOR_ATTACHMENTi or NONE
+ context->recordError(
+ Error(GL_INVALID_OPERATION, "Ith value does not match COLOR_ATTACHMENTi or NONE"));
+ return false;
+ }
+ }
+
+ // INVALID_OPERATION is generated if GL is bound to the default framebuffer
+ // and n is not 1 or bufs is bound to value other than BACK and NONE
+ if (frameBufferId == 0)
+ {
+ if (n != 1)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION,
+ "n must be 1 when GL is bound to the default framebuffer"));
+ return false;
+ }
+
+ if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
+ {
+ context->recordError(Error(
+ GL_INVALID_OPERATION,
+ "Only NONE or BACK are valid values when drawing to the default framebuffer"));
+ return false;
+ }
+ }
+
+ return true;
+}
}