Commit b1196687 by Geoff Lang

Update validation functions to use new error mechanisms.

BUG=angle:520 Change-Id: I1c64af2e57cf2d89138bd23da2b07d5873742e4e Reviewed-on: https://chromium-review.googlesource.com/209880Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 05881a0f
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -168,7 +168,7 @@ bool ValidMipLevel(const Context *context, GLenum target, GLint level) ...@@ -168,7 +168,7 @@ bool ValidMipLevel(const Context *context, GLenum target, GLint level)
return level <= gl::log2(maxDimension); return level <= gl::log2(maxDimension);
} }
bool ValidImageSize(const gl::Context *context, GLenum target, GLint level, bool ValidImageSize(const Context *context, GLenum target, GLint level,
GLsizei width, GLsizei height, GLsizei depth) GLsizei width, GLsizei height, GLsizei depth)
{ {
if (level < 0 || width < 0 || height < 0 || depth < 0) if (level < 0 || width < 0 || height < 0 || depth < 0)
...@@ -190,7 +190,7 @@ bool ValidImageSize(const gl::Context *context, GLenum target, GLint level, ...@@ -190,7 +190,7 @@ bool ValidImageSize(const gl::Context *context, GLenum target, GLint level,
return true; return true;
} }
bool ValidCompressedImageSize(const gl::Context *context, GLenum internalFormat, GLsizei width, GLsizei height) bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height)
{ {
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
if (!formatInfo.compressed) if (!formatInfo.compressed)
...@@ -224,7 +224,7 @@ bool ValidQueryType(const Context *context, GLenum queryType) ...@@ -224,7 +224,7 @@ bool ValidQueryType(const Context *context, GLenum queryType)
} }
} }
bool ValidProgram(const Context *context, GLuint id) bool ValidProgram(Context *context, GLuint id)
{ {
// ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will generate the // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will generate the
// error INVALID_VALUE if the provided name is not the name of either a shader or program object and // error INVALID_VALUE if the provided name is not the name of either a shader or program object and
...@@ -237,16 +237,18 @@ bool ValidProgram(const Context *context, GLuint id) ...@@ -237,16 +237,18 @@ bool ValidProgram(const Context *context, GLuint id)
else if (context->getShader(id) != NULL) else if (context->getShader(id) != NULL)
{ {
// ID is the wrong type // ID is the wrong type
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
else else
{ {
// No shader/program object has this ID // No shader/program object has this ID
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment) bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment)
{ {
if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
{ {
...@@ -254,7 +256,8 @@ bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment) ...@@ -254,7 +256,8 @@ bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment)
if (colorAttachment >= context->getCaps().maxColorAttachments) if (colorAttachment >= context->getCaps().maxColorAttachments)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
else else
...@@ -268,19 +271,21 @@ bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment) ...@@ -268,19 +271,21 @@ bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment)
case GL_DEPTH_STENCIL_ATTACHMENT: case GL_DEPTH_STENCIL_ATTACHMENT:
if (context->getClientVersion() < 3) if (context->getClientVersion() < 3)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
return true; return true;
} }
bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples, bool ValidateRenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height, GLenum internalformat, GLsizei width, GLsizei height,
bool angleExtension) bool angleExtension)
{ {
...@@ -289,18 +294,21 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta ...@@ -289,18 +294,21 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta
case GL_RENDERBUFFER: case GL_RENDERBUFFER:
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (width < 0 || height < 0 || samples < 0) if (width < 0 || height < 0 || samples < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
// ANGLE_framebuffer_multisample does not explicitly state that the internal format must be // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
...@@ -309,23 +317,27 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta ...@@ -309,23 +317,27 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta
// internal format must be sized and not an integer format if samples is greater than zero. // internal format must be sized and not an integer format if samples is greater than zero.
if (formatInfo.pixelBytes == 0) if (formatInfo.pixelBytes == 0)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && samples > 0) if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && samples > 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
if (!formatCaps.renderable) if (!formatCaps.renderable)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize) if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
// ANGLE_framebuffer_multisample states that the value of samples must be less than or equal // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
...@@ -337,27 +349,31 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta ...@@ -337,27 +349,31 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta
ASSERT(context->getExtensions().framebufferMultisample); ASSERT(context->getExtensions().framebufferMultisample);
if (static_cast<GLuint>(samples) > context->getExtensions().maxSamples) if (static_cast<GLuint>(samples) > context->getExtensions().maxSamples)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
// Check if this specific format supports enough samples // Check if this specific format supports enough samples
if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples()) if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
{ {
return gl::error(GL_OUT_OF_MEMORY, false); context->recordError(Error(GL_OUT_OF_MEMORY));
return false;
} }
} }
else else
{ {
if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples()) if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
GLuint handle = context->getState().getRenderbufferId(); GLuint handle = context->getState().getRenderbufferId();
if (handle == 0) if (handle == 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
...@@ -368,7 +384,8 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ ...@@ -368,7 +384,8 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ
{ {
if (!ValidFramebufferTarget(target)) if (!ValidFramebufferTarget(target))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
...@@ -376,7 +393,8 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ ...@@ -376,7 +393,8 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ
if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0)) if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (!ValidateAttachmentTarget(context, attachment)) if (!ValidateAttachmentTarget(context, attachment))
...@@ -392,7 +410,8 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ ...@@ -392,7 +410,8 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ
{ {
if (!context->getRenderbuffer(renderbuffer)) if (!context->getRenderbuffer(renderbuffer))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -434,16 +453,19 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -434,16 +453,19 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
case GL_LINEAR: case GL_LINEAR:
if (fromAngleExtension) if (fromAngleExtension)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0) if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (mask == 0) if (mask == 0)
...@@ -456,14 +478,16 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -456,14 +478,16 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (fromAngleExtension && (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)) if (fromAngleExtension && (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0))
{ {
ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation."); ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation.");
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// ES3.0 spec, section 4.3.2 states that linear filtering is only available for the // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
// color buffer, leaving only nearest being unfiltered from above // color buffer, leaving only nearest being unfiltered from above
if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST) if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (context->getState().getReadFramebuffer()->id() == context->getState().getDrawFramebuffer()->id()) if (context->getState().getReadFramebuffer()->id() == context->getState().getDrawFramebuffer()->id())
...@@ -473,7 +497,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -473,7 +497,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
ERR("Blits with the same source and destination framebuffer are not supported by this " ERR("Blits with the same source and destination framebuffer are not supported by this "
"implementation."); "implementation.");
} }
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
gl::Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); gl::Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
...@@ -481,12 +506,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -481,12 +506,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE || if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
!drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{ {
return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
} }
if (drawFramebuffer->getSamples() != 0) if (drawFramebuffer->getSamples() != 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1; bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
...@@ -515,29 +542,34 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -515,29 +542,34 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if ( (readFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || readFormatInfo.componentType == GL_SIGNED_NORMALIZED) && if ( (readFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || readFormatInfo.componentType == GL_SIGNED_NORMALIZED) &&
!(drawFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || drawFormatInfo.componentType == GL_SIGNED_NORMALIZED)) !(drawFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || drawFormatInfo.componentType == GL_SIGNED_NORMALIZED))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (readFormatInfo.componentType == GL_UNSIGNED_INT && drawFormatInfo.componentType != GL_UNSIGNED_INT) if (readFormatInfo.componentType == GL_UNSIGNED_INT && drawFormatInfo.componentType != GL_UNSIGNED_INT)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (readFormatInfo.componentType == GL_INT && drawFormatInfo.componentType != GL_INT) if (readFormatInfo.componentType == GL_INT && drawFormatInfo.componentType != GL_INT)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (readColorBuffer->getSamples() > 0 && (readInternalFormat != drawInternalFormat || !sameBounds)) if (readColorBuffer->getSamples() > 0 && (readInternalFormat != drawInternalFormat || !sameBounds))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
} }
if ((readFormatInfo.componentType == GL_INT || readFormatInfo.componentType == GL_UNSIGNED_INT) && filter == GL_LINEAR) if ((readFormatInfo.componentType == GL_INT || readFormatInfo.componentType == GL_UNSIGNED_INT) && filter == GL_LINEAR)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (fromAngleExtension) if (fromAngleExtension)
...@@ -545,7 +577,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -545,7 +577,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType(); const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
if (readColorbufferType != GL_TEXTURE_2D && readColorbufferType != GL_RENDERBUFFER) if (readColorbufferType != GL_TEXTURE_2D && readColorbufferType != GL_RENDERBUFFER)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
...@@ -557,12 +590,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -557,12 +590,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (attachment->type() != GL_TEXTURE_2D && attachment->type() != GL_RENDERBUFFER) if (attachment->type() != GL_TEXTURE_2D && attachment->type() != GL_RENDERBUFFER)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (attachment->getActualFormat() != readColorBuffer->getActualFormat()) if (attachment->getActualFormat() != readColorBuffer->getActualFormat())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
} }
...@@ -570,7 +605,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -570,7 +605,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
srcX0, srcY0, srcX1, srcY1, srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1)) dstX0, dstY0, dstX1, dstY1))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
} }
...@@ -585,12 +621,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -585,12 +621,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
{ {
if (readDepthBuffer->getActualFormat() != drawDepthBuffer->getActualFormat()) if (readDepthBuffer->getActualFormat() != drawDepthBuffer->getActualFormat())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (readDepthBuffer->getSamples() > 0 && !sameBounds) if (readDepthBuffer->getSamples() > 0 && !sameBounds)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (fromAngleExtension) if (fromAngleExtension)
...@@ -599,12 +637,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -599,12 +637,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1)) srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
{ {
ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
return false;
} }
if (readDepthBuffer->getSamples() != 0 || drawDepthBuffer->getSamples() != 0) if (readDepthBuffer->getSamples() != 0 || drawDepthBuffer->getSamples() != 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
} }
...@@ -619,12 +659,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -619,12 +659,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
{ {
if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat()) if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (readStencilBuffer->getSamples() > 0 && !sameBounds) if (readStencilBuffer->getSamples() > 0 && !sameBounds)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (fromAngleExtension) if (fromAngleExtension)
...@@ -633,12 +675,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -633,12 +675,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1)) srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
{ {
ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
return false;
} }
if (readStencilBuffer->getSamples() != 0 || drawStencilBuffer->getSamples() != 0) if (readStencilBuffer->getSamples() != 0 || drawStencilBuffer->getSamples() != 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
} }
...@@ -647,7 +691,7 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -647,7 +691,7 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
return true; return true;
} }
bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion) bool ValidateGetVertexAttribParameters(Context *context, GLenum pname)
{ {
switch (pname) switch (pname)
{ {
...@@ -667,10 +711,16 @@ bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion) ...@@ -667,10 +711,16 @@ bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion)
return true; return true;
case GL_VERTEX_ATTRIB_ARRAY_INTEGER: case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
return ((clientVersion >= 3) ? true : gl::error(GL_INVALID_ENUM, false)); if (context->getClientVersion() < 3)
{
context->recordError(Error(GL_INVALID_ENUM));
return false;
}
return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
...@@ -691,7 +741,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) ...@@ -691,7 +741,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_MAX_LOD:
if (context->getClientVersion() < 3) if (context->getClientVersion() < 3)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
...@@ -710,7 +761,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) ...@@ -710,7 +761,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_MIRRORED_REPEAT: case GL_MIRRORED_REPEAT:
return true; return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MIN_FILTER:
...@@ -724,7 +776,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) ...@@ -724,7 +776,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_LINEAR_MIPMAP_LINEAR: case GL_LINEAR_MIPMAP_LINEAR:
return true; return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
...@@ -735,7 +788,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) ...@@ -735,7 +788,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_LINEAR: case GL_LINEAR:
return true; return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
...@@ -746,20 +800,23 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) ...@@ -746,20 +800,23 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_FRAMEBUFFER_ATTACHMENT_ANGLE: case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
return true; return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_TEXTURE_MAX_ANISOTROPY_EXT: case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!context->getExtensions().textureFilterAnisotropic) if (!context->getExtensions().textureFilterAnisotropic)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
// we assume the parameter passed to this validation method is truncated, not rounded // we assume the parameter passed to this validation method is truncated, not rounded
if (param < 1) if (param < 1)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
return true; return true;
...@@ -776,7 +833,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) ...@@ -776,7 +833,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_COMPARE_REF_TO_TEXTURE: case GL_COMPARE_REF_TO_TEXTURE:
return true; return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
...@@ -794,7 +852,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) ...@@ -794,7 +852,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_NEVER: case GL_NEVER:
return true; return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
...@@ -812,7 +871,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) ...@@ -812,7 +871,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_ONE: case GL_ONE:
return true; return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
...@@ -820,16 +880,18 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) ...@@ -820,16 +880,18 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MAX_LEVEL:
if (param < 0) if (param < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
return true; return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
bool ValidateSamplerObjectParameter(GLenum pname) bool ValidateSamplerObjectParameter(gl::Context *context, GLenum pname)
{ {
switch (pname) switch (pname)
{ {
...@@ -845,7 +907,8 @@ bool ValidateSamplerObjectParameter(GLenum pname) ...@@ -845,7 +907,8 @@ bool ValidateSamplerObjectParameter(GLenum pname)
return true; return true;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
...@@ -857,17 +920,20 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize ...@@ -857,17 +920,20 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{ {
return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
} }
if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0) if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (!framebuffer->getReadColorbuffer()) if (!framebuffer->getReadColorbuffer())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
GLenum currentInternalFormat, currentFormat, currentType; GLenum currentInternalFormat, currentFormat, currentType;
...@@ -880,7 +946,8 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize ...@@ -880,7 +946,8 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize
if (!(currentFormat == format && currentType == type) && !validReadFormat) if (!(currentFormat == format && currentType == type) && !validReadFormat)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
...@@ -893,7 +960,8 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize ...@@ -893,7 +960,8 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize
int requiredSize = outputPitch * height; int requiredSize = outputPitch * height;
if (requiredSize > *bufSize) if (requiredSize > *bufSize)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -904,12 +972,14 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) ...@@ -904,12 +972,14 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id)
{ {
if (!ValidQueryType(context, target)) if (!ValidQueryType(context, target))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (id == 0) if (id == 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
...@@ -929,7 +999,8 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) ...@@ -929,7 +999,8 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id)
// no query may be active for either if glBeginQuery targets either. // no query may be active for either if glBeginQuery targets either.
if (context->getState().isQueryActive()) if (context->getState().isQueryActive())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
Query *queryObject = context->getQuery(id, true, target); Query *queryObject = context->getQuery(id, true, target);
...@@ -937,13 +1008,15 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) ...@@ -937,13 +1008,15 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id)
// check that name was obtained with glGenQueries // check that name was obtained with glGenQueries
if (!queryObject) if (!queryObject)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// check for type mismatch // check for type mismatch
if (queryObject->getType() != target) if (queryObject->getType() != target)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
...@@ -953,19 +1026,22 @@ bool ValidateEndQuery(gl::Context *context, GLenum target) ...@@ -953,19 +1026,22 @@ bool ValidateEndQuery(gl::Context *context, GLenum target)
{ {
if (!ValidQueryType(context, target)) if (!ValidQueryType(context, target))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
const Query *queryObject = context->getState().getActiveQuery(target); const Query *queryObject = context->getState().getActiveQuery(target);
if (queryObject == NULL) if (queryObject == NULL)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (!queryObject->isStarted()) if (!queryObject->isStarted())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
...@@ -976,13 +1052,15 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform ...@@ -976,13 +1052,15 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform
{ {
if (count < 0) if (count < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary(); gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
if (!programBinary) if (!programBinary)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (location == -1) if (location == -1)
...@@ -993,7 +1071,8 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform ...@@ -993,7 +1071,8 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform
if (!programBinary->isValidUniformLocation(location)) if (!programBinary->isValidUniformLocation(location))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
LinkedUniform *uniform = programBinary->getUniformByLocation(location); LinkedUniform *uniform = programBinary->getUniformByLocation(location);
...@@ -1001,7 +1080,8 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform ...@@ -1001,7 +1080,8 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform
// attempting to write an array to a non-array uniform is an INVALID_OPERATION // attempting to write an array to a non-array uniform is an INVALID_OPERATION
if (uniform->elementCount() == 1 && count > 1) if (uniform->elementCount() == 1 && count > 1)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
*uniformOut = uniform; *uniformOut = uniform;
...@@ -1013,7 +1093,8 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G ...@@ -1013,7 +1093,8 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G
// Check for ES3 uniform entry points // Check for ES3 uniform entry points
if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3) if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
LinkedUniform *uniform = NULL; LinkedUniform *uniform = NULL;
...@@ -1026,7 +1107,8 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G ...@@ -1026,7 +1107,8 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G
bool samplerUniformCheck = (IsSampler(uniform->type) && uniformType == GL_INT); bool samplerUniformCheck = (IsSampler(uniform->type) && uniformType == GL_INT);
if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type) if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
...@@ -1040,12 +1122,14 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati ...@@ -1040,12 +1122,14 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati
int cols = VariableColumnCount(matrixType); int cols = VariableColumnCount(matrixType);
if (rows != cols && context->getClientVersion() < 3) if (rows != cols && context->getClientVersion() < 3)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (transpose != GL_FALSE && context->getClientVersion() < 3) if (transpose != GL_FALSE && context->getClientVersion() < 3)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
LinkedUniform *uniform = NULL; LinkedUniform *uniform = NULL;
...@@ -1056,7 +1140,8 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati ...@@ -1056,7 +1140,8 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati
if (uniform->type != matrixType) if (uniform->type != matrixType)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
...@@ -1066,7 +1151,8 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, ...@@ -1066,7 +1151,8 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
{ {
if (!context->getQueryParameterInfo(pname, nativeType, numParams)) if (!context->getQueryParameterInfo(pname, nativeType, numParams))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15) if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
...@@ -1075,7 +1161,8 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, ...@@ -1075,7 +1161,8 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
if (colorAttachment >= context->getCaps().maxDrawBuffers) if (colorAttachment >= context->getCaps().maxDrawBuffers)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -1087,7 +1174,8 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, ...@@ -1087,7 +1174,8 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
case GL_TEXTURE_BINDING_2D_ARRAY: case GL_TEXTURE_BINDING_2D_ARRAY:
if (context->getState().getActiveSampler() >= context->getCaps().maxCombinedTextureImageUnits) if (context->getState().getActiveSampler() >= context->getCaps().maxCombinedTextureImageUnits)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
...@@ -1098,13 +1186,15 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, ...@@ -1098,13 +1186,15 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
ASSERT(framebuffer); ASSERT(framebuffer);
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
FramebufferAttachment *attachment = framebuffer->getReadColorbuffer(); FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
if (!attachment) if (!attachment)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
break; break;
...@@ -1129,38 +1219,45 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1129,38 +1219,45 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
if (!ValidTexture2DDestinationTarget(context, target)) if (!ValidTexture2DDestinationTarget(context, target))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (level < 0 || xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0) if (level < 0 || xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (border != 0) if (border != 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (!ValidMipLevel(context, target, level)) if (!ValidMipLevel(context, target, level))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{ {
return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
} }
if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0) if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::Caps &caps = context->getCaps(); const gl::Caps &caps = context->getCaps();
...@@ -1240,24 +1337,28 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1240,24 +1337,28 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (!texture) if (!texture)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (texture->isImmutable() && !isSubImage) if (texture->isImmutable() && !isSubImage)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
if (formatInfo.depthBits > 0) if (formatInfo.depthBits > 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (formatInfo.compressed) if (formatInfo.compressed)
...@@ -1265,7 +1366,8 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1265,7 +1366,8 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
if (((width % formatInfo.compressedBlockWidth) != 0 && width != textureLevelWidth) || if (((width % formatInfo.compressedBlockWidth) != 0 && width != textureLevelWidth) ||
((height % formatInfo.compressedBlockHeight) != 0 && height != textureLevelHeight)) ((height % formatInfo.compressedBlockHeight) != 0 && height != textureLevelHeight))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -1275,25 +1377,29 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1275,25 +1377,29 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
yoffset + height > textureLevelHeight || yoffset + height > textureLevelHeight ||
zoffset >= textureLevelDepth) zoffset >= textureLevelDepth)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
else else
{ {
if (IsCubemapTextureTarget(target) && width != height) if (IsCubemapTextureTarget(target) && width != height)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
int maxLevelDimension = (maxDimension >> level); int maxLevelDimension = (maxDimension >> level);
if (static_cast<int>(width) > maxLevelDimension || static_cast<int>(height) > maxLevelDimension) if (static_cast<int>(width) > maxLevelDimension || static_cast<int>(height) > maxLevelDimension)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
...@@ -1301,7 +1407,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1301,7 +1407,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
return true; return true;
} }
static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count, GLsizei maxVertex, GLsizei primcount) static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsizei maxVertex, GLsizei primcount)
{ {
switch (mode) switch (mode)
{ {
...@@ -1314,18 +1420,23 @@ static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count, ...@@ -1314,18 +1420,23 @@ static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count,
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (count < 0) if (count < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
const State &state = context->getState();
// Check for mapped buffers // Check for mapped buffers
if (state.hasMappedBuffer(GL_ARRAY_BUFFER)) if (state.hasMappedBuffer(GL_ARRAY_BUFFER))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
...@@ -1337,24 +1448,28 @@ static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count, ...@@ -1337,24 +1448,28 @@ static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count,
// See Section 6.10 of the WebGL 1.0 spec // See Section 6.10 of the WebGL 1.0 spec
ERR("This ANGLE implementation does not support separate front/back stencil " ERR("This ANGLE implementation does not support separate front/back stencil "
"writemasks, reference values, or stencil mask values."); "writemasks, reference values, or stencil mask values.");
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::Framebuffer *fbo = state.getDrawFramebuffer(); const gl::Framebuffer *fbo = state.getDrawFramebuffer();
if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE) if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
{ {
return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
} }
if (state.getCurrentProgramId() == 0) if (state.getCurrentProgramId() == 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
gl::ProgramBinary *programBinary = state.getCurrentProgramBinary(); gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
if (!programBinary->validateSamplers(NULL)) if (!programBinary->validateSamplers(NULL))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// Buffer validations // Buffer validations
...@@ -1388,15 +1503,16 @@ static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count, ...@@ -1388,15 +1503,16 @@ static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count,
// enough backing data. // enough backing data.
if (attribDataSize > buffer->getSize()) if (attribDataSize > buffer->getSize())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
else if (attrib.pointer == NULL) else if (attrib.pointer == NULL)
{ {
// This is an application error that would normally result in a crash, // This is an application error that would normally result in a crash,
// but we catch it and return an error // but we catch it and return an error
ERR("An enabled vertex array has no buffer and no pointer."); context->recordError(Error(GL_INVALID_OPERATION, "An enabled vertex array has no buffer and no pointer."));
return gl::error(GL_INVALID_OPERATION, false); return false;
} }
} }
} }
...@@ -1405,11 +1521,12 @@ static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count, ...@@ -1405,11 +1521,12 @@ static bool ValidateDrawBase(const gl::State &state, GLenum mode, GLsizei count,
return (count > 0); return (count > 0);
} }
bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount) bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{ {
if (first < 0) if (first < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
const State &state = context->getState(); const State &state = context->getState();
...@@ -1420,10 +1537,11 @@ bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GL ...@@ -1420,10 +1537,11 @@ bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GL
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
// that does not match the current transform feedback object's draw mode (if transform feedback // that does not match the current transform feedback object's draw mode (if transform feedback
// is active), (3.0.2, section 2.14, pg 86) // is active), (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (!ValidateDrawBase(state, mode, count, count, primcount)) if (!ValidateDrawBase(context, mode, count, count, primcount))
{ {
return false; return false;
} }
...@@ -1431,11 +1549,12 @@ bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GL ...@@ -1431,11 +1549,12 @@ bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GL
return true; return true;
} }
bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount) bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{ {
if (primcount < 0) if (primcount < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (!ValidateDrawArrays(context, mode, first, count, primcount)) if (!ValidateDrawArrays(context, mode, first, count, primcount))
...@@ -1447,7 +1566,7 @@ bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint ...@@ -1447,7 +1566,7 @@ bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint
return (primcount > 0); return (primcount > 0);
} }
bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type,
const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut) const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut)
{ {
switch (type) switch (type)
...@@ -1458,11 +1577,13 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count ...@@ -1458,11 +1577,13 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
if (!context->getExtensions().elementIndexUint) if (!context->getExtensions().elementIndexUint)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
const State &state = context->getState(); const State &state = context->getState();
...@@ -1472,20 +1593,23 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count ...@@ -1472,20 +1593,23 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count
{ {
// It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
// while transform feedback is active, (3.0.2, section 2.14, pg 86) // while transform feedback is active, (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// Check for mapped buffers // Check for mapped buffers
if (state.hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER)) if (state.hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::VertexArray *vao = state.getVertexArray(); const gl::VertexArray *vao = state.getVertexArray();
const gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); const gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
if (!indices && !elementArrayBuffer) if (!indices && !elementArrayBuffer)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (elementArrayBuffer) if (elementArrayBuffer)
...@@ -1499,19 +1623,22 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count ...@@ -1499,19 +1623,22 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count
if (static_cast<GLuint>(count) > (std::numeric_limits<GLuint>::max() / typeInfo.bytes) || if (static_cast<GLuint>(count) > (std::numeric_limits<GLuint>::max() / typeInfo.bytes) ||
byteCount > static_cast<GLint64>(std::numeric_limits<GLuint>::max())) byteCount > static_cast<GLint64>(std::numeric_limits<GLuint>::max()))
{ {
return gl::error(GL_OUT_OF_MEMORY, false); context->recordError(Error(GL_OUT_OF_MEMORY));
return false;
} }
// Check for reading past the end of the bound buffer object // Check for reading past the end of the bound buffer object
if (byteCount > elementArrayBuffer->getSize()) if (byteCount > elementArrayBuffer->getSize())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
else if (!indices) else if (!indices)
{ {
// Catch this programming error here // Catch this programming error here
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// Use max index to validate if our vertex buffers are large enough for the pull. // Use max index to validate if our vertex buffers are large enough for the pull.
...@@ -1532,7 +1659,7 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count ...@@ -1532,7 +1659,7 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count
*indexRangeOut = rx::IndexRangeCache::ComputeRange(type, indices, count); *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, indices, count);
} }
if (!ValidateDrawBase(state, mode, count, static_cast<GLsizei>(indexRangeOut->end), primcount)) if (!ValidateDrawBase(context, mode, count, static_cast<GLsizei>(indexRangeOut->end), primcount))
{ {
return false; return false;
} }
...@@ -1540,14 +1667,15 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count ...@@ -1540,14 +1667,15 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count
return true; return true;
} }
bool ValidateDrawElementsInstanced(const gl::Context *context, bool ValidateDrawElementsInstanced(Context *context,
GLenum mode, GLsizei count, GLenum type, GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei primcount, const GLvoid *indices, GLsizei primcount,
rx::RangeUI *indexRangeOut) rx::RangeUI *indexRangeOut)
{ {
if (primcount < 0) if (primcount < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (!ValidateDrawElements(context, mode, count, type, indices, primcount, indexRangeOut)) if (!ValidateDrawElements(context, mode, count, type, indices, primcount, indexRangeOut))
...@@ -1559,12 +1687,13 @@ bool ValidateDrawElementsInstanced(const gl::Context *context, ...@@ -1559,12 +1687,13 @@ bool ValidateDrawElementsInstanced(const gl::Context *context,
return (primcount > 0); return (primcount > 0);
} }
bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level) GLuint texture, GLint level)
{ {
if (!ValidFramebufferTarget(target)) if (!ValidFramebufferTarget(target))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (!ValidateAttachmentTarget(context, attachment)) if (!ValidateAttachmentTarget(context, attachment))
...@@ -1578,12 +1707,14 @@ bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, G ...@@ -1578,12 +1707,14 @@ bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, G
if (tex == NULL) if (tex == NULL)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (level < 0) if (level < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
...@@ -1592,19 +1723,21 @@ bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, G ...@@ -1592,19 +1723,21 @@ bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, G
if (framebufferHandle == 0 || !framebuffer) if (framebufferHandle == 0 || !framebuffer)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
} }
bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level) GLenum textarget, GLuint texture, GLint level)
{ {
// Attachments are required to be bound to level 0 in ES2 // Attachments are required to be bound to level 0 in ES2
if (context->getClientVersion() < 3 && level != 0) if (context->getClientVersion() < 3 && level != 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level)) if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
...@@ -1625,16 +1758,19 @@ bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLe ...@@ -1625,16 +1758,19 @@ bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLe
{ {
if (level > gl::log2(caps.max2DTextureSize)) if (level > gl::log2(caps.max2DTextureSize))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (tex->getTarget() != GL_TEXTURE_2D) if (tex->getTarget() != GL_TEXTURE_2D)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex); gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
if (tex2d->isCompressed(level)) if (tex2d->isCompressed(level))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
break; break;
...@@ -1648,67 +1784,75 @@ bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLe ...@@ -1648,67 +1784,75 @@ bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLe
{ {
if (level > gl::log2(caps.maxCubeMapTextureSize)) if (level > gl::log2(caps.maxCubeMapTextureSize))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex); gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
if (texcube->isCompressed(textarget, level)) if (texcube->isCompressed(textarget, level))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
return true; return true;
} }
bool ValidateGetUniformBase(const gl::Context *context, GLuint program, GLint location) bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
{ {
if (program == 0) if (program == 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::Program *programObject = context->getProgram(program); gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked()) if (!programObject || !programObject->isLinked())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
gl::ProgramBinary *programBinary = programObject->getProgramBinary(); gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary) if (!programBinary)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (!programBinary->isValidUniformLocation(location)) if (!programBinary->isValidUniformLocation(location))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
} }
bool ValidateGetUniformfv(const gl::Context *context, GLuint program, GLint location, GLfloat* params) bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params)
{ {
return ValidateGetUniformBase(context, program, location); return ValidateGetUniformBase(context, program, location);
} }
bool ValidateGetUniformiv(const gl::Context *context, GLuint program, GLint location, GLint* params) bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint* params)
{ {
return ValidateGetUniformBase(context, program, location); return ValidateGetUniformBase(context, program, location);
} }
static bool ValidateSizedGetUniform(const gl::Context *context, GLuint program, GLint location, GLsizei bufSize) static bool ValidateSizedGetUniform(Context *context, GLuint program, GLint location, GLsizei bufSize)
{ {
if (!ValidateGetUniformBase(context, program, location)) if (!ValidateGetUniformBase(context, program, location))
{ {
...@@ -1722,18 +1866,19 @@ static bool ValidateSizedGetUniform(const gl::Context *context, GLuint program, ...@@ -1722,18 +1866,19 @@ static bool ValidateSizedGetUniform(const gl::Context *context, GLuint program,
size_t requiredBytes = VariableExternalSize(uniform->type); size_t requiredBytes = VariableExternalSize(uniform->type);
if (static_cast<size_t>(bufSize) < requiredBytes) if (static_cast<size_t>(bufSize) < requiredBytes)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
} }
bool ValidateGetnUniformfvEXT(const gl::Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params) bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
{ {
return ValidateSizedGetUniform(context, program, location, bufSize); return ValidateSizedGetUniform(context, program, location, bufSize);
} }
bool ValidateGetnUniformivEXT(const gl::Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params) bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params)
{ {
return ValidateSizedGetUniform(context, program, location, bufSize); return ValidateSizedGetUniform(context, program, location, bufSize);
} }
......
...@@ -26,63 +26,63 @@ bool ValidFramebufferTarget(GLenum target); ...@@ -26,63 +26,63 @@ bool ValidFramebufferTarget(GLenum target);
bool ValidBufferTarget(const Context *context, GLenum target); bool ValidBufferTarget(const Context *context, GLenum target);
bool ValidBufferParameter(const Context *context, GLenum pname); bool ValidBufferParameter(const Context *context, GLenum pname);
bool ValidMipLevel(const Context *context, GLenum target, GLint level); bool ValidMipLevel(const Context *context, GLenum target, GLint level);
bool ValidImageSize(const gl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth); bool ValidImageSize(const Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth);
bool ValidCompressedImageSize(const gl::Context *context, GLenum internalFormat, GLsizei width, GLsizei height); bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height);
bool ValidQueryType(const gl::Context *context, GLenum queryType); bool ValidQueryType(const Context *context, GLenum queryType);
bool ValidProgram(const gl::Context *context, GLuint id); bool ValidProgram(Context *context, GLuint id);
bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment); bool ValidateAttachmentTarget(Context *context, GLenum attachment);
bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples, bool ValidateRenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height, GLenum internalformat, GLsizei width, GLsizei height,
bool angleExtension); bool angleExtension);
bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferRenderbufferParameters(Context *context, GLenum target, GLenum attachment,
GLenum renderbuffertarget, GLuint renderbuffer); GLenum renderbuffertarget, GLuint renderbuffer);
bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, bool ValidateBlitFramebufferParameters(Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask,
GLenum filter, bool fromAngleExtension); GLenum filter, bool fromAngleExtension);
bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion); bool ValidateGetVertexAttribParameters(Context *context, GLenum pname);
bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param); bool ValidateTexParamParameters(Context *context, GLenum pname, GLint param);
bool ValidateSamplerObjectParameter(GLenum pname); bool ValidateSamplerObjectParameter(Context *context, GLenum pname);
bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsizei width, GLsizei height, bool ValidateReadPixelsParameters(Context *context, GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels); GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels);
bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id); bool ValidateBeginQuery(Context *context, GLenum target, GLuint id);
bool ValidateEndQuery(gl::Context *context, GLenum target); bool ValidateEndQuery(Context *context, GLenum target);
bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count); bool ValidateUniform(Context *context, GLenum uniformType, GLint location, GLsizei count);
bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint location, GLsizei count, bool ValidateUniformMatrix(Context *context, GLenum matrixType, GLint location, GLsizei count,
GLboolean transpose); GLboolean transpose);
bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams); bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams);
bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, bool ValidateCopyTexImageParametersBase(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height,
GLint border, GLenum *textureInternalFormatOut); GLint border, GLenum *textureInternalFormatOut);
bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type,
const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut); const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut);
bool ValidateDrawElementsInstanced(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, bool ValidateDrawElementsInstanced(Context *context, GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut); const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut);
bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level); GLuint texture, GLint level);
bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level); GLenum textarget, GLuint texture, GLint level);
bool ValidateGetUniformBase(const gl::Context *context, GLuint program, GLint location); bool ValidateGetUniformBase(Context *context, GLuint program, GLint location);
bool ValidateGetUniformfv(const gl::Context *context, GLuint program, GLint location, GLfloat* params); bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params);
bool ValidateGetUniformiv(const gl::Context *context, GLuint program, GLint location, GLint* params); bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint* params);
bool ValidateGetnUniformfvEXT(const gl::Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params); bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
bool ValidateGetnUniformivEXT(const gl::Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params); bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params);
} }
......
...@@ -22,25 +22,28 @@ ...@@ -22,25 +22,28 @@
namespace gl namespace gl
{ {
static bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height, static bool ValidateSubImageParams2D(Context *context, bool compressed, GLsizei width, GLsizei height,
GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type, GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
gl::Texture2D *texture) gl::Texture2D *texture)
{ {
if (!texture) if (!texture)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (compressed != texture->isCompressed(level)) if (compressed != texture->isCompressed(level))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (format != GL_NONE) if (format != GL_NONE)
{ {
if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(level)) if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(level))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -49,38 +52,43 @@ static bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei hei ...@@ -49,38 +52,43 @@ static bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei hei
if ((width % 4 != 0 && width != texture->getWidth(level)) || if ((width % 4 != 0 && width != texture->getWidth(level)) ||
(height % 4 != 0 && height != texture->getHeight(level))) (height % 4 != 0 && height != texture->getHeight(level)))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
if (xoffset + width > texture->getWidth(level) || if (xoffset + width > texture->getWidth(level) ||
yoffset + height > texture->getHeight(level)) yoffset + height > texture->getHeight(level))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
return true; return true;
} }
static bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height, static bool ValidateSubImageParamsCube(Context *context, bool compressed, GLsizei width, GLsizei height,
GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
gl::TextureCubeMap *texture) gl::TextureCubeMap *texture)
{ {
if (!texture) if (!texture)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (compressed != texture->isCompressed(target, level)) if (compressed != texture->isCompressed(target, level))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (format != GL_NONE) if (format != GL_NONE)
{ {
if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(target, level)) if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(target, level))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -89,43 +97,49 @@ static bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei h ...@@ -89,43 +97,49 @@ static bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei h
if ((width % 4 != 0 && width != texture->getWidth(target, 0)) || if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
(height % 4 != 0 && height != texture->getHeight(target, 0))) (height % 4 != 0 && height != texture->getHeight(target, 0)))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
if (xoffset + width > texture->getWidth(target, level) || if (xoffset + width > texture->getWidth(target, level) ||
yoffset + height > texture->getHeight(target, level)) yoffset + height > texture->getHeight(target, level))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
return true; return true;
} }
bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, const GLvoid *pixels) GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{ {
if (!ValidTexture2DDestinationTarget(context, target)) if (!ValidTexture2DDestinationTarget(context, target))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (!ValidImageSize(context, target, level, width, height, 1)) if (!ValidImageSize(context, target, level, width, height, 1))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (level < 0 || xoffset < 0 || if (level < 0 || xoffset < 0 ||
std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - xoffset < width ||
std::numeric_limits<GLsizei>::max() - yoffset < height) std::numeric_limits<GLsizei>::max() - yoffset < height)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (!isSubImage && !isCompressed && internalformat != format) if (!isSubImage && !isCompressed && internalformat != format)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::Caps &caps = context->getCaps(); const gl::Caps &caps = context->getCaps();
...@@ -142,7 +156,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -142,7 +156,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) || if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
static_cast<GLuint>(height) > (caps.max2DTextureSize >> level)) static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::Texture2D *tex2d = context->getTexture2D(); gl::Texture2D *tex2d = context->getTexture2D();
...@@ -155,7 +170,7 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -155,7 +170,7 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
texture = tex2d; texture = tex2d;
} }
if (isSubImage && !validateSubImageParams2D(isCompressed, width, height, xoffset, yoffset, if (isSubImage && !ValidateSubImageParams2D(context, isCompressed, width, height, xoffset, yoffset,
level, format, type, tex2d)) level, format, type, tex2d))
{ {
return false; return false;
...@@ -174,13 +189,15 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -174,13 +189,15 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
{ {
if (!isSubImage && width != height) if (!isSubImage && width != height)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) || if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level)) static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::TextureCubeMap *texCube = context->getTextureCubeMap(); gl::TextureCubeMap *texCube = context->getTextureCubeMap();
...@@ -193,7 +210,7 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -193,7 +210,7 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
texture = texCube; texture = texCube;
} }
if (isSubImage && !validateSubImageParamsCube(isCompressed, width, height, xoffset, yoffset, if (isSubImage && !ValidateSubImageParamsCube(context, isCompressed, width, height, xoffset, yoffset,
target, level, format, type, texCube)) target, level, format, type, texCube))
{ {
return false; return false;
...@@ -202,23 +219,27 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -202,23 +219,27 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (!texture) if (!texture)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (!isSubImage && texture->isImmutable()) if (!isSubImage && texture->isImmutable())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// Verify zero border // Verify zero border
if (border != 0) if (border != 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat; GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
...@@ -226,7 +247,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -226,7 +247,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
{ {
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
switch (actualInternalFormat) switch (actualInternalFormat)
...@@ -235,23 +257,27 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -235,23 +257,27 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (!context->getExtensions().textureCompressionDXT1) if (!context->getExtensions().textureCompressionDXT1)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (!context->getExtensions().textureCompressionDXT1) if (!context->getExtensions().textureCompressionDXT1)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (!context->getExtensions().textureCompressionDXT5) if (!context->getExtensions().textureCompressionDXT5)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
else else
...@@ -270,7 +296,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -270,7 +296,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_FLOAT: case GL_FLOAT:
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
// validate <format> + <type> combinations // validate <format> + <type> combinations
...@@ -287,15 +314,17 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -287,15 +314,17 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_FLOAT: case GL_FLOAT:
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES:
break; break;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_RED: case GL_RED:
case GL_RG: case GL_RG:
if (!context->getExtensions().textureRG) if (!context->getExtensions().textureRG)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
switch (type) switch (type)
{ {
...@@ -304,7 +333,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -304,7 +333,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES:
break; break;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_RGB: case GL_RGB:
...@@ -316,7 +346,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -316,7 +346,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES:
break; break;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_RGBA: case GL_RGBA:
...@@ -329,7 +360,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -329,7 +360,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES:
break; break;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_BGRA_EXT: case GL_BGRA_EXT:
...@@ -338,21 +370,24 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -338,21 +370,24 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
break; break;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_SRGB_EXT: case GL_SRGB_EXT:
case GL_SRGB_ALPHA_EXT: case GL_SRGB_ALPHA_EXT:
if (!context->getExtensions().sRGB) if (!context->getExtensions().sRGB)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
switch (type) switch (type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
break; break;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
...@@ -367,7 +402,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -367,7 +402,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
break; break;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_DEPTH_STENCIL_OES: case GL_DEPTH_STENCIL_OES:
...@@ -376,11 +412,13 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -376,11 +412,13 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_UNSIGNED_INT_24_8_OES: case GL_UNSIGNED_INT_24_8_OES:
break; break;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
switch (format) switch (format)
...@@ -389,48 +427,57 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -389,48 +427,57 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (context->getExtensions().textureCompressionDXT1) if (context->getExtensions().textureCompressionDXT1)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
else else
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (context->getExtensions().textureCompressionDXT3) if (context->getExtensions().textureCompressionDXT3)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
else else
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (context->getExtensions().textureCompressionDXT5) if (context->getExtensions().textureCompressionDXT5)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
else else
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES: case GL_DEPTH_STENCIL_OES:
if (!context->getExtensions().depthTextures) if (!context->getExtensions().depthTextures)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (target != GL_TEXTURE_2D) if (target != GL_TEXTURE_2D)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// OES_depth_texture supports loading depth data and multiple levels, // OES_depth_texture supports loading depth data and multiple levels,
// but ANGLE_depth_texture does not // but ANGLE_depth_texture does not
if (pixels != NULL || level != 0) if (pixels != NULL || level != 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
default: default:
...@@ -441,14 +488,16 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -441,14 +488,16 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
{ {
if (!context->getExtensions().textureFloat) if (!context->getExtensions().textureFloat)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
else if (type == GL_HALF_FLOAT_OES) else if (type == GL_HALF_FLOAT_OES)
{ {
if (!context->getExtensions().textureHalfFloat) if (!context->getExtensions().textureHalfFloat)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
} }
...@@ -458,7 +507,7 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -458,7 +507,7 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
GLint border) GLint border)
{ {
...@@ -485,7 +534,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -485,7 +534,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_LUMINANCE: case GL_LUMINANCE:
...@@ -497,7 +547,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -497,7 +547,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_RED_EXT: case GL_RED_EXT:
...@@ -509,7 +560,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -509,7 +560,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_RG_EXT: case GL_RG_EXT:
...@@ -520,7 +572,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -520,7 +572,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_RGB: case GL_RGB:
...@@ -530,7 +583,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -530,7 +583,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:
...@@ -539,19 +593,23 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -539,19 +593,23 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES: case GL_DEPTH_STENCIL_OES:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
else else
...@@ -565,7 +623,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -565,7 +623,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_LUMINANCE: case GL_LUMINANCE:
...@@ -578,7 +637,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -578,7 +637,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_RED_EXT: case GL_RED_EXT:
...@@ -591,7 +651,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -591,7 +651,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_RG_EXT: case GL_RG_EXT:
...@@ -603,7 +664,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -603,7 +664,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_RGB: case GL_RGB:
...@@ -614,7 +676,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -614,7 +676,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:
...@@ -624,38 +687,45 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -624,38 +687,45 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES) colorbufferFormat != GL_RGBA8_OES)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (context->getExtensions().textureCompressionDXT1) if (context->getExtensions().textureCompressionDXT1)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
else else
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (context->getExtensions().textureCompressionDXT3) if (context->getExtensions().textureCompressionDXT3)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
else else
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (context->getExtensions().textureCompressionDXT5) if (context->getExtensions().textureCompressionDXT5)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
else else
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT:
...@@ -665,14 +735,17 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -665,14 +735,17 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
case GL_DEPTH24_STENCIL8_OES: case GL_DEPTH24_STENCIL8_OES:
if (context->getExtensions().depthTextures) if (context->getExtensions().depthTextures)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
else else
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
...@@ -680,33 +753,38 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin ...@@ -680,33 +753,38 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
return (width > 0 && height > 0); return (width > 0 && height > 0);
} }
bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat, bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height) GLsizei width, GLsizei height)
{ {
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (width < 1 || height < 1 || levels < 1) if (width < 1 || height < 1 || levels < 1)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (target == GL_TEXTURE_CUBE_MAP && width != height) if (target == GL_TEXTURE_CUBE_MAP && width != height)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1) if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE) if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
const gl::Caps &caps = context->getCaps(); const gl::Caps &caps = context->getCaps();
...@@ -717,25 +795,29 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -717,25 +795,29 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
if (static_cast<GLuint>(width) > caps.max2DTextureSize || if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize) static_cast<GLuint>(height) > caps.max2DTextureSize)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
break; break;
case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP:
if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize || if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
static_cast<GLuint>(height) > caps.maxCubeMapTextureSize) static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (levels != 1 && !context->getExtensions().textureNPOT) if (levels != 1 && !context->getExtensions().textureNPOT)
{ {
if (!gl::isPow2(width) || !gl::isPow2(height)) if (!gl::isPow2(width) || !gl::isPow2(height))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -745,19 +827,22 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -745,19 +827,22 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (!context->getExtensions().textureCompressionDXT1) if (!context->getExtensions().textureCompressionDXT1)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (!context->getExtensions().textureCompressionDXT3) if (!context->getExtensions().textureCompressionDXT3)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (!context->getExtensions().textureCompressionDXT5) if (!context->getExtensions().textureCompressionDXT5)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_RGBA32F_EXT: case GL_RGBA32F_EXT:
...@@ -767,7 +852,8 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -767,7 +852,8 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_LUMINANCE_ALPHA32F_EXT: case GL_LUMINANCE_ALPHA32F_EXT:
if (!context->getExtensions().textureFloat) if (!context->getExtensions().textureFloat)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_RGBA16F_EXT: case GL_RGBA16F_EXT:
...@@ -777,7 +863,8 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -777,7 +863,8 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_LUMINANCE_ALPHA16F_EXT: case GL_LUMINANCE_ALPHA16F_EXT:
if (!context->getExtensions().textureHalfFloat) if (!context->getExtensions().textureHalfFloat)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_R8_EXT: case GL_R8_EXT:
...@@ -788,7 +875,8 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -788,7 +875,8 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_RG32F_EXT: case GL_RG32F_EXT:
if (!context->getExtensions().textureRG) if (!context->getExtensions().textureRG)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT16:
...@@ -796,16 +884,19 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -796,16 +884,19 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_DEPTH24_STENCIL8_OES: case GL_DEPTH24_STENCIL8_OES:
if (!context->getExtensions().depthTextures) if (!context->getExtensions().depthTextures)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (target != GL_TEXTURE_2D) if (target != GL_TEXTURE_2D)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// ANGLE_depth_texture only supports 1-level textures // ANGLE_depth_texture only supports 1-level textures
if (levels != 1) if (levels != 1)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
break; break;
default: default:
...@@ -827,19 +918,21 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -827,19 +918,21 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
if (!texture || texture->id() == 0) if (!texture || texture->id() == 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (texture->isImmutable()) if (texture->isImmutable())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
} }
// check for combinations of format and type that are valid for ReadPixels // check for combinations of format and type that are valid for ReadPixels
bool ValidES2ReadFormatType(gl::Context *context, GLenum format, GLenum type) bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
{ {
switch (format) switch (format)
{ {
......
...@@ -16,18 +16,18 @@ namespace gl ...@@ -16,18 +16,18 @@ namespace gl
class Context; class Context;
bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLint border, GLenum format, GLenum type, const GLvoid *pixels);
bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
GLint border); GLint border);
bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat, bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height); GLsizei width, GLsizei height);
bool ValidES2ReadFormatType(gl::Context *context, GLenum format, GLenum type); bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type);
} }
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
namespace gl namespace gl
{ {
// ES3 has a specific set of permutations of internal formats, formats and types which are acceptable.
struct ES3FormatCombination struct ES3FormatCombination
{ {
GLenum internalFormat; GLenum internalFormat;
...@@ -224,7 +223,8 @@ static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum inter ...@@ -224,7 +223,8 @@ static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum inter
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
// The type and format are valid if any supported internal format has that type and format // The type and format are valid if any supported internal format has that type and format
...@@ -257,7 +257,8 @@ static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum inter ...@@ -257,7 +257,8 @@ static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum inter
if (!typeSupported || !formatSupported) if (!typeSupported || !formatSupported)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
// Check if this is a valid format combination to load texture data // Check if this is a valid format combination to load texture data
...@@ -268,31 +269,35 @@ static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum inter ...@@ -268,31 +269,35 @@ static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum inter
if (es3FormatSet.find(searchFormat) == es3FormatSet.end()) if (es3FormatSet.find(searchFormat) == es3FormatSet.end())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return true; return true;
} }
bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid *pixels) GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{ {
if (!ValidTexture2DDestinationTarget(context, target)) if (!ValidTexture2DDestinationTarget(context, target))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
// Validate image size // Validate image size
if (!ValidImageSize(context, target, level, width, height, depth)) if (!ValidImageSize(context, target, level, width, height, depth))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
// Verify zero border // Verify zero border
if (border != 0) if (border != 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (xoffset < 0 || yoffset < 0 || zoffset < 0 || if (xoffset < 0 || yoffset < 0 || zoffset < 0 ||
...@@ -300,7 +305,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -300,7 +305,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
std::numeric_limits<GLsizei>::max() - yoffset < height || std::numeric_limits<GLsizei>::max() - yoffset < height ||
std::numeric_limits<GLsizei>::max() - zoffset < depth) std::numeric_limits<GLsizei>::max() - zoffset < depth)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
const gl::Caps &caps = context->getCaps(); const gl::Caps &caps = context->getCaps();
...@@ -318,7 +324,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -318,7 +324,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) || if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
static_cast<GLuint>(height) > (caps.max2DTextureSize >> level)) static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::Texture2D *texture2d = context->getTexture2D(); gl::Texture2D *texture2d = context->getTexture2D();
...@@ -343,12 +350,14 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -343,12 +350,14 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
{ {
if (!isSubImage && width != height) if (!isSubImage && width != height)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level)) if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
...@@ -370,7 +379,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -370,7 +379,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
static_cast<GLuint>(height) > (caps.max3DTextureSize >> level) || static_cast<GLuint>(height) > (caps.max3DTextureSize >> level) ||
static_cast<GLuint>(depth) > (caps.max3DTextureSize >> level)) static_cast<GLuint>(depth) > (caps.max3DTextureSize >> level))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::Texture3D *texture3d = context->getTexture3D(); gl::Texture3D *texture3d = context->getTexture3D();
...@@ -392,7 +402,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -392,7 +402,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
static_cast<GLuint>(height) > (caps.max2DTextureSize >> level) || static_cast<GLuint>(height) > (caps.max2DTextureSize >> level) ||
static_cast<GLuint>(depth) > (caps.maxArrayTextureLayers >> level)) static_cast<GLuint>(depth) > (caps.maxArrayTextureLayers >> level))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::Texture2DArray *texture2darray = context->getTexture2DArray(); gl::Texture2DArray *texture2darray = context->getTexture2DArray();
...@@ -409,17 +420,20 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -409,17 +420,20 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (!texture) if (!texture)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (texture->isImmutable() && !isSubImage) if (texture->isImmutable() && !isSubImage)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// Validate texture formats // Validate texture formats
...@@ -429,17 +443,20 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -429,17 +443,20 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
{ {
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (!actualFormatInfo.compressed) if (!actualFormatInfo.compressed)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (target == GL_TEXTURE_3D) if (target == GL_TEXTURE_3D)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
else else
...@@ -451,7 +468,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -451,7 +468,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
if (target == GL_TEXTURE_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)) if (target == GL_TEXTURE_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -460,7 +478,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -460,7 +478,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
{ {
if (isCompressed != textureCompressed) if (isCompressed != textureCompressed)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (isCompressed) if (isCompressed)
...@@ -468,7 +487,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -468,7 +487,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
if ((width % 4 != 0 && width != textureLevelWidth) || if ((width % 4 != 0 && width != textureLevelWidth) ||
(height % 4 != 0 && height != textureLevelHeight)) (height % 4 != 0 && height != textureLevelHeight))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -479,21 +499,24 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -479,21 +499,24 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
if (xoffset < 0 || yoffset < 0 || zoffset < 0) if (xoffset < 0 || yoffset < 0 || zoffset < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (std::numeric_limits<GLsizei>::max() - xoffset < width || if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
std::numeric_limits<GLsizei>::max() - yoffset < height || std::numeric_limits<GLsizei>::max() - yoffset < height ||
std::numeric_limits<GLsizei>::max() - zoffset < depth) std::numeric_limits<GLsizei>::max() - zoffset < depth)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (xoffset + width > textureLevelWidth || if (xoffset + width > textureLevelWidth ||
yoffset + height > textureLevelHeight || yoffset + height > textureLevelHeight ||
zoffset + depth > textureLevelDepth) zoffset + depth > textureLevelDepth)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
...@@ -515,7 +538,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -515,7 +538,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
!rx::IsUnsignedMultiplicationSafe(widthSize * heightSize * depthSize, pixelBytes)) !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize * depthSize, pixelBytes))
{ {
// Overflow past the end of the buffer // Overflow past the end of the buffer
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes; size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes;
...@@ -525,7 +549,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -525,7 +549,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->getSize()))) ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->getSize())))
{ {
// Overflow past the end of the buffer // Overflow past the end of the buffer
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// ...data is not evenly divisible into the number of bytes needed to store in memory a datum // ...data is not evenly divisible into the number of bytes needed to store in memory a datum
...@@ -534,13 +559,15 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -534,13 +559,15 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
if ((offset % dataBytesPerPixel) != 0) if ((offset % dataBytesPerPixel) != 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
// ...the buffer object's data store is currently mapped. // ...the buffer object's data store is currently mapped.
if (pixelUnpackBuffer->isMapped()) if (pixelUnpackBuffer->isMapped())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -831,7 +858,7 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen ...@@ -831,7 +858,7 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen
return false; return false;
} }
bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat,
bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height, GLint border) GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{ {
...@@ -847,12 +874,14 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin ...@@ -847,12 +874,14 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{ {
return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
} }
if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0) if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
gl::FramebufferAttachment *source = framebuffer->getReadColorbuffer(); gl::FramebufferAttachment *source = framebuffer->getReadColorbuffer();
...@@ -863,7 +892,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin ...@@ -863,7 +892,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
if (!IsValidES3CopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat, if (!IsValidES3CopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat,
context->getState().getReadFramebuffer()->id())) context->getState().getReadFramebuffer()->id()))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
else else
...@@ -871,7 +901,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin ...@@ -871,7 +901,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
if (!gl::IsValidES3CopyTexImageCombination(internalformat, colorbufferInternalFormat, if (!gl::IsValidES3CopyTexImageCombination(internalformat, colorbufferInternalFormat,
context->getState().getReadFramebuffer()->id())) context->getState().getReadFramebuffer()->id()))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
...@@ -879,17 +910,19 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin ...@@ -879,17 +910,19 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
return (width > 0 && height > 0); return (width > 0 && height > 0);
} }
bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat, bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth) GLsizei width, GLsizei height, GLsizei depth)
{ {
if (width < 1 || height < 1 || depth < 1 || levels < 1) if (width < 1 || height < 1 || depth < 1 || levels < 1)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (levels > gl::log2(std::max(std::max(width, height), depth)) + 1) if (levels > gl::log2(std::max(std::max(width, height), depth)) + 1)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::Caps &caps = context->getCaps(); const gl::Caps &caps = context->getCaps();
...@@ -904,7 +937,8 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -904,7 +937,8 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize
if (static_cast<GLuint>(width) > caps.max2DTextureSize || if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize) static_cast<GLuint>(height) > caps.max2DTextureSize)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
break; break;
...@@ -915,12 +949,14 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -915,12 +949,14 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize
if (width != height) if (width != height)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize) if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
break; break;
...@@ -933,7 +969,8 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -933,7 +969,8 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize
static_cast<GLuint>(height) > caps.max3DTextureSize || static_cast<GLuint>(height) > caps.max3DTextureSize ||
static_cast<GLuint>(depth) > caps.max3DTextureSize) static_cast<GLuint>(depth) > caps.max3DTextureSize)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
break; break;
...@@ -946,50 +983,58 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize ...@@ -946,50 +983,58 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize
static_cast<GLuint>(height) > caps.max2DTextureSize || static_cast<GLuint>(height) > caps.max2DTextureSize ||
static_cast<GLuint>(depth) > caps.maxArrayTextureLayers) static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
} }
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (!texture || texture->id() == 0) if (!texture || texture->id() == 0)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (texture->isImmutable()) if (texture->isImmutable())
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (formatInfo.pixelBytes == 0) if (formatInfo.pixelBytes == 0)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
return true; return true;
} }
bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level, GLint layer) GLuint texture, GLint level, GLint layer)
{ {
if (context->getClientVersion() < 3) if (context->getClientVersion() < 3)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
if (layer < 0) if (layer < 0)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level)) if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
...@@ -1009,18 +1054,21 @@ bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target, ...@@ -1009,18 +1054,21 @@ bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target,
{ {
if (level > gl::log2(caps.max2DTextureSize)) if (level > gl::log2(caps.max2DTextureSize))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers) if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::Texture2DArray *texArray = static_cast<gl::Texture2DArray *>(tex); gl::Texture2DArray *texArray = static_cast<gl::Texture2DArray *>(tex);
if (texArray->isCompressed(level)) if (texArray->isCompressed(level))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
break; break;
...@@ -1029,31 +1077,35 @@ bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target, ...@@ -1029,31 +1077,35 @@ bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target,
{ {
if (level > gl::log2(caps.max3DTextureSize)) if (level > gl::log2(caps.max3DTextureSize))
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
if (static_cast<GLuint>(layer) >= caps.max3DTextureSize) if (static_cast<GLuint>(layer) >= caps.max3DTextureSize)
{ {
return gl::error(GL_INVALID_VALUE, false); context->recordError(Error(GL_INVALID_VALUE));
return false;
} }
gl::Texture3D *tex3d = static_cast<gl::Texture3D *>(tex); gl::Texture3D *tex3d = static_cast<gl::Texture3D *>(tex);
if (tex3d->isCompressed(level)) if (tex3d->isCompressed(level))
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
break; break;
default: default:
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
return true; return true;
} }
bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type) bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum format, GLenum type)
{ {
const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
...@@ -1130,7 +1182,7 @@ bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum ...@@ -1130,7 +1182,7 @@ bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum
return true; return true;
} }
bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target, GLsizei numAttachments, bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
const GLenum* attachments) const GLenum* attachments)
{ {
bool defaultFramebuffer = false; bool defaultFramebuffer = false;
...@@ -1145,7 +1197,8 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target ...@@ -1145,7 +1197,8 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
defaultFramebuffer = context->getState().getReadFramebuffer()->id() == 0; defaultFramebuffer = context->getState().getReadFramebuffer()->id() == 0;
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
for (int i = 0; i < numAttachments; ++i) for (int i = 0; i < numAttachments; ++i)
...@@ -1154,12 +1207,14 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target ...@@ -1154,12 +1207,14 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
{ {
if (defaultFramebuffer) if (defaultFramebuffer)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments) if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
} }
else else
...@@ -1171,7 +1226,8 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target ...@@ -1171,7 +1226,8 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
case GL_DEPTH_STENCIL_ATTACHMENT: case GL_DEPTH_STENCIL_ATTACHMENT:
if (defaultFramebuffer) if (defaultFramebuffer)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
case GL_COLOR: case GL_COLOR:
...@@ -1179,11 +1235,13 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target ...@@ -1179,11 +1235,13 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
case GL_STENCIL: case GL_STENCIL:
if (!defaultFramebuffer) if (!defaultFramebuffer)
{ {
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
break; break;
default: default:
return gl::error(GL_INVALID_ENUM, false); context->recordError(Error(GL_INVALID_ENUM));
return false;
} }
} }
} }
...@@ -1191,27 +1249,30 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target ...@@ -1191,27 +1249,30 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
return true; return true;
} }
bool ValidateClearBuffer(const gl::Context *context) bool ValidateClearBuffer(Context *context)
{ {
if (context->getClientVersion() < 3) if (context->getClientVersion() < 3)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer(); const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer();
if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE) if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
{ {
return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
} }
return true; return true;
} }
bool ValidateGetUniformuiv(const gl::Context *context, GLuint program, GLint location, GLuint* params) bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params)
{ {
if (context->getClientVersion() < 3) if (context->getClientVersion() < 3)
{ {
return gl::error(GL_INVALID_OPERATION, false); context->recordError(Error(GL_INVALID_OPERATION));
return false;
} }
return ValidateGetUniformBase(context, program, location); return ValidateGetUniformBase(context, program, location);
......
...@@ -16,28 +16,28 @@ namespace gl ...@@ -16,28 +16,28 @@ namespace gl
class Context; class Context;
bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLint border, GLenum format, GLenum type, const GLvoid *pixels);
bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat,
bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
GLsizei width, GLsizei height, GLint border); GLsizei width, GLsizei height, GLint border);
bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat, bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth); GLsizei width, GLsizei height, GLsizei depth);
bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level, GLint layer); GLuint texture, GLint level, GLint layer);
bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type); bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum format, GLenum type);
bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target, GLsizei numAttachments, bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
const GLenum* attachments); const GLenum* attachments);
bool ValidateClearBuffer(const gl::Context *context); bool ValidateClearBuffer(Context *context);
bool ValidateGetUniformuiv(const gl::Context *context, GLuint program, GLint location, GLuint* params); bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params);
} }
......
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