Commit bf18ed01 by Dian Xiang

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: 's avatarDian Xiang <dianx@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tryjob-Request: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent 941abaf2
......@@ -897,4 +897,68 @@ bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numA
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;
}
}
......@@ -32,6 +32,7 @@ bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type);
bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments,
const GLenum *attachments);
bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs);
}
#endif // LIBANGLE_VALIDATION_ES2_H_
......@@ -806,41 +806,11 @@ void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs)
Context *context = GetValidGlobalContext();
if (context)
{
if (n < 0 || static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
if (!ValidateDrawBuffers(context, n, bufs))
{
context->recordError(Error(GL_INVALID_VALUE));
return;
}
ASSERT(context->getState().getDrawFramebuffer());
if (context->getState().getDrawFramebuffer()->id() == 0)
{
if (n != 1)
{
context->recordError(Error(GL_INVALID_OPERATION));
return;
}
if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
{
context->recordError(Error(GL_INVALID_OPERATION));
return;
}
}
else
{
for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
{
const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
{
context->recordError(Error(GL_INVALID_OPERATION));
return;
}
}
}
Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
ASSERT(framebuffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment