Commit ced53ae2 by He Yunchao Committed by Commit Bot

Fix the coding style issue for validation code

Change-Id: I63aa1c1b3bbc52b0b522e4a703e6d20574eb21ad Reviewed-on: https://chromium-review.googlesource.com/414588Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent e157e5a9
...@@ -39,9 +39,9 @@ bool ValidateDrawAttribs(ValidationContext *context, GLint primcount, GLint maxV ...@@ -39,9 +39,9 @@ bool ValidateDrawAttribs(ValidationContext *context, GLint primcount, GLint maxV
const gl::State &state = context->getGLState(); const gl::State &state = context->getGLState();
const gl::Program *program = state.getProgram(); const gl::Program *program = state.getProgram();
const VertexArray *vao = state.getVertexArray(); const VertexArray *vao = state.getVertexArray();
const auto &vertexAttribs = vao->getVertexAttributes(); const auto &vertexAttribs = vao->getVertexAttributes();
size_t maxEnabledAttrib = vao->getMaxEnabledAttribute(); size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
for (size_t attributeIndex = 0; attributeIndex < maxEnabledAttrib; ++attributeIndex) for (size_t attributeIndex = 0; attributeIndex < maxEnabledAttrib; ++attributeIndex)
{ {
const VertexAttribute &attrib = vertexAttribs[attributeIndex]; const VertexAttribute &attrib = vertexAttribs[attributeIndex];
...@@ -51,7 +51,7 @@ bool ValidateDrawAttribs(ValidationContext *context, GLint primcount, GLint maxV ...@@ -51,7 +51,7 @@ bool ValidateDrawAttribs(ValidationContext *context, GLint primcount, GLint maxV
if (buffer) if (buffer)
{ {
GLint64 attribStride = static_cast<GLint64>(ComputeVertexAttributeStride(attrib)); GLint64 attribStride = static_cast<GLint64>(ComputeVertexAttributeStride(attrib));
GLint64 maxVertexElement = 0; GLint64 maxVertexElement = 0;
if (attrib.divisor > 0) if (attrib.divisor > 0)
...@@ -1300,20 +1300,20 @@ bool ValidTextureTarget(const ValidationContext *context, GLenum target) ...@@ -1300,20 +1300,20 @@ bool ValidTextureTarget(const ValidationContext *context, GLenum target)
{ {
switch (target) switch (target)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP:
return true; return true;
case GL_TEXTURE_3D: case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_ARRAY:
return (context->getClientMajorVersion() >= 3); return (context->getClientMajorVersion() >= 3);
case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE:
UNIMPLEMENTED(); UNIMPLEMENTED();
return (context->getClientVersion() >= Version(3, 1)); return (context->getClientVersion() >= Version(3, 1));
default: default:
return false; return false;
} }
} }
...@@ -1360,16 +1360,16 @@ bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum ta ...@@ -1360,16 +1360,16 @@ bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum ta
{ {
switch (target) switch (target)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
return true; return true;
default: default:
return false; return false;
} }
} }
...@@ -1377,25 +1377,30 @@ bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum ta ...@@ -1377,25 +1377,30 @@ bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum ta
{ {
switch (target) switch (target)
{ {
case GL_TEXTURE_3D: case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_ARRAY:
return true; return true;
default: default:
return false; return false;
} }
} }
bool ValidFramebufferTarget(GLenum target) bool ValidFramebufferTarget(GLenum target)
{ {
static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER && GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER, static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
"ANGLE framebuffer enums must equal the ES3 framebuffer enums."); "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
switch (target) switch (target)
{ {
case GL_FRAMEBUFFER: return true; case GL_FRAMEBUFFER:
case GL_READ_FRAMEBUFFER: return true; return true;
case GL_DRAW_FRAMEBUFFER: return true; case GL_READ_FRAMEBUFFER:
default: return false; return true;
case GL_DRAW_FRAMEBUFFER:
return true;
default:
return false;
} }
} }
...@@ -1403,30 +1408,30 @@ bool ValidBufferTarget(const ValidationContext *context, GLenum target) ...@@ -1403,30 +1408,30 @@ bool ValidBufferTarget(const ValidationContext *context, GLenum target)
{ {
switch (target) switch (target)
{ {
case GL_ARRAY_BUFFER: case GL_ARRAY_BUFFER:
case GL_ELEMENT_ARRAY_BUFFER: case GL_ELEMENT_ARRAY_BUFFER:
return true; return true;
case GL_PIXEL_PACK_BUFFER: case GL_PIXEL_PACK_BUFFER:
case GL_PIXEL_UNPACK_BUFFER: case GL_PIXEL_UNPACK_BUFFER:
return (context->getExtensions().pixelBufferObject || return (context->getExtensions().pixelBufferObject ||
context->getClientMajorVersion() >= 3); context->getClientMajorVersion() >= 3);
case GL_COPY_READ_BUFFER: case GL_COPY_READ_BUFFER:
case GL_COPY_WRITE_BUFFER: case GL_COPY_WRITE_BUFFER:
case GL_TRANSFORM_FEEDBACK_BUFFER: case GL_TRANSFORM_FEEDBACK_BUFFER:
case GL_UNIFORM_BUFFER: case GL_UNIFORM_BUFFER:
return (context->getClientMajorVersion() >= 3); return (context->getClientMajorVersion() >= 3);
case GL_ATOMIC_COUNTER_BUFFER: case GL_ATOMIC_COUNTER_BUFFER:
case GL_SHADER_STORAGE_BUFFER: case GL_SHADER_STORAGE_BUFFER:
case GL_DRAW_INDIRECT_BUFFER: case GL_DRAW_INDIRECT_BUFFER:
case GL_DISPATCH_INDIRECT_BUFFER: case GL_DISPATCH_INDIRECT_BUFFER:
UNIMPLEMENTED(); UNIMPLEMENTED();
return context->getClientVersion() >= Version(3, 1); return context->getClientVersion() >= Version(3, 1);
default: default:
return false; return false;
} }
} }
...@@ -1439,22 +1444,23 @@ bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level) ...@@ -1439,22 +1444,23 @@ bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level)
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
maxDimension = caps.max2DTextureSize; maxDimension = caps.max2DTextureSize;
break; break;
case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
maxDimension = caps.maxCubeMapTextureSize; maxDimension = caps.maxCubeMapTextureSize;
break; break;
case GL_TEXTURE_3D: case GL_TEXTURE_3D:
maxDimension = caps.max3DTextureSize; maxDimension = caps.max3DTextureSize;
break; break;
case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_ARRAY:
maxDimension = caps.max2DTextureSize; maxDimension = caps.max2DTextureSize;
break; break;
default: UNREACHABLE(); default:
UNREACHABLE();
} }
return level <= gl::log2(static_cast<int>(maxDimension)); return level <= gl::log2(static_cast<int>(maxDimension));
...@@ -1608,30 +1614,33 @@ bool ValidImageDataSize(ValidationContext *context, ...@@ -1608,30 +1614,33 @@ bool ValidImageDataSize(ValidationContext *context,
bool ValidQueryType(const Context *context, GLenum queryType) bool ValidQueryType(const Context *context, GLenum queryType)
{ {
static_assert(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT, "GL extension enums not equal."); static_assert(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT,
static_assert(GL_ANY_SAMPLES_PASSED_CONSERVATIVE == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, "GL extension enums not equal."); "GL extension enums not equal.");
static_assert(GL_ANY_SAMPLES_PASSED_CONSERVATIVE == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
"GL extension enums not equal.");
switch (queryType) switch (queryType)
{ {
case GL_ANY_SAMPLES_PASSED: case GL_ANY_SAMPLES_PASSED:
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
return true; return true;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return (context->getClientMajorVersion() >= 3); return (context->getClientMajorVersion() >= 3);
case GL_TIME_ELAPSED_EXT: case GL_TIME_ELAPSED_EXT:
return context->getExtensions().disjointTimerQuery; return context->getExtensions().disjointTimerQuery;
case GL_COMMANDS_COMPLETED_CHROMIUM: case GL_COMMANDS_COMPLETED_CHROMIUM:
return context->getExtensions().syncQuery; return context->getExtensions().syncQuery;
default: default:
return false; return false;
} }
} }
Program *GetValidProgram(ValidationContext *context, GLuint id) Program *GetValidProgram(ValidationContext *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
// error INVALID_VALUE if the provided name is not the name of either a shader or program object and // generate the error INVALID_VALUE if the provided name is not the name of either a shader
// INVALID_OPERATION if the provided name identifies an object that is not the expected type." // or program object and INVALID_OPERATION if the provided name identifies an object
// that is not the expected type."
Program *validProgram = context->getProgram(id); Program *validProgram = context->getProgram(id);
...@@ -1689,38 +1698,42 @@ bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment) ...@@ -1689,38 +1698,42 @@ bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment)
{ {
switch (attachment) switch (attachment)
{ {
case GL_DEPTH_ATTACHMENT: case GL_DEPTH_ATTACHMENT:
case GL_STENCIL_ATTACHMENT: case GL_STENCIL_ATTACHMENT:
break; break;
case GL_DEPTH_STENCIL_ATTACHMENT: case GL_DEPTH_STENCIL_ATTACHMENT:
if (!context->getExtensions().webglCompatibility && if (!context->getExtensions().webglCompatibility &&
context->getClientMajorVersion() < 3) context->getClientMajorVersion() < 3)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
} }
return true; return true;
} }
bool ValidateRenderbufferStorageParametersBase(gl::Context *context, GLenum target, GLsizei samples, bool ValidateRenderbufferStorageParametersBase(gl::Context *context,
GLenum internalformat, GLsizei width, GLsizei height) GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height)
{ {
switch (target) switch (target)
{ {
case GL_RENDERBUFFER: case GL_RENDERBUFFER:
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
if (width < 0 || height < 0 || samples < 0) if (width < 0 || height < 0 || samples < 0)
...@@ -1762,8 +1775,12 @@ bool ValidateRenderbufferStorageParametersBase(gl::Context *context, GLenum targ ...@@ -1762,8 +1775,12 @@ bool ValidateRenderbufferStorageParametersBase(gl::Context *context, GLenum targ
return true; return true;
} }
bool ValidateRenderbufferStorageParametersANGLE(gl::Context *context, GLenum target, GLsizei samples, bool ValidateRenderbufferStorageParametersANGLE(gl::Context *context,
GLenum internalformat, GLsizei width, GLsizei height) GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height)
{ {
ASSERT(samples == 0 || context->getExtensions().framebufferMultisample); ASSERT(samples == 0 || context->getExtensions().framebufferMultisample);
...@@ -1790,11 +1807,15 @@ bool ValidateRenderbufferStorageParametersANGLE(gl::Context *context, GLenum tar ...@@ -1790,11 +1807,15 @@ bool ValidateRenderbufferStorageParametersANGLE(gl::Context *context, GLenum tar
} }
} }
return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width, height); return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
width, height);
} }
bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferRenderbufferParameters(gl::Context *context,
GLenum renderbuffertarget, GLuint renderbuffer) GLenum target,
GLenum attachment,
GLenum renderbuffertarget,
GLuint renderbuffer)
{ {
if (!ValidFramebufferTarget(target)) if (!ValidFramebufferTarget(target))
{ {
...@@ -1847,13 +1868,13 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context, ...@@ -1847,13 +1868,13 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context,
{ {
switch (filter) switch (filter)
{ {
case GL_NEAREST: case GL_NEAREST:
break; break;
case GL_LINEAR: case GL_LINEAR:
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; 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)
...@@ -1934,13 +1955,15 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context, ...@@ -1934,13 +1955,15 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context,
// The GL ES 3.0.2 spec (pg 193) states that: // The GL ES 3.0.2 spec (pg 193) states that:
// 1) If the read buffer is fixed point format, the draw buffer must be as well // 1) If the read buffer is fixed point format, the draw buffer must be as well
// 2) If the read buffer is an unsigned integer format, the draw buffer must be as well // 2) If the read buffer is an unsigned integer format, the draw buffer must be
// 3) If the read buffer is a signed integer format, the draw buffer must be as well // as well
// 3) If the read buffer is a signed integer format, the draw buffer must be as
// well
// Changes with EXT_color_buffer_float: // Changes with EXT_color_buffer_float:
// Case 1) is changed to fixed point OR floating point // Case 1) is changed to fixed point OR floating point
GLenum readComponentType = readFormat.info->componentType; GLenum readComponentType = readFormat.info->componentType;
GLenum drawComponentType = drawFormat.info->componentType; GLenum drawComponentType = drawFormat.info->componentType;
bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED || bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
readComponentType == GL_SIGNED_NORMALIZED); readComponentType == GL_SIGNED_NORMALIZED);
bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED || bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
drawComponentType == GL_SIGNED_NORMALIZED); drawComponentType == GL_SIGNED_NORMALIZED);
...@@ -1999,14 +2022,16 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context, ...@@ -1999,14 +2022,16 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context,
} }
} }
GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT}; GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
for (size_t i = 0; i < 2; i++) for (size_t i = 0; i < 2; i++)
{ {
if (mask & masks[i]) if (mask & masks[i])
{ {
const gl::FramebufferAttachment *readBuffer = readFramebuffer->getAttachment(attachments[i]); const gl::FramebufferAttachment *readBuffer =
const gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getAttachment(attachments[i]); readFramebuffer->getAttachment(attachments[i]);
const gl::FramebufferAttachment *drawBuffer =
drawFramebuffer->getAttachment(attachments[i]);
if (readBuffer && drawBuffer) if (readBuffer && drawBuffer)
{ {
...@@ -2682,7 +2707,7 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G ...@@ -2682,7 +2707,7 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G
return false; return false;
} }
GLenum targetBoolType = VariableBoolVectorType(uniformType); GLenum targetBoolType = VariableBoolVectorType(uniformType);
bool samplerUniformCheck = (IsSamplerType(uniform->type) && uniformType == GL_INT); bool samplerUniformCheck = (IsSamplerType(uniform->type) && uniformType == GL_INT);
if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type) if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type)
{ {
...@@ -2693,7 +2718,10 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G ...@@ -2693,7 +2718,10 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G
return true; return true;
} }
bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint location, GLsizei count, bool ValidateUniformMatrix(gl::Context *context,
GLenum matrixType,
GLint location,
GLsizei count,
GLboolean transpose) GLboolean transpose)
{ {
// Check for ES3 uniform entry points // Check for ES3 uniform entry points
...@@ -2753,24 +2781,24 @@ bool ValidateStateQuery(ValidationContext *context, ...@@ -2753,24 +2781,24 @@ bool ValidateStateQuery(ValidationContext *context,
switch (pname) switch (pname)
{ {
case GL_TEXTURE_BINDING_2D: case GL_TEXTURE_BINDING_2D:
case GL_TEXTURE_BINDING_CUBE_MAP: case GL_TEXTURE_BINDING_CUBE_MAP:
case GL_TEXTURE_BINDING_3D: case GL_TEXTURE_BINDING_3D:
case GL_TEXTURE_BINDING_2D_ARRAY: case GL_TEXTURE_BINDING_2D_ARRAY:
break; break;
case GL_TEXTURE_BINDING_EXTERNAL_OES: case GL_TEXTURE_BINDING_EXTERNAL_OES:
if (!context->getExtensions().eglStreamConsumerExternal && if (!context->getExtensions().eglStreamConsumerExternal &&
!context->getExtensions().eglImageExternal) !context->getExtensions().eglImageExternal)
{ {
context->handleError(Error(GL_INVALID_ENUM, context->handleError(Error(GL_INVALID_ENUM,
"Neither NV_EGL_stream_consumer_external nor " "Neither NV_EGL_stream_consumer_external nor "
"GL_OES_EGL_image_external extensions enabled")); "GL_OES_EGL_image_external extensions enabled"));
return false; return false;
} }
break; break;
case GL_IMPLEMENTATION_COLOR_READ_TYPE: case GL_IMPLEMENTATION_COLOR_READ_TYPE:
case GL_IMPLEMENTATION_COLOR_READ_FORMAT: case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
{ {
if (context->getGLState().getReadFramebuffer()->checkStatus( if (context->getGLState().getReadFramebuffer()->checkStatus(
context->getContextState()) != GL_FRAMEBUFFER_COMPLETE) context->getContextState()) != GL_FRAMEBUFFER_COMPLETE)
...@@ -2797,8 +2825,8 @@ bool ValidateStateQuery(ValidationContext *context, ...@@ -2797,8 +2825,8 @@ bool ValidateStateQuery(ValidationContext *context,
} }
break; break;
default: default:
break; break;
} }
// pname is valid, but there are no parameters to return // pname is valid, but there are no parameters to return
...@@ -2855,7 +2883,8 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, ...@@ -2855,7 +2883,8 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context,
return false; 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)
{ {
context->handleError(Error(GL_INVALID_VALUE)); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
...@@ -2898,30 +2927,30 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, ...@@ -2898,30 +2927,30 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context,
GLuint maxDimension = 0; GLuint maxDimension = 0;
switch (target) switch (target)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
maxDimension = caps.max2DTextureSize; maxDimension = caps.max2DTextureSize;
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
maxDimension = caps.maxCubeMapTextureSize; maxDimension = caps.maxCubeMapTextureSize;
break; break;
case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_ARRAY:
maxDimension = caps.max2DTextureSize; maxDimension = caps.max2DTextureSize;
break; break;
case GL_TEXTURE_3D: case GL_TEXTURE_3D:
maxDimension = caps.max3DTextureSize; maxDimension = caps.max3DTextureSize;
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
gl::Texture *texture = gl::Texture *texture =
...@@ -2977,7 +3006,8 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, ...@@ -2977,7 +3006,8 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context,
} }
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)
{ {
context->handleError(Error(GL_INVALID_VALUE)); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
...@@ -2998,17 +3028,17 @@ static bool ValidateDrawBase(ValidationContext *context, ...@@ -2998,17 +3028,17 @@ static bool ValidateDrawBase(ValidationContext *context,
{ {
switch (mode) switch (mode)
{ {
case GL_POINTS: case GL_POINTS:
case GL_LINES: case GL_LINES:
case GL_LINE_LOOP: case GL_LINE_LOOP:
case GL_LINE_STRIP: case GL_LINE_STRIP:
case GL_TRIANGLES: case GL_TRIANGLES:
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
if (count < 0) if (count < 0)
...@@ -3030,8 +3060,8 @@ static bool ValidateDrawBase(ValidationContext *context, ...@@ -3030,8 +3060,8 @@ static bool ValidateDrawBase(ValidationContext *context,
if (context->getLimitations().noSeparateStencilRefsAndMasks) if (context->getLimitations().noSeparateStencilRefsAndMasks)
{ {
const FramebufferAttachment *stencilBuffer = framebuffer->getStencilbuffer(); const FramebufferAttachment *stencilBuffer = framebuffer->getStencilbuffer();
GLuint stencilBits = stencilBuffer ? stencilBuffer->getStencilSize() : 0; GLuint stencilBits = stencilBuffer ? stencilBuffer->getStencilSize() : 0;
GLuint minimumRequiredStencilMask = (1 << stencilBits) - 1; GLuint minimumRequiredStencilMask = (1 << stencilBits) - 1;
const DepthStencilState &depthStencilState = state.getDepthStencilState(); const DepthStencilState &depthStencilState = state.getDepthStencilState();
if ((depthStencilState.stencilWritemask & minimumRequiredStencilMask) != if ((depthStencilState.stencilWritemask & minimumRequiredStencilMask) !=
(depthStencilState.stencilBackWritemask & minimumRequiredStencilMask) || (depthStencilState.stencilBackWritemask & minimumRequiredStencilMask) ||
...@@ -3041,8 +3071,7 @@ static bool ValidateDrawBase(ValidationContext *context, ...@@ -3041,8 +3071,7 @@ static bool ValidateDrawBase(ValidationContext *context,
{ {
// Note: these separate values are not supported in WebGL, due to D3D's limitations. See // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
// Section 6.10 of the WebGL 1.0 spec // Section 6.10 of the WebGL 1.0 spec
ERR( ERR("This ANGLE implementation does not support separate front/back stencil "
"This ANGLE implementation does not support separate front/back stencil "
"writemasks, reference values, or stencil mask values."); "writemasks, reference values, or stencil mask values.");
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
...@@ -3069,10 +3098,11 @@ static bool ValidateDrawBase(ValidationContext *context, ...@@ -3069,10 +3098,11 @@ static bool ValidateDrawBase(ValidationContext *context,
} }
// Uniform buffer validation // Uniform buffer validation
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++) for (unsigned int uniformBlockIndex = 0;
uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
{ {
const gl::UniformBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex); const gl::UniformBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex); GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
const OffsetBindingPointer<Buffer> &uniformBuffer = const OffsetBindingPointer<Buffer> &uniformBuffer =
state.getIndexedUniformBuffer(blockBinding); state.getIndexedUniformBuffer(blockBinding);
...@@ -3120,11 +3150,12 @@ bool ValidateDrawArrays(ValidationContext *context, ...@@ -3120,11 +3150,12 @@ bool ValidateDrawArrays(ValidationContext *context,
const State &state = context->getGLState(); const State &state = context->getGLState();
gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused() && if (curTransformFeedback && curTransformFeedback->isActive() &&
curTransformFeedback->getPrimitiveMode() != mode) !curTransformFeedback->isPaused() && curTransformFeedback->getPrimitiveMode() != mode)
{ {
// 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)
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
...@@ -3143,7 +3174,11 @@ bool ValidateDrawArrays(ValidationContext *context, ...@@ -3143,7 +3174,11 @@ bool ValidateDrawArrays(ValidationContext *context,
return true; return true;
} }
bool ValidateDrawArraysInstanced(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)
{ {
...@@ -3183,7 +3218,11 @@ static bool ValidateDrawInstancedANGLE(Context *context) ...@@ -3183,7 +3218,11 @@ static bool ValidateDrawInstancedANGLE(Context *context)
return false; return false;
} }
bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount) bool ValidateDrawArraysInstancedANGLE(Context *context,
GLenum mode,
GLint first,
GLsizei count,
GLsizei primcount)
{ {
if (!ValidateDrawInstancedANGLE(context)) if (!ValidateDrawInstancedANGLE(context))
{ {
...@@ -3203,27 +3242,29 @@ bool ValidateDrawElements(ValidationContext *context, ...@@ -3203,27 +3242,29 @@ bool ValidateDrawElements(ValidationContext *context,
{ {
switch (type) switch (type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT:
break; break;
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint) if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
const State &state = context->getGLState(); const State &state = context->getGLState();
gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused()) if (curTransformFeedback && curTransformFeedback->isActive() &&
!curTransformFeedback->isPaused())
{ {
// 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)
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
...@@ -3236,7 +3277,7 @@ bool ValidateDrawElements(ValidationContext *context, ...@@ -3236,7 +3277,7 @@ bool ValidateDrawElements(ValidationContext *context,
return false; return false;
} }
const gl::VertexArray *vao = state.getVertexArray(); const gl::VertexArray *vao = state.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
if (!indices && !elementArrayBuffer) if (!indices && !elementArrayBuffer)
{ {
...@@ -3249,7 +3290,8 @@ bool ValidateDrawElements(ValidationContext *context, ...@@ -3249,7 +3290,8 @@ bool ValidateDrawElements(ValidationContext *context,
const gl::Type &typeInfo = gl::GetTypeInfo(type); const gl::Type &typeInfo = gl::GetTypeInfo(type);
GLint64 offset = reinterpret_cast<GLint64>(indices); GLint64 offset = reinterpret_cast<GLint64>(indices);
GLint64 byteCount = static_cast<GLint64>(typeInfo.bytes) * static_cast<GLint64>(count)+offset; GLint64 byteCount =
static_cast<GLint64>(typeInfo.bytes) * static_cast<GLint64>(count) + offset;
// check for integer overflows // check for integer overflows
if (static_cast<GLuint>(count) > (std::numeric_limits<GLuint>::max() / typeInfo.bytes) || if (static_cast<GLuint>(count) > (std::numeric_limits<GLuint>::max() / typeInfo.bytes) ||
...@@ -3352,11 +3394,15 @@ bool ValidateDrawElementsInstancedANGLE(Context *context, ...@@ -3352,11 +3394,15 @@ bool ValidateDrawElementsInstancedANGLE(Context *context,
return false; return false;
} }
return ValidateDrawElementsInstanced(context, mode, count, type, indices, primcount, indexRangeOut); return ValidateDrawElementsInstanced(context, mode, count, type, indices, primcount,
indexRangeOut);
} }
bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTextureBase(Context *context,
GLuint texture, GLint level) GLenum target,
GLenum attachment,
GLuint texture,
GLint level)
{ {
if (!ValidFramebufferTarget(target)) if (!ValidFramebufferTarget(target))
{ {
...@@ -3399,10 +3445,15 @@ bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum atta ...@@ -3399,10 +3445,15 @@ bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum atta
return true; return true;
} }
bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTexture2D(Context *context,
GLenum textarget, GLuint texture, GLint level) GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level)
{ {
// Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap extension // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
// extension
if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap && if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
level != 0) level != 0)
{ {
...@@ -3424,7 +3475,7 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach ...@@ -3424,7 +3475,7 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach
switch (textarget) switch (textarget)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
{ {
if (level > gl::log2(caps.max2DTextureSize)) if (level > gl::log2(caps.max2DTextureSize))
{ {
...@@ -3439,12 +3490,12 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach ...@@ -3439,12 +3490,12 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach
} }
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{ {
if (level > gl::log2(caps.maxCubeMapTextureSize)) if (level > gl::log2(caps.maxCubeMapTextureSize))
{ {
...@@ -3459,9 +3510,9 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach ...@@ -3459,9 +3510,9 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach
} }
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
const Format &format = tex->getFormat(textarget, level); const Format &format = tex->getFormat(textarget, level);
...@@ -3504,12 +3555,12 @@ bool ValidateGetUniformBase(Context *context, GLuint program, GLint location) ...@@ -3504,12 +3555,12 @@ bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
return true; return true;
} }
bool ValidateGetUniformfv(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(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);
} }
...@@ -3541,7 +3592,7 @@ static bool ValidateSizedGetUniform(Context *context, ...@@ -3541,7 +3592,7 @@ static bool ValidateSizedGetUniform(Context *context,
// sized queries -- ensure the provided buffer is large enough // sized queries -- ensure the provided buffer is large enough
const LinkedUniform &uniform = programObject->getUniformByLocation(location); const LinkedUniform &uniform = programObject->getUniformByLocation(location);
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)
{ {
context->handleError( context->handleError(
...@@ -3557,12 +3608,20 @@ static bool ValidateSizedGetUniform(Context *context, ...@@ -3557,12 +3608,20 @@ static bool ValidateSizedGetUniform(Context *context,
return true; return true;
} }
bool ValidateGetnUniformfvEXT(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, nullptr); return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
} }
bool ValidateGetnUniformivEXT(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, nullptr); return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
} }
...@@ -3622,8 +3681,11 @@ bool ValidateGetUniformuivRobustANGLE(Context *context, ...@@ -3622,8 +3681,11 @@ bool ValidateGetUniformuivRobustANGLE(Context *context,
return ValidateSizedGetUniform(context, program, location, bufSize, length); return ValidateSizedGetUniform(context, program, location, bufSize, length);
} }
bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei numAttachments, bool ValidateDiscardFramebufferBase(Context *context,
const GLenum *attachments, bool defaultFramebuffer) GLenum target,
GLsizei numAttachments,
const GLenum *attachments,
bool defaultFramebuffer)
{ {
if (numAttachments < 0) if (numAttachments < 0)
{ {
...@@ -3654,31 +3716,31 @@ bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei num ...@@ -3654,31 +3716,31 @@ bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei num
{ {
switch (attachments[i]) switch (attachments[i])
{ {
case GL_DEPTH_ATTACHMENT: case GL_DEPTH_ATTACHMENT:
case GL_STENCIL_ATTACHMENT: case GL_STENCIL_ATTACHMENT:
case GL_DEPTH_STENCIL_ATTACHMENT: case GL_DEPTH_STENCIL_ATTACHMENT:
if (defaultFramebuffer) if (defaultFramebuffer)
{ {
context->handleError( context->handleError(
Error(GL_INVALID_ENUM, Error(GL_INVALID_ENUM,
"Invalid attachment when the default framebuffer is bound")); "Invalid attachment when the default framebuffer is bound"));
return false; return false;
} }
break; break;
case GL_COLOR: case GL_COLOR:
case GL_DEPTH: case GL_DEPTH:
case GL_STENCIL: case GL_STENCIL:
if (!defaultFramebuffer) if (!defaultFramebuffer)
{ {
context->handleError( context->handleError(
Error(GL_INVALID_ENUM, Error(GL_INVALID_ENUM,
"Invalid attachment when the default framebuffer is not bound")); "Invalid attachment when the default framebuffer is not bound"));
return false;
}
break;
default:
context->handleError(Error(GL_INVALID_ENUM, "Invalid attachment"));
return false; return false;
}
break;
default:
context->handleError(Error(GL_INVALID_ENUM, "Invalid attachment"));
return false;
} }
} }
} }
......
...@@ -313,8 +313,7 @@ bool ValidateES2TexImageParameters(Context *context, ...@@ -313,8 +313,7 @@ bool ValidateES2TexImageParameters(Context *context,
return false; 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)
{ {
context->handleError(Error(GL_INVALID_VALUE)); context->handleError(Error(GL_INVALID_VALUE));
...@@ -359,7 +358,8 @@ bool ValidateES2TexImageParameters(Context *context, ...@@ -359,7 +358,8 @@ bool ValidateES2TexImageParameters(Context *context,
return false; return false;
} }
gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); gl::Texture *texture =
context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
if (!texture) if (!texture)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
...@@ -413,47 +413,48 @@ bool ValidateES2TexImageParameters(Context *context, ...@@ -413,47 +413,48 @@ bool ValidateES2TexImageParameters(Context *context,
isSubImage ? texture->getFormat(target, level).asSized() : internalformat; isSubImage ? texture->getFormat(target, level).asSized() : internalformat;
switch (actualInternalFormat) switch (actualInternalFormat)
{ {
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)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; 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)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; 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)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; break;
case GL_ETC1_RGB8_OES: case GL_ETC1_RGB8_OES:
if (!context->getExtensions().compressedETC1RGB8Texture) if (!context->getExtensions().compressedETC1RGB8Texture)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
if (!context->getExtensions().lossyETCDecode)
{
context->handleError(Error(
GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported"));
return false;
}
break;
default:
context->handleError(
Error(GL_INVALID_ENUM,
"internalformat is not a supported compressed internal format"));
return false; return false;
}
break;
case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
if (!context->getExtensions().lossyETCDecode)
{
context->handleError(
Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported"));
return false;
}
break;
default:
context->handleError(Error(
GL_INVALID_ENUM, "internalformat is not a supported compressed internal format"));
return false;
} }
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
{ {
...@@ -466,19 +467,19 @@ bool ValidateES2TexImageParameters(Context *context, ...@@ -466,19 +467,19 @@ bool ValidateES2TexImageParameters(Context *context,
// validate <type> by itself (used as secondary key below) // validate <type> by itself (used as secondary key below)
switch (type) switch (type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
case GL_UNSIGNED_INT_24_8_OES: case GL_UNSIGNED_INT_24_8_OES:
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES:
case GL_FLOAT: case GL_FLOAT:
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
// validate <format> + <type> combinations // validate <format> + <type> combinations
...@@ -486,713 +487,679 @@ bool ValidateES2TexImageParameters(Context *context, ...@@ -486,713 +487,679 @@ bool ValidateES2TexImageParameters(Context *context,
// - invalid <format>+<type> combination -> sets INVALID_OPERATION // - invalid <format>+<type> combination -> sets INVALID_OPERATION
switch (format) switch (format)
{ {
case GL_ALPHA: case GL_ALPHA:
case GL_LUMINANCE: case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:
switch (type) switch (type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
case GL_FLOAT: case GL_FLOAT:
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES:
break;
default:
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break; break;
default: case GL_RED:
context->handleError(Error(GL_INVALID_OPERATION)); case GL_RG:
return false; if (!context->getExtensions().textureRG)
} {
break; context->handleError(Error(GL_INVALID_ENUM));
case GL_RED: return false;
case GL_RG: }
if (!context->getExtensions().textureRG) switch (type)
{ {
context->handleError(Error(GL_INVALID_ENUM)); case GL_UNSIGNED_BYTE:
return false; case GL_FLOAT:
} case GL_HALF_FLOAT_OES:
switch (type) break;
{ default:
case GL_UNSIGNED_BYTE: context->handleError(Error(GL_INVALID_OPERATION));
case GL_FLOAT: return false;
case GL_HALF_FLOAT_OES: }
break;
default:
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RGB:
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break; break;
default: case GL_RGB:
context->handleError(Error(GL_INVALID_OPERATION)); switch (type)
return false; {
} case GL_UNSIGNED_BYTE:
break; case GL_UNSIGNED_SHORT_5_6_5:
case GL_RGBA: case GL_FLOAT:
switch (type) case GL_HALF_FLOAT_OES:
{ break;
case GL_UNSIGNED_BYTE: default:
case GL_UNSIGNED_SHORT_4_4_4_4: context->handleError(Error(GL_INVALID_OPERATION));
case GL_UNSIGNED_SHORT_5_5_5_1: return false;
case GL_FLOAT: }
case GL_HALF_FLOAT_OES:
break; break;
default: case GL_RGBA:
context->handleError(Error(GL_INVALID_OPERATION)); switch (type)
return false; {
} case GL_UNSIGNED_BYTE:
break; case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_BGRA_EXT: case GL_UNSIGNED_SHORT_5_5_5_1:
switch (type) case GL_FLOAT:
{ case GL_HALF_FLOAT_OES:
case GL_UNSIGNED_BYTE: break;
default:
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break; break;
default: case GL_BGRA_EXT:
context->handleError(Error(GL_INVALID_OPERATION)); switch (type)
return false; {
} case GL_UNSIGNED_BYTE:
break; break;
case GL_SRGB_EXT: default:
case GL_SRGB_ALPHA_EXT: context->handleError(Error(GL_INVALID_OPERATION));
if (!context->getExtensions().sRGB) return false;
{ }
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
switch (type)
{
case GL_UNSIGNED_BYTE:
break; break;
default: case GL_SRGB_EXT:
context->handleError(Error(GL_INVALID_OPERATION)); case GL_SRGB_ALPHA_EXT:
return false; if (!context->getExtensions().sRGB)
} {
break; context->handleError(Error(GL_INVALID_ENUM));
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below return false;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: }
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: switch (type)
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: {
break; case GL_UNSIGNED_BYTE:
case GL_DEPTH_COMPONENT: break;
switch (type) default:
{ context->handleError(Error(GL_INVALID_OPERATION));
case GL_UNSIGNED_SHORT: return false;
case GL_UNSIGNED_INT: }
break; break;
default: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
context->handleError(Error(GL_INVALID_OPERATION)); // handled below
return false; case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
} case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
break; case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
case GL_DEPTH_STENCIL_OES: break;
switch (type) case GL_DEPTH_COMPONENT:
{ switch (type)
case GL_UNSIGNED_INT_24_8_OES: {
case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT:
break;
default:
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break; break;
default: case GL_DEPTH_STENCIL_OES:
context->handleError(Error(GL_INVALID_OPERATION)); switch (type)
{
case GL_UNSIGNED_INT_24_8_OES:
break;
default:
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
default:
context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
}
break;
default:
context->handleError(Error(GL_INVALID_ENUM));
return false;
} }
switch (format) switch (format)
{ {
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)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
else else
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; 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)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
else else
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (context->getExtensions().textureCompressionDXT5)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
else
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_ETC1_RGB8_OES:
if (context->getExtensions().compressedETC1RGB8Texture)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
else
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
if (context->getExtensions().lossyETCDecode)
{
context->handleError(
Error(GL_INVALID_OPERATION,
"ETC1_RGB8_LOSSY_DECODE_ANGLE can't work with this type."));
return false;
}
else
{
context->handleError(Error(
GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
return false;
}
break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES:
if (!context->getExtensions().depthTextures)
{
context->handleError(Error(GL_INVALID_VALUE));
return false;
}
if (target != GL_TEXTURE_2D)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
// OES_depth_texture supports loading depth data and multiple levels,
// but ANGLE_depth_texture does not
if (pixels != NULL || level != 0)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
default:
break;
}
if (type == GL_FLOAT)
{
if (!context->getExtensions().textureFloat)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; }
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: else if (type == GL_HALF_FLOAT_OES)
if (context->getExtensions().textureCompressionDXT5) {
{ if (!context->getExtensions().textureHalfFloat)
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
else
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; }
case GL_ETC1_RGB8_OES: }
if (context->getExtensions().compressedETC1RGB8Texture)
{ if (!ValidImageDataSize(context, target, width, height, 1, internalformat, type, pixels,
imageSize))
{
return false;
}
return true;
}
bool ValidateES2CopyTexImageParameters(ValidationContext *context,
GLenum target,
GLint level,
GLenum internalformat,
bool isSubImage,
GLint xoffset,
GLint yoffset,
GLint x,
GLint y,
GLsizei width,
GLsizei height,
GLint border)
{
if (!ValidTexture2DDestinationTarget(context, target))
{
context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target"));
return false;
}
Format textureFormat = Format::Invalid();
if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
xoffset, yoffset, 0, x, y, width, height, border,
&textureFormat))
{
return false;
}
const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getFormat().asSized();
const auto &formatInfo = *textureFormat.info;
// [OpenGL ES 2.0.24] table 3.9
if (isSubImage)
{
switch (formatInfo.format)
{
case GL_ALPHA:
if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_LUMINANCE:
if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RED_EXT:
if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
colorbufferFormat != GL_RGBA32F)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RG_EXT:
if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
colorbufferFormat != GL_RGBA32F)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RGB:
if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
colorbufferFormat != GL_RGBA32F)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_LUMINANCE_ALPHA:
case GL_RGBA:
if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
case GL_ETC1_RGB8_OES:
case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} case GL_DEPTH_COMPONENT:
else case GL_DEPTH_STENCIL_OES:
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
if (context->getExtensions().lossyETCDecode)
{
context->handleError(
Error(GL_INVALID_OPERATION,
"ETC1_RGB8_LOSSY_DECODE_ANGLE can't work with this type."));
return false;
}
else
{
context->handleError(
Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
return false;
}
break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES:
if (!context->getExtensions().depthTextures)
{
context->handleError(Error(GL_INVALID_VALUE));
return false;
}
if (target != GL_TEXTURE_2D)
{
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} default:
// OES_depth_texture supports loading depth data and multiple levels,
// but ANGLE_depth_texture does not
if (pixels != NULL || level != 0)
{
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
}
break;
default:
break;
} }
if (type == GL_FLOAT) if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
{ {
if (!context->getExtensions().textureFloat) context->handleError(Error(GL_INVALID_OPERATION));
{ return false;
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
} }
else if (type == GL_HALF_FLOAT_OES) }
else
{
switch (internalformat)
{ {
if (!context->getExtensions().textureHalfFloat) case GL_ALPHA:
{ if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_LUMINANCE:
if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RED_EXT:
if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RG_EXT:
if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RGB:
if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_LUMINANCE_ALPHA:
case GL_RGBA:
if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (context->getExtensions().textureCompressionDXT1)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
else
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (context->getExtensions().textureCompressionDXT3)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
else
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (context->getExtensions().textureCompressionDXT5)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
else
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_ETC1_RGB8_OES:
if (context->getExtensions().compressedETC1RGB8Texture)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
else
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
if (context->getExtensions().lossyETCDecode)
{
context->handleError(Error(GL_INVALID_OPERATION,
"ETC1_RGB8_LOSSY_DECODE_ANGLE can't be copied to."));
return false;
}
else
{
context->handleError(Error(
GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
return false;
}
break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_STENCIL_OES:
case GL_DEPTH24_STENCIL8_OES:
if (context->getExtensions().depthTextures)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
else
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
}
} }
} }
if (!ValidImageDataSize(context, target, width, height, 1, internalformat, type, pixels, // If width or height is zero, it is a no-op. Return false without setting an error.
imageSize)) return (width > 0 && height > 0);
}
bool ValidateES2TexStorageParameters(Context *context,
GLenum target,
GLsizei levels,
GLenum internalformat,
GLsizei width,
GLsizei height)
{
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
{ {
context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
return true; if (width < 1 || height < 1 || levels < 1)
} {
context->handleError(Error(GL_INVALID_VALUE));
return false;
}
bool ValidateES2CopyTexImageParameters(ValidationContext *context, if (target == GL_TEXTURE_CUBE_MAP && width != height)
GLenum target,
GLint level,
GLenum internalformat,
bool isSubImage,
GLint xoffset,
GLint yoffset,
GLint x,
GLint y,
GLsizei width,
GLsizei height,
GLint border)
{
if (!ValidTexture2DDestinationTarget(context, target))
{ {
context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target")); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
} }
Format textureFormat = Format::Invalid(); if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
xoffset, yoffset, 0, x, y, width, height, border,
&textureFormat))
{ {
context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer(); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getFormat().asSized(); if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
const auto &formatInfo = *textureFormat.info; {
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
// [OpenGL ES 2.0.24] table 3.9 const gl::Caps &caps = context->getCaps();
if (isSubImage)
switch (target)
{ {
switch (formatInfo.format) case GL_TEXTURE_2D:
{ if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
case GL_ALPHA: static_cast<GLuint>(height) > caps.max2DTextureSize)
if (colorbufferFormat != GL_ALPHA8_EXT &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_LUMINANCE:
if (colorbufferFormat != GL_R8_EXT &&
colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RED_EXT:
if (colorbufferFormat != GL_R8_EXT &&
colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_R32F &&
colorbufferFormat != GL_RG32F &&
colorbufferFormat != GL_RGB32F &&
colorbufferFormat != GL_RGBA32F)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RG_EXT:
if (colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_RG32F &&
colorbufferFormat != GL_RGB32F &&
colorbufferFormat != GL_RGBA32F)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RGB:
if (colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_RGB32F &&
colorbufferFormat != GL_RGBA32F)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
} }
break; break;
case GL_LUMINANCE_ALPHA: case GL_TEXTURE_CUBE_MAP:
case GL_RGBA: if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
if (colorbufferFormat != GL_RGBA4 && static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_RGBA32F)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
} }
break; break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: default:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: context->handleError(Error(GL_INVALID_ENUM));
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
case GL_ETC1_RGB8_OES:
case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
context->handleError(Error(GL_INVALID_OPERATION));
return false;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES:
context->handleError(Error(GL_INVALID_OPERATION));
return false;
default:
context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat) if (levels != 1 && !context->getExtensions().textureNPOT)
{
if (!gl::isPow2(width) || !gl::isPow2(height))
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
} }
else
switch (internalformat)
{ {
switch (internalformat) case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
{ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_ALPHA: if (!context->getExtensions().textureCompressionDXT1)
if (colorbufferFormat != GL_ALPHA8_EXT &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; break;
case GL_LUMINANCE: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (colorbufferFormat != GL_R8_EXT && if (!context->getExtensions().textureCompressionDXT3)
colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RED_EXT:
if (colorbufferFormat != GL_R8_EXT &&
colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RG_EXT:
if (colorbufferFormat != GL_RG8_EXT &&
colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
case GL_RGB:
if (colorbufferFormat != GL_RGB565 &&
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; break;
case GL_LUMINANCE_ALPHA: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
case GL_RGBA: if (!context->getExtensions().textureCompressionDXT5)
if (colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES &&
colorbufferFormat != GL_BGR5_A1_ANGLEX)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_ETC1_RGB8_OES:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: if (!context->getExtensions().compressedETC1RGB8Texture)
if (context->getExtensions().textureCompressionDXT1)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
else
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
if (context->getExtensions().textureCompressionDXT3) if (!context->getExtensions().lossyETCDecode)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(
Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
return false; return false;
} }
else break;
case GL_RGBA32F_EXT:
case GL_RGB32F_EXT:
case GL_ALPHA32F_EXT:
case GL_LUMINANCE32F_EXT:
case GL_LUMINANCE_ALPHA32F_EXT:
if (!context->getExtensions().textureFloat)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: case GL_RGBA16F_EXT:
if (context->getExtensions().textureCompressionDXT5) case GL_RGB16F_EXT:
{ case GL_ALPHA16F_EXT:
context->handleError(Error(GL_INVALID_OPERATION)); case GL_LUMINANCE16F_EXT:
return false; case GL_LUMINANCE_ALPHA16F_EXT:
} if (!context->getExtensions().textureHalfFloat)
else
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; break;
case GL_ETC1_RGB8_OES: case GL_R8_EXT:
if (context->getExtensions().compressedETC1RGB8Texture) case GL_RG8_EXT:
case GL_R16F_EXT:
case GL_RG16F_EXT:
case GL_R32F_EXT:
case GL_RG32F_EXT:
if (!context->getExtensions().textureRG)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
else break;
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH24_STENCIL8_OES:
if (!context->getExtensions().depthTextures)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
break; if (target != GL_TEXTURE_2D)
case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
if (context->getExtensions().lossyETCDecode)
{
context->handleError(Error(GL_INVALID_OPERATION,
"ETC1_RGB8_LOSSY_DECODE_ANGLE can't be copied to."));
return false;
}
else
{
context->handleError(
Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
return false;
}
break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_STENCIL_OES:
case GL_DEPTH24_STENCIL8_OES:
if (context->getExtensions().depthTextures)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
else // ANGLE_depth_texture only supports 1-level textures
if (levels != 1)
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
default: break;
context->handleError(Error(GL_INVALID_ENUM)); default:
return false; break;
}
}
// If width or height is zero, it is a no-op. Return false without setting an error.
return (width > 0 && height > 0);
}
bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height)
{
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
if (width < 1 || height < 1 || levels < 1)
{
context->handleError(Error(GL_INVALID_VALUE));
return false;
}
if (target == GL_TEXTURE_CUBE_MAP && width != height)
{
context->handleError(Error(GL_INVALID_VALUE));
return false;
}
if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
const gl::Caps &caps = context->getCaps();
switch (target)
{
case GL_TEXTURE_2D:
if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize)
{
context->handleError(Error(GL_INVALID_VALUE));
return false;
}
break;
case GL_TEXTURE_CUBE_MAP:
if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
{
context->handleError(Error(GL_INVALID_VALUE));
return false;
}
break;
default:
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
if (levels != 1 && !context->getExtensions().textureNPOT)
{
if (!gl::isPow2(width) || !gl::isPow2(height))
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
}
switch (internalformat)
{
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (!context->getExtensions().textureCompressionDXT1)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (!context->getExtensions().textureCompressionDXT3)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (!context->getExtensions().textureCompressionDXT5)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_ETC1_RGB8_OES:
if (!context->getExtensions().compressedETC1RGB8Texture)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
if (!context->getExtensions().lossyETCDecode)
{
context->handleError(
Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
return false;
}
break;
case GL_RGBA32F_EXT:
case GL_RGB32F_EXT:
case GL_ALPHA32F_EXT:
case GL_LUMINANCE32F_EXT:
case GL_LUMINANCE_ALPHA32F_EXT:
if (!context->getExtensions().textureFloat)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_RGBA16F_EXT:
case GL_RGB16F_EXT:
case GL_ALPHA16F_EXT:
case GL_LUMINANCE16F_EXT:
case GL_LUMINANCE_ALPHA16F_EXT:
if (!context->getExtensions().textureHalfFloat)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_R8_EXT:
case GL_RG8_EXT:
case GL_R16F_EXT:
case GL_RG16F_EXT:
case GL_R32F_EXT:
case GL_RG32F_EXT:
if (!context->getExtensions().textureRG)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
break;
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH24_STENCIL8_OES:
if (!context->getExtensions().depthTextures)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
if (target != GL_TEXTURE_2D)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
// ANGLE_depth_texture only supports 1-level textures
if (levels != 1)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
break;
default:
break;
} }
gl::Texture *texture = context->getTargetTexture(target); gl::Texture *texture = context->getTargetTexture(target);
...@@ -1211,7 +1178,9 @@ bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei le ...@@ -1211,7 +1178,9 @@ bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei le
return true; return true;
} }
bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments, bool ValidateDiscardFramebufferEXT(Context *context,
GLenum target,
GLsizei numAttachments,
const GLenum *attachments) const GLenum *attachments)
{ {
if (!context->getExtensions().discardFramebuffer) if (!context->getExtensions().discardFramebuffer)
...@@ -1224,16 +1193,17 @@ bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numA ...@@ -1224,16 +1193,17 @@ bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numA
switch (target) switch (target)
{ {
case GL_FRAMEBUFFER: case GL_FRAMEBUFFER:
defaultFramebuffer = defaultFramebuffer =
(context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0); (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM, "Invalid framebuffer target")); context->handleError(Error(GL_INVALID_ENUM, "Invalid framebuffer target"));
return false; return false;
} }
return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer); return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
defaultFramebuffer);
} }
bool ValidateBindVertexArrayOES(Context *context, GLuint array) bool ValidateBindVertexArrayOES(Context *context, GLuint array)
...@@ -1923,8 +1893,7 @@ bool ValidateBlitFramebufferANGLE(Context *context, ...@@ -1923,8 +1893,7 @@ bool ValidateBlitFramebufferANGLE(Context *context,
dstX0, dstY0, dstX1, dstY1)) dstX0, dstY0, dstX1, dstY1))
{ {
// only whole-buffer copies are permitted // only whole-buffer copies are permitted
ERR( ERR("Only whole-buffer depth and stencil blits are supported by this "
"Only whole-buffer depth and stencil blits are supported by this "
"implementation."); "implementation.");
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
...@@ -3149,8 +3118,9 @@ bool ValidateProgramPathFragmentInputGen(Context *context, ...@@ -3149,8 +3118,9 @@ bool ValidateProgramPathFragmentInputGen(Context *context,
expectedComponents = 4; expectedComponents = 4;
break; break;
default: default:
context->handleError(Error(GL_INVALID_OPERATION, context->handleError(
"Fragment input type is not a floating point scalar or vector.")); Error(GL_INVALID_OPERATION,
"Fragment input type is not a floating point scalar or vector."));
return false; return false;
} }
if (expectedComponents != components && genMode != GL_NONE) if (expectedComponents != components && genMode != GL_NONE)
......
...@@ -24,7 +24,10 @@ using namespace angle; ...@@ -24,7 +24,10 @@ using namespace angle;
namespace gl namespace gl
{ {
static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type) static bool ValidateTexImageFormatCombination(gl::Context *context,
GLenum internalFormat,
GLenum format,
GLenum type)
{ {
// For historical reasons, glTexImage2D and glTexImage3D pass in their internal format as a // For historical reasons, glTexImage2D and glTexImage3D pass in their internal format as a
// GLint instead of a GLenum. Therefor an invalid internal format gives a GL_INVALID_VALUE // GLint instead of a GLenum. Therefor an invalid internal format gives a GL_INVALID_VALUE
...@@ -99,60 +102,61 @@ bool ValidateES3TexImageParametersBase(Context *context, ...@@ -99,60 +102,61 @@ bool ValidateES3TexImageParametersBase(Context *context,
switch (target) switch (target)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
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))
{ {
context->handleError(Error(GL_INVALID_VALUE)); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
} }
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (!isSubImage && width != height) if (!isSubImage && width != height)
{ {
context->handleError(Error(GL_INVALID_VALUE)); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
} }
if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level)) if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level))
{ {
context->handleError(Error(GL_INVALID_VALUE)); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
} }
break; break;
case GL_TEXTURE_3D: case GL_TEXTURE_3D:
if (static_cast<GLuint>(width) > (caps.max3DTextureSize >> level) || if (static_cast<GLuint>(width) > (caps.max3DTextureSize >> level) ||
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))
{ {
context->handleError(Error(GL_INVALID_VALUE)); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
} }
break; break;
case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_ARRAY:
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) ||
static_cast<GLuint>(depth) > caps.maxArrayTextureLayers) static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
{ {
context->handleError(Error(GL_INVALID_VALUE)); context->handleError(Error(GL_INVALID_VALUE));
return false; return false;
} }
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); gl::Texture *texture =
context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
if (!texture) if (!texture)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
...@@ -263,7 +267,8 @@ bool ValidateES3TexImageParametersBase(Context *context, ...@@ -263,7 +267,8 @@ bool ValidateES3TexImageParametersBase(Context *context,
gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER); gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
if (pixelUnpackBuffer != nullptr) if (pixelUnpackBuffer != nullptr)
{ {
// ...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
// indicated by type. // indicated by type.
if (!isCompressed) if (!isCompressed)
{ {
...@@ -442,7 +447,8 @@ bool GetUnsizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat, ...@@ -442,7 +447,8 @@ bool GetUnsizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat,
outEffectiveFormat); outEffectiveFormat);
} }
static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat, const InternalFormat &destFormat, static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat,
const InternalFormat &destFormat,
GLenum *outEffectiveFormat) GLenum *outEffectiveFormat)
{ {
if (destFormat.pixelBytes > 0) if (destFormat.pixelBytes > 0)
...@@ -738,7 +744,7 @@ bool ValidateES3TexStorageParametersBase(Context *context, ...@@ -738,7 +744,7 @@ bool ValidateES3TexStorageParametersBase(Context *context,
switch (target) switch (target)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
{ {
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)
...@@ -749,7 +755,7 @@ bool ValidateES3TexStorageParametersBase(Context *context, ...@@ -749,7 +755,7 @@ bool ValidateES3TexStorageParametersBase(Context *context,
} }
break; break;
case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP:
{ {
if (width != height) if (width != height)
{ {
...@@ -765,7 +771,7 @@ bool ValidateES3TexStorageParametersBase(Context *context, ...@@ -765,7 +771,7 @@ bool ValidateES3TexStorageParametersBase(Context *context,
} }
break; break;
case GL_TEXTURE_3D: case GL_TEXTURE_3D:
{ {
if (static_cast<GLuint>(width) > caps.max3DTextureSize || if (static_cast<GLuint>(width) > caps.max3DTextureSize ||
static_cast<GLuint>(height) > caps.max3DTextureSize || static_cast<GLuint>(height) > caps.max3DTextureSize ||
...@@ -777,7 +783,7 @@ bool ValidateES3TexStorageParametersBase(Context *context, ...@@ -777,7 +783,7 @@ bool ValidateES3TexStorageParametersBase(Context *context,
} }
break; break;
case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_ARRAY:
{ {
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 ||
...@@ -789,9 +795,9 @@ bool ValidateES3TexStorageParametersBase(Context *context, ...@@ -789,9 +795,9 @@ bool ValidateES3TexStorageParametersBase(Context *context,
} }
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
return false; return false;
} }
gl::Texture *texture = context->getTargetTexture(target); gl::Texture *texture = context->getTargetTexture(target);
...@@ -903,8 +909,12 @@ bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint ...@@ -903,8 +909,12 @@ bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint
return ValidateGetQueryObjectValueBase(context, id, pname, nullptr); return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
} }
bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment, bool ValidateFramebufferTextureLayer(Context *context,
GLuint texture, GLint level, GLint layer) GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLint layer)
{ {
if (context->getClientMajorVersion() < 3) if (context->getClientMajorVersion() < 3)
{ {
...@@ -931,7 +941,7 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att ...@@ -931,7 +941,7 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att
switch (tex->getTarget()) switch (tex->getTarget())
{ {
case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_ARRAY:
{ {
if (level > gl::log2(caps.max2DTextureSize)) if (level > gl::log2(caps.max2DTextureSize))
{ {
...@@ -947,7 +957,7 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att ...@@ -947,7 +957,7 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att
} }
break; break;
case GL_TEXTURE_3D: case GL_TEXTURE_3D:
{ {
if (level > gl::log2(caps.max3DTextureSize)) if (level > gl::log2(caps.max3DTextureSize))
{ {
...@@ -963,9 +973,9 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att ...@@ -963,9 +973,9 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att
} }
break; break;
default: default:
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
const auto &format = tex->getFormat(tex->getTarget(), level); const auto &format = tex->getFormat(tex->getTarget(), level);
...@@ -979,17 +989,24 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att ...@@ -979,17 +989,24 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att
return true; return true;
} }
bool ValidateES3RenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples, bool ValidateES3RenderbufferStorageParameters(gl::Context *context,
GLenum internalformat, GLsizei width, GLsizei height) GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height)
{ {
if (!ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width, height)) if (!ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width,
height))
{ {
return false; return false;
} }
//The ES3 spec(section 4.4.2) states that the internal format must be sized and not an integer format if samples is greater than zero. // The ES3 spec(section 4.4.2) states that the internal format must be sized and not an integer
// format if samples is greater than zero.
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && samples > 0) if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) &&
samples > 0)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
...@@ -1008,7 +1025,9 @@ bool ValidateES3RenderbufferStorageParameters(gl::Context *context, GLenum targe ...@@ -1008,7 +1025,9 @@ bool ValidateES3RenderbufferStorageParameters(gl::Context *context, GLenum targe
return true; return true;
} }
bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numAttachments, bool ValidateInvalidateFramebuffer(Context *context,
GLenum target,
GLsizei numAttachments,
const GLenum *attachments) const GLenum *attachments)
{ {
if (context->getClientMajorVersion() < 3) if (context->getClientMajorVersion() < 3)
...@@ -1022,19 +1041,20 @@ bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numA ...@@ -1022,19 +1041,20 @@ bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numA
switch (target) switch (target)
{ {
case GL_DRAW_FRAMEBUFFER: case GL_DRAW_FRAMEBUFFER:
case GL_FRAMEBUFFER: case GL_FRAMEBUFFER:
defaultFramebuffer = context->getGLState().getDrawFramebuffer()->id() == 0; defaultFramebuffer = context->getGLState().getDrawFramebuffer()->id() == 0;
break; break;
case GL_READ_FRAMEBUFFER: case GL_READ_FRAMEBUFFER:
defaultFramebuffer = context->getGLState().getReadFramebuffer()->id() == 0; defaultFramebuffer = context->getGLState().getReadFramebuffer()->id() == 0;
break; break;
default: default:
context->handleError(Error(GL_INVALID_ENUM, "Invalid framebuffer target")); context->handleError(Error(GL_INVALID_ENUM, "Invalid framebuffer target"));
return false; return false;
} }
return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer); return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
defaultFramebuffer);
} }
bool ValidateClearBuffer(ValidationContext *context) bool ValidateClearBuffer(ValidationContext *context)
...@@ -1091,7 +1111,7 @@ bool ValidateDrawRangeElements(Context *context, ...@@ -1091,7 +1111,7 @@ bool ValidateDrawRangeElements(Context *context,
return true; return true;
} }
bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params) bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint *params)
{ {
if (context->getClientMajorVersion() < 3) if (context->getClientMajorVersion() < 3)
{ {
...@@ -1133,7 +1153,8 @@ bool ValidateReadBuffer(Context *context, GLenum src) ...@@ -1133,7 +1153,8 @@ bool ValidateReadBuffer(Context *context, GLenum src)
{ {
if (src != GL_BACK) if (src != GL_BACK)
{ {
const char *errorMsg = "'src' must be GL_NONE or GL_BACK when reading from the default framebuffer."; const char *errorMsg =
"'src' must be GL_NONE or GL_BACK when reading from the default framebuffer.";
context->handleError(gl::Error(GL_INVALID_OPERATION, errorMsg)); context->handleError(gl::Error(GL_INVALID_OPERATION, errorMsg));
return false; return false;
} }
......
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