summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/validationES.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/validationES.h')
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES.h1272
1 files changed, 1272 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/validationES.h b/gfx/angle/checkout/src/libANGLE/validationES.h
new file mode 100644
index 0000000000..685e1e505b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES.h
@@ -0,0 +1,1272 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// validationES.h: Validation functions for generic OpenGL ES entry point parameters
+
+#ifndef LIBANGLE_VALIDATION_ES_H_
+#define LIBANGLE_VALIDATION_ES_H_
+
+#include "common/PackedEnums.h"
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/VertexArray.h"
+
+#include <GLES2/gl2.h>
+#include <GLES3/gl3.h>
+#include <GLES3/gl31.h>
+
+namespace egl
+{
+class Display;
+class Image;
+} // namespace egl
+
+namespace gl
+{
+class Context;
+struct Format;
+class Framebuffer;
+struct LinkedUniform;
+class Program;
+class Shader;
+
+void SetRobustLengthParam(const GLsizei *length, GLsizei value);
+bool ValidTextureTarget(const Context *context, TextureType type);
+bool ValidTexture2DTarget(const Context *context, TextureType type);
+bool ValidTexture3DTarget(const Context *context, TextureType target);
+bool ValidTextureExternalTarget(const Context *context, TextureType target);
+bool ValidTextureExternalTarget(const Context *context, TextureTarget target);
+bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target);
+bool ValidTexture3DDestinationTarget(const Context *context, TextureTarget target);
+bool ValidTexLevelDestinationTarget(const Context *context, TextureType type);
+bool ValidFramebufferTarget(const Context *context, GLenum target);
+bool ValidMipLevel(const Context *context, TextureType type, GLint level);
+bool ValidImageSizeParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ bool isSubImage);
+bool ValidCompressedImageSize(const Context *context,
+ GLenum internalFormat,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+bool ValidCompressedSubImageSize(const Context *context,
+ GLenum internalFormat,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ size_t textureWidth,
+ size_t textureHeight,
+ size_t textureDepth);
+bool ValidImageDataSize(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType texType,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ GLsizei imageSize);
+
+bool ValidQueryType(const Context *context, QueryType queryType);
+
+bool ValidateWebGLVertexAttribPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexAttribType type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *ptr,
+ bool pureInteger);
+
+// Returns valid program if id is a valid program name
+// Errors INVALID_OPERATION if valid shader is given and returns NULL
+// Errors INVALID_VALUE otherwise and returns NULL
+Program *GetValidProgram(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id);
+
+// Returns valid shader if id is a valid shader name
+// Errors INVALID_OPERATION if valid program is given and returns NULL
+// Errors INVALID_VALUE otherwise and returns NULL
+Shader *GetValidShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id);
+
+bool ValidateAttachmentTarget(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum attachment);
+
+bool ValidateBlitFramebufferParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+
+bool ValidateBindFramebufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ FramebufferID framebuffer);
+bool ValidateBindRenderbufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ RenderbufferID renderbuffer);
+bool ValidateFramebufferParameteriBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLint param);
+bool ValidateFramebufferRenderbufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbuffer);
+bool ValidateFramebufferTextureBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level);
+bool ValidateGenerateMipmapBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target);
+
+bool ValidateRenderbufferStorageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+bool ValidatePixelPack(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum format,
+ GLenum type,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLsizei bufSize,
+ GLsizei *length,
+ const void *pixels);
+
+bool ValidateReadPixelsBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ const void *pixels);
+bool ValidateReadPixelsRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *columns,
+ const GLsizei *rows,
+ const void *pixels);
+bool ValidateReadnPixelsEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateReadnPixelsRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *columns,
+ const GLsizei *rows,
+ const void *data);
+
+bool ValidateGenQueriesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *ids);
+bool ValidateDeleteQueriesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *ids);
+bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID id);
+bool ValidateBeginQueryBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ QueryID id);
+bool ValidateBeginQueryEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ QueryID id);
+bool ValidateEndQueryBase(const Context *context, angle::EntryPoint entryPoint, QueryType target);
+bool ValidateEndQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryType target);
+bool ValidateQueryCounterEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ QueryType target);
+bool ValidateGetQueryivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ GLsizei *numParams);
+bool ValidateGetQueryivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetQueryivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetQueryObjectValueBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei *numParams);
+bool ValidateGetQueryObjectivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetQueryObjectivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetQueryObjectuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateGetQueryObjectuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateGetQueryObjecti64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLint64 *params);
+bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ GLint64 *params);
+bool ValidateGetQueryObjectui64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLuint64 *params);
+bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ GLuint64 *params);
+
+bool ValidateUniformCommonBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Program *program,
+ UniformLocation location,
+ GLsizei count,
+ const LinkedUniform **uniformOut);
+bool ValidateUniform1ivValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum uniformType,
+ GLsizei count,
+ const GLint *value);
+
+ANGLE_INLINE bool ValidateUniformValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ GLenum uniformType)
+{
+ // Check that the value type is compatible with uniform type.
+ // Do the cheaper test first, for a little extra speed.
+ if (valueType != uniformType && VariableBoolVectorType(valueType) != uniformType)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kUniformSizeMismatch);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateUniformMatrixValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ GLenum uniformType);
+bool ValidateUniform(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum uniformType,
+ UniformLocation location,
+ GLsizei count);
+bool ValidateUniformMatrix(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum matrixType,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose);
+bool ValidateGetBooleanvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLboolean *params);
+bool ValidateGetFloatvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateStateQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLenum *nativeType,
+ unsigned int *numParams);
+bool ValidateGetIntegervRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *data);
+bool ValidateGetInteger64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ GLint64 *data);
+bool ValidateRobustStateQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ GLenum *nativeType,
+ unsigned int *numParams);
+
+bool ValidateCopyImageSubDataBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+bool ValidateCopyTexImageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ Format *textureFormatOut);
+
+void RecordDrawModeError(const Context *context, angle::EntryPoint entryPoint, PrimitiveMode mode);
+const char *ValidateDrawElementsStates(const Context *context);
+
+ANGLE_INLINE bool ValidateDrawBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode)
+{
+ intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
+ if (drawStatesError)
+ {
+ const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
+
+ // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
+ // Incomplete.
+ bool isFramebufferIncomplete = strcmp(errorMessage, err::kDrawFramebufferIncomplete) == 0;
+ GLenum errorCode =
+ isFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION : GL_INVALID_OPERATION;
+ context->validationError(entryPoint, errorCode, errorMessage);
+ return false;
+ }
+
+ if (!context->getStateCache().isValidDrawMode(mode))
+ {
+ RecordDrawModeError(context, entryPoint, mode);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawArraysInstancedBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount);
+bool ValidateDrawArraysInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount);
+bool ValidateDrawArraysInstancedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount);
+
+bool ValidateDrawElementsInstancedBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount);
+bool ValidateDrawElementsInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount);
+bool ValidateDrawElementsInstancedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount);
+
+bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint);
+
+bool ValidateGetUniformBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location);
+bool ValidateSizedGetUniform(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLsizei *length);
+bool ValidateGetnUniformfvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLfloat *params);
+bool ValidateGetnUniformfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetnUniformivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLint *params);
+bool ValidateGetnUniformivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetnUniformuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateGetUniformfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetUniformivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetUniformuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+
+bool ValidateDiscardFramebufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ bool defaultFramebuffer);
+
+bool ValidateInsertEventMarkerEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei length,
+ const char *marker);
+bool ValidatePushGroupMarkerEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei length,
+ const char *marker);
+bool ValidateEGLImageObject(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType type,
+ GLeglImageOES image);
+bool ValidateEGLImageTargetTexture2DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType type,
+ GLeglImageOES image);
+bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLeglImageOES image);
+
+bool ValidateProgramBinaryBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length);
+bool ValidateGetProgramBinaryBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLenum *binaryFormat,
+ const void *binary);
+
+bool ValidateDrawBuffersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLenum *bufs);
+
+bool ValidateGetBufferPointervBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ GLsizei *length,
+ void *const *params);
+bool ValidateUnmapBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target);
+bool ValidateMapBufferRangeBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access);
+bool ValidateFlushMappedBufferRangeBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length);
+
+bool ValidateGenOrDelete(const Context *context, angle::EntryPoint entryPoint, GLint n);
+
+bool ValidateRobustEntryPoint(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei bufSize);
+bool ValidateRobustBufferSize(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei bufSize,
+ GLsizei numParams);
+
+bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei *numParams);
+
+bool ValidateGetFramebufferParameterivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params);
+
+bool ValidateGetBufferParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ bool pointerVersion,
+ GLsizei *numParams);
+
+bool ValidateGetProgramivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum pname,
+ GLsizei *numParams);
+
+bool ValidateGetRenderbufferParameterivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLsizei *length);
+
+bool ValidateGetShaderivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader,
+ GLenum pname,
+ GLsizei *length);
+
+bool ValidateGetTexParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei *length);
+
+template <typename ParamType>
+bool ValidateTexParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ bool vectorParams,
+ const ParamType *params);
+
+bool ValidateGetVertexAttribBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei *length,
+ bool pointer,
+ bool pureIntegerEntryPoint);
+
+ANGLE_INLINE bool ValidateVertexFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribTypeCase validation)
+{
+ const Caps &caps = context->getCaps();
+ if (index >= static_cast<GLuint>(caps.maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ err::kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ switch (validation)
+ {
+ case VertexAttribTypeCase::Invalid:
+ context->validationError(entryPoint, GL_INVALID_ENUM, err::kInvalidType);
+ return false;
+ case VertexAttribTypeCase::Valid:
+ if (size < 1 || size > 4)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kInvalidVertexAttrSize);
+ return false;
+ }
+ break;
+ case VertexAttribTypeCase::ValidSize4Only:
+ if (size != 4)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kInvalidVertexAttribSize2101010);
+ return false;
+ }
+ break;
+ case VertexAttribTypeCase::ValidSize3or4:
+ if (size != 3 && size != 4)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kInvalidVertexAttribSize1010102);
+ return false;
+ }
+ break;
+ }
+
+ return true;
+}
+
+// Note: These byte, short, and int types are all converted to float for the shader.
+ANGLE_INLINE bool ValidateFloatVertexFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribType type)
+{
+ return ValidateVertexFormat(context, entryPoint, index, size,
+ context->getStateCache().getVertexAttribTypeValidation(type));
+}
+
+ANGLE_INLINE bool ValidateIntegerVertexFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribType type)
+{
+ return ValidateVertexFormat(
+ context, entryPoint, index, size,
+ context->getStateCache().getIntegerVertexAttribTypeValidation(type));
+}
+
+bool ValidateWebGLFramebufferAttachmentClearType(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint drawbuffer,
+ const GLenum *validComponentTypes,
+ size_t validComponentTypeCount);
+
+bool ValidateRobustCompressedTexImageBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei imageSize,
+ GLsizei dataSize);
+
+bool ValidateVertexAttribIndex(const Context *context, angle::EntryPoint entryPoint, GLuint index);
+
+bool ValidateGetActiveUniformBlockivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ GLsizei *length);
+
+bool ValidateGetSamplerParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei *length);
+
+template <typename ParamType>
+bool ValidateSamplerParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ bool vectorParams,
+ const ParamType *params);
+
+bool ValidateGetInternalFormativBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *numParams);
+
+bool ValidateFramebufferNotMultisampled(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Framebuffer *framebuffer,
+ bool checkReadBufferResourceSamples);
+
+bool ValidateMultitextureUnit(const Context *context, angle::EntryPoint entryPoint, GLenum texture);
+
+bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode transformFeedbackPrimitiveMode,
+ PrimitiveMode renderPrimitiveMode);
+
+// Common validation for 2D and 3D variants of TexStorage*Multisample.
+bool ValidateTexStorageMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height);
+
+bool ValidateTexStorage2DMultisampleBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height);
+
+bool ValidateGetTexLevelParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLsizei *length);
+
+bool ValidateMapBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target);
+bool ValidateIndexedStateQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ GLsizei *length);
+bool ValidateES3TexImage2DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isCompressed,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei imageSize,
+ const void *pixels);
+bool ValidateES3CopyTexImage2DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border);
+bool ValidateES3TexStorageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+bool ValidateES3TexStorage2DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+bool ValidateES3TexStorage3DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+
+bool ValidateGetMultisamplefvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ const GLfloat *val);
+bool ValidateSampleMaskiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint maskNumber,
+ GLbitfield mask);
+
+bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
+ const ProgramExecutable *programExecutable);
+
+// We should check with Khronos if returning INVALID_FRAMEBUFFER_OPERATION is OK when querying
+// implementation format info for incomplete framebuffers. It seems like these queries are
+// incongruent with the other errors.
+// Inlined for speed.
+template <GLenum ErrorCode = GL_INVALID_FRAMEBUFFER_OPERATION>
+ANGLE_INLINE bool ValidateFramebufferComplete(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Framebuffer *framebuffer)
+{
+ const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
+ if (!framebufferStatus.isComplete())
+ {
+ ASSERT(framebufferStatus.reason != nullptr);
+ context->validationError(entryPoint, ErrorCode, framebufferStatus.reason);
+ return false;
+ }
+
+ return true;
+}
+
+const char *ValidateProgramPipelineDrawStates(const State &state,
+ const Extensions &extensions,
+ ProgramPipeline *programPipeline);
+const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline);
+const char *ValidateDrawStates(const Context *context);
+const char *ValidateProgramPipeline(const Context *context);
+
+void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint);
+
+ANGLE_INLINE bool ValidateDrawAttribs(const Context *context,
+ angle::EntryPoint entryPoint,
+ int64_t maxVertex)
+{
+ if (maxVertex > context->getStateCache().getNonInstancedVertexElementLimit())
+ {
+ RecordDrawAttribsError(context, entryPoint);
+ return false;
+ }
+
+ return true;
+}
+
+ANGLE_INLINE bool ValidateDrawArraysAttribs(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint first,
+ GLsizei count)
+{
+ if (!context->isBufferAccessValidationEnabled())
+ {
+ return true;
+ }
+
+ // Check the computation of maxVertex doesn't overflow.
+ // - first < 0 has been checked as an error condition.
+ // - if count <= 0, skip validating no-op draw calls.
+ // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
+ ASSERT(first >= 0);
+ ASSERT(count > 0);
+ int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
+ if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow);
+ return false;
+ }
+
+ return ValidateDrawAttribs(context, entryPoint, maxVertex);
+}
+
+ANGLE_INLINE bool ValidateDrawInstancedAttribs(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint primcount)
+{
+ if (!context->isBufferAccessValidationEnabled())
+ {
+ return true;
+ }
+
+ if ((primcount - 1) > context->getStateCache().getInstancedVertexElementLimit())
+ {
+ RecordDrawAttribsError(context, entryPoint);
+ return false;
+ }
+
+ return true;
+}
+
+ANGLE_INLINE bool ValidateDrawArraysCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount)
+{
+ if (first < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeStart);
+ return false;
+ }
+
+ if (count <= 0)
+ {
+ if (count < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
+ return false;
+ }
+
+ // Early exit.
+ return ValidateDrawBase(context, entryPoint, mode);
+ }
+
+ if (primcount <= 0)
+ {
+ if (primcount < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
+ return false;
+ }
+ // Early exit.
+ return ValidateDrawBase(context, entryPoint, mode);
+ }
+
+ if (!ValidateDrawBase(context, entryPoint, mode))
+ {
+ return false;
+ }
+
+ if (context->getStateCache().isTransformFeedbackActiveUnpaused() &&
+ !context->supportsGeometryOrTesselation())
+ {
+ const State &state = context->getState();
+ TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+ if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kTransformFeedbackBufferTooSmall);
+ return false;
+ }
+ }
+
+ return ValidateDrawArraysAttribs(context, entryPoint, first, count);
+}
+
+ANGLE_INLINE bool ValidateDrawElementsBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ DrawElementsType type)
+{
+ if (!context->getStateCache().isValidDrawElementsType(type))
+ {
+ if (type == DrawElementsType::UnsignedInt)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, err::kTypeNotUnsignedShortByte);
+ return false;
+ }
+
+ ASSERT(type == DrawElementsType::InvalidEnum);
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, err::kEnumInvalid);
+ return false;
+ }
+
+ intptr_t drawElementsError = context->getStateCache().getBasicDrawElementsError(context);
+ if (drawElementsError)
+ {
+ // All errors from ValidateDrawElementsStates return INVALID_OPERATION.
+ const char *errorMessage = reinterpret_cast<const char *>(drawElementsError);
+ context->validationError(entryPoint, GL_INVALID_OPERATION, errorMessage);
+ return false;
+ }
+
+ // Note that we are missing overflow checks for active transform feedback buffers.
+ return true;
+}
+
+ANGLE_INLINE bool ValidateDrawElementsCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount)
+{
+ if (!ValidateDrawElementsBase(context, entryPoint, mode, type))
+ {
+ return false;
+ }
+
+ ASSERT(isPow2(GetDrawElementsTypeSize(type)) && GetDrawElementsTypeSize(type) > 0);
+
+ if (context->isWebGL())
+ {
+ GLuint typeBytes = GetDrawElementsTypeSize(type);
+
+ if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
+ {
+ // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
+ // The offset arguments to drawElements and [...], must be a multiple of the size of the
+ // data type passed to the call, or an INVALID_OPERATION error is generated.
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kOffsetMustBeMultipleOfType);
+ return false;
+ }
+
+ // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
+ // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
+ // error is generated.
+ if (reinterpret_cast<intptr_t>(indices) < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeOffset);
+ return false;
+ }
+ }
+
+ if (count <= 0)
+ {
+ if (count < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
+ return false;
+ }
+
+ // Early exit.
+ return ValidateDrawBase(context, entryPoint, mode);
+ }
+
+ if (!ValidateDrawBase(context, entryPoint, mode))
+ {
+ return false;
+ }
+
+ const State &state = context->getState();
+ const VertexArray *vao = state.getVertexArray();
+ Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+
+ if (!elementArrayBuffer)
+ {
+ if (!indices)
+ {
+ // This is an application error that would normally result in a crash, but we catch
+ // it and return an error
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kElementArrayNoBufferOrPointer);
+ return false;
+ }
+ }
+ else
+ {
+ // The max possible type size is 8 and count is on 32 bits so doing the multiplication
+ // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
+ static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
+ constexpr uint64_t kMaxTypeSize = 8;
+ constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
+ constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
+ static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
+
+ uint64_t elementCount = static_cast<uint64_t>(count);
+ ASSERT(elementCount > 0 && GetDrawElementsTypeSize(type) <= kMaxTypeSize);
+
+ // Doing the multiplication here is overflow-safe
+ uint64_t elementDataSizeNoOffset = elementCount << GetDrawElementsTypeShift(type);
+
+ // The offset can be any value, check for overflows
+ uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
+ uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
+ if (elementDataSizeWithOffset < elementDataSizeNoOffset)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow);
+ return false;
+ }
+
+ // Related to possible test bug: https://github.com/KhronosGroup/WebGL/issues/3064
+ if ((elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize())) &&
+ (primcount > 0))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kInsufficientBufferSize);
+ return false;
+ }
+ }
+
+ if (context->isBufferAccessValidationEnabled() && primcount > 0)
+ {
+ // Use the parameter buffer to retrieve and cache the index range.
+ IndexRange indexRange{IndexRange::Undefined()};
+ ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
+
+ // If we use an index greater than our maximum supported index range, return an error.
+ // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should
+ // always return an error if possible here.
+ if (static_cast<GLint64>(indexRange.end) >= context->getCaps().maxElementIndex)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kExceedsMaxElement);
+ return false;
+ }
+
+ if (!ValidateDrawAttribs(context, entryPoint, static_cast<GLint>(indexRange.end)))
+ {
+ return false;
+ }
+
+ // No op if there are no real indices in the index data (all are primitive restart).
+ return (indexRange.vertexIndexCount > 0);
+ }
+
+ return true;
+}
+
+ANGLE_INLINE bool ValidateBindVertexArrayBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID array)
+{
+ if (!context->isVertexArrayGenerated(array))
+ {
+ // The default VAO should always exist
+ ASSERT(array.value != 0);
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kInvalidVertexArray);
+ return false;
+ }
+
+ return true;
+}
+
+ANGLE_INLINE bool ValidateVertexAttribIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index)
+{
+ if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ err::kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLogicOpCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ LogicalOperation opcodePacked);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES_H_