| // |
| // Copyright 2018 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. |
| // |
| // validationES2.h: |
| // Inlined validation functions for OpenGL ES 2.0 entry points. |
| |
| #ifndef LIBANGLE_VALIDATION_ES2_H_ |
| #define LIBANGLE_VALIDATION_ES2_H_ |
| |
| #include "libANGLE/ErrorStrings.h" |
| #include "libANGLE/validationES.h" |
| #include "libANGLE/validationES2_autogen.h" |
| |
| namespace gl |
| { |
| ANGLE_INLINE bool ValidateDrawArrays(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode mode, |
| GLint first, |
| GLsizei count) |
| { |
| return ValidateDrawArraysCommon(context, entryPoint, mode, first, count, 1); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform1f(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLfloat x) |
| { |
| return ValidateUniform(context, entryPoint, GL_FLOAT, location, 1); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform1fv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| const GLfloat *v) |
| { |
| return ValidateUniform(context, entryPoint, GL_FLOAT, location, count); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform1i(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLint x) |
| { |
| return ValidateUniform1iv(context, entryPoint, location, 1, &x); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform2f(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLfloat x, |
| GLfloat y) |
| { |
| return ValidateUniform(context, entryPoint, GL_FLOAT_VEC2, location, 1); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform2fv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| const GLfloat *v) |
| { |
| return ValidateUniform(context, entryPoint, GL_FLOAT_VEC2, location, count); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform2i(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLint x, |
| GLint y) |
| { |
| return ValidateUniform(context, entryPoint, GL_INT_VEC2, location, 1); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform2iv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| const GLint *v) |
| { |
| return ValidateUniform(context, entryPoint, GL_INT_VEC2, location, count); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform3f(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLfloat x, |
| GLfloat y, |
| GLfloat z) |
| { |
| return ValidateUniform(context, entryPoint, GL_FLOAT_VEC3, location, 1); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform3fv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| const GLfloat *v) |
| { |
| return ValidateUniform(context, entryPoint, GL_FLOAT_VEC3, location, count); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform3i(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLint x, |
| GLint y, |
| GLint z) |
| { |
| return ValidateUniform(context, entryPoint, GL_INT_VEC3, location, 1); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform3iv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| const GLint *v) |
| { |
| return ValidateUniform(context, entryPoint, GL_INT_VEC3, location, count); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform4f(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLfloat x, |
| GLfloat y, |
| GLfloat z, |
| GLfloat w) |
| { |
| return ValidateUniform(context, entryPoint, GL_FLOAT_VEC4, location, 1); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform4fv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| const GLfloat *v) |
| { |
| return ValidateUniform(context, entryPoint, GL_FLOAT_VEC4, location, count); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform4i(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLint x, |
| GLint y, |
| GLint z, |
| GLint w) |
| { |
| return ValidateUniform(context, entryPoint, GL_INT_VEC4, location, 1); |
| } |
| |
| ANGLE_INLINE bool ValidateUniform4iv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| const GLint *v) |
| { |
| return ValidateUniform(context, entryPoint, GL_INT_VEC4, location, count); |
| } |
| |
| ANGLE_INLINE bool ValidateUniformMatrix2fv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT2, location, count, transpose); |
| } |
| |
| ANGLE_INLINE bool ValidateUniformMatrix3fv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT3, location, count, transpose); |
| } |
| |
| ANGLE_INLINE bool ValidateUniformMatrix4fv(const Context *context, |
| angle::EntryPoint entryPoint, |
| UniformLocation location, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT4, location, count, transpose); |
| } |
| |
| ANGLE_INLINE bool ValidateVertexAttrib1f(const PrivateState &state, |
| ErrorSet *errors, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLfloat x) |
| { |
| return ValidateVertexAttribIndex(state, errors, entryPoint, index); |
| } |
| |
| ANGLE_INLINE bool ValidateVertexAttrib1fv(const PrivateState &state, |
| ErrorSet *errors, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| const GLfloat *values) |
| { |
| if (values == nullptr) |
| { |
| errors->validationError(entryPoint, GL_INVALID_VALUE, err::kVertexAttributeValueNULL); |
| return false; |
| } |
| |
| return ValidateVertexAttribIndex(state, errors, entryPoint, index); |
| } |
| |
| ANGLE_INLINE bool ValidateVertexAttrib2f(const PrivateState &state, |
| ErrorSet *errors, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLfloat x, |
| GLfloat y) |
| { |
| return ValidateVertexAttribIndex(state, errors, entryPoint, index); |
| } |
| |
| ANGLE_INLINE bool ValidateVertexAttrib2fv(const PrivateState &state, |
| ErrorSet *errors, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| const GLfloat *values) |
| { |
| if (values == nullptr) |
| { |
| errors->validationError(entryPoint, GL_INVALID_VALUE, err::kVertexAttributeValueNULL); |
| return false; |
| } |
| |
| return ValidateVertexAttribIndex(state, errors, entryPoint, index); |
| } |
| |
| ANGLE_INLINE bool ValidateVertexAttrib3f(const PrivateState &state, |
| ErrorSet *errors, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLfloat x, |
| GLfloat y, |
| GLfloat z) |
| { |
| return ValidateVertexAttribIndex(state, errors, entryPoint, index); |
| } |
| |
| ANGLE_INLINE bool ValidateVertexAttrib3fv(const PrivateState &state, |
| ErrorSet *errors, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| const GLfloat *values) |
| { |
| if (values == nullptr) |
| { |
| errors->validationError(entryPoint, GL_INVALID_VALUE, err::kVertexAttributeValueNULL); |
| return false; |
| } |
| |
| return ValidateVertexAttribIndex(state, errors, entryPoint, index); |
| } |
| |
| ANGLE_INLINE bool ValidateVertexAttrib4f(const PrivateState &state, |
| ErrorSet *errors, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLfloat x, |
| GLfloat y, |
| GLfloat z, |
| GLfloat w) |
| { |
| return ValidateVertexAttribIndex(state, errors, entryPoint, index); |
| } |
| |
| ANGLE_INLINE bool ValidateVertexAttrib4fv(const PrivateState &state, |
| ErrorSet *errors, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| const GLfloat *values) |
| { |
| if (values == nullptr) |
| { |
| errors->validationError(entryPoint, GL_INVALID_VALUE, err::kVertexAttributeValueNULL); |
| return false; |
| } |
| |
| return ValidateVertexAttribIndex(state, errors, entryPoint, index); |
| } |
| |
| ANGLE_INLINE bool ValidateGenBuffers(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLint n, |
| const BufferID *buffers) |
| { |
| return ValidateGenOrDelete(context, entryPoint, n, buffers); |
| } |
| |
| ANGLE_INLINE bool ValidateGenFramebuffers(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLint n, |
| const FramebufferID *framebuffers) |
| { |
| return ValidateGenOrDelete(context, entryPoint, n, framebuffers); |
| } |
| |
| ANGLE_INLINE bool ValidateGenRenderbuffers(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLint n, |
| const RenderbufferID *renderbuffers) |
| { |
| return ValidateGenOrDelete(context, entryPoint, n, renderbuffers); |
| } |
| |
| ANGLE_INLINE bool ValidateGenTextures(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLint n, |
| const TextureID *textures) |
| { |
| return ValidateGenOrDelete(context, entryPoint, n, textures); |
| } |
| |
| ANGLE_INLINE bool ValidateGenerateMipmap(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target) |
| { |
| return ValidateGenerateMipmapBase(context, entryPoint, target); |
| } |
| |
| ANGLE_INLINE bool ValidateGetBufferParameteriv(const Context *context, |
| angle::EntryPoint entryPoint, |
| BufferBinding target, |
| GLenum pname, |
| const GLint *params) |
| { |
| return ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, nullptr); |
| } |
| |
| ANGLE_INLINE bool ValidateGetRenderbufferParameteriv(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLenum pname, |
| const GLint *params) |
| { |
| return ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, nullptr); |
| } |
| |
| ANGLE_INLINE bool ValidateGetShaderiv(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID shader, |
| GLenum pname, |
| const GLint *params) |
| { |
| if (params == nullptr) |
| { |
| ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kPLSParamsNULL); |
| return false; |
| } |
| |
| return ValidateGetShaderivBase(context, entryPoint, shader, pname, nullptr); |
| } |
| |
| ANGLE_INLINE bool ValidateGetTexParameterfv(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLenum pname, |
| const GLfloat *params) |
| { |
| return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr); |
| } |
| |
| ANGLE_INLINE bool ValidateGetTexParameteriv(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLenum pname, |
| const GLint *params) |
| { |
| return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr); |
| } |
| |
| ANGLE_INLINE bool ValidateGetUniformfv(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID program, |
| UniformLocation location, |
| const GLfloat *params) |
| { |
| return ValidateGetUniformBase(context, entryPoint, program, location); |
| } |
| |
| ANGLE_INLINE bool ValidateGetUniformiv(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID program, |
| UniformLocation location, |
| const GLint *params) |
| { |
| return ValidateGetUniformBase(context, entryPoint, program, location); |
| } |
| |
| ANGLE_INLINE bool ValidateGetVertexAttribfv(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLenum pname, |
| const GLfloat *params) |
| { |
| return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, false); |
| } |
| |
| ANGLE_INLINE bool ValidateGetVertexAttribiv(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLenum pname, |
| const GLint *params) |
| { |
| return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, false); |
| } |
| |
| ANGLE_INLINE bool ValidateGetVertexAttribPointerv(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLenum pname, |
| void *const *pointer) |
| { |
| return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, true, false); |
| } |
| |
| ANGLE_INLINE bool ValidateReadPixels(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLint x, |
| GLint y, |
| GLsizei width, |
| GLsizei height, |
| GLenum format, |
| GLenum type, |
| const void *pixels) |
| { |
| return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, -1, |
| nullptr, nullptr, nullptr, pixels); |
| } |
| |
| ANGLE_INLINE bool ValidateTexParameterf(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLenum pname, |
| GLfloat param) |
| { |
| return ValidateTexParameterBase(context, entryPoint, target, pname, -1, false, ¶m); |
| } |
| |
| ANGLE_INLINE bool ValidateTexParameterfv(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLenum pname, |
| const GLfloat *params) |
| { |
| return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params); |
| } |
| |
| ANGLE_INLINE bool ValidateTexParameteri(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLenum pname, |
| GLint param) |
| { |
| return ValidateTexParameterBase(context, entryPoint, target, pname, -1, false, ¶m); |
| } |
| |
| ANGLE_INLINE bool ValidateTexParameteriv(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLenum pname, |
| const GLint *params) |
| { |
| return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params); |
| } |
| |
| ANGLE_INLINE bool ValidateBindBuffer(const Context *context, |
| angle::EntryPoint entryPoint, |
| BufferBinding target, |
| BufferID buffer) |
| { |
| if (!context->isValidBufferBinding(target)) |
| { |
| ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, err::kInvalidBufferTypes); |
| return false; |
| } |
| |
| if (!context->getState().isBindGeneratesResourceEnabled() && |
| !context->isBufferGenerated(buffer)) |
| { |
| ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kObjectNotGenerated); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| ANGLE_INLINE bool ValidateDrawElements(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode mode, |
| GLsizei count, |
| DrawElementsType type, |
| const void *indices) |
| { |
| return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1); |
| } |
| |
| ANGLE_INLINE bool ValidateVertexAttribPointer(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLint size, |
| VertexAttribType type, |
| GLboolean normalized, |
| GLsizei stride, |
| const void *ptr) |
| { |
| if (!ValidateFloatVertexFormat(context, entryPoint, index, size, type)) |
| { |
| return false; |
| } |
| |
| if (stride < 0) |
| { |
| ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeStride); |
| return false; |
| } |
| |
| if (context->getClientVersion() >= ES_3_1) |
| { |
| const Caps &caps = context->getCaps(); |
| if (stride > caps.maxVertexAttribStride) |
| { |
| ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kExceedsMaxVertexAttribStride); |
| return false; |
| } |
| |
| if (index >= static_cast<GLuint>(caps.maxVertexAttribBindings)) |
| { |
| ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kExceedsMaxVertexAttribBindings); |
| return false; |
| } |
| } |
| |
| // [OpenGL ES 3.0.2] Section 2.8 page 24: |
| // An INVALID_OPERATION error is generated when a non-zero vertex array object |
| // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, |
| // and the pointer argument is not NULL. |
| bool nullBufferAllowed = context->getState().areClientArraysEnabled() && |
| context->getState().getVertexArray()->id().value == 0; |
| if (!nullBufferAllowed && context->getState().getTargetBuffer(BufferBinding::Array) == 0 && |
| ptr != nullptr) |
| { |
| ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kClientDataInVertexArray); |
| return false; |
| } |
| |
| if (context->isWebGL()) |
| { |
| // WebGL 1.0 [Section 6.14] Fixed point support |
| // The WebGL API does not support the GL_FIXED data type. |
| if (type == VertexAttribType::Fixed) |
| { |
| ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, err::kFixedNotInWebGL); |
| return false; |
| } |
| |
| if (!ValidateWebGLVertexAttribPointer(context, entryPoint, type, normalized, stride, ptr, |
| false)) |
| { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| void RecordBindTextureTypeError(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target); |
| |
| ANGLE_INLINE bool ValidateBindTexture(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| TextureID texture) |
| { |
| if (!context->getStateCache().isValidBindTextureType(target)) |
| { |
| RecordBindTextureTypeError(context, entryPoint, target); |
| return false; |
| } |
| |
| if (texture.value == 0) |
| { |
| return true; |
| } |
| |
| Texture *textureObject = context->getTexture(texture); |
| if (textureObject && textureObject->getType() != target) |
| { |
| ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, err::kTextureTargetMismatchWithLabel, |
| static_cast<uint8_t>(target), |
| static_cast<uint8_t>(textureObject->getType()), |
| textureObject->getLabel().c_str()); |
| return false; |
| } |
| |
| if (!context->getState().isBindGeneratesResourceEnabled() && |
| !context->isTextureGenerated(texture)) |
| { |
| ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kObjectNotGenerated); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| // Validation of all Tex[Sub]Image2D parameters except TextureTarget. |
| bool ValidateES2TexImageParametersBase(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureTarget target, |
| GLint level, |
| GLenum internalformat, |
| bool isCompressed, |
| bool isSubImage, |
| GLint xoffset, |
| GLint yoffset, |
| GLsizei width, |
| GLsizei height, |
| GLint border, |
| GLenum format, |
| GLenum type, |
| GLsizei imageSize, |
| const void *pixels); |
| |
| // Validation of TexStorage*2DEXT |
| bool ValidateES2TexStorageParametersBase(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLsizei levels, |
| GLenum internalformat, |
| GLsizei width, |
| GLsizei height); |
| |
| // Validation of [Push,Pop]DebugGroup |
| bool ValidatePushDebugGroupBase(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum source, |
| GLuint id, |
| GLsizei length, |
| const GLchar *message); |
| bool ValidatePopDebugGroupBase(const Context *context, angle::EntryPoint entryPoint); |
| |
| bool ValidateDebugMessageControlBase(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum source, |
| GLenum type, |
| GLenum severity, |
| GLsizei count, |
| const GLuint *ids); |
| |
| bool ValidateDebugMessageInsertBase(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum source, |
| GLenum type, |
| GLuint id, |
| GLenum severity, |
| GLsizei length, |
| const GLchar *buf); |
| |
| // Validation of ObjectLabel |
| bool ValidateObjectLabelBase(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum identifier, |
| GLuint name, |
| GLsizei length, |
| const GLchar *label); |
| |
| // Validation of GetObjectLabel |
| bool ValidateGetObjectLabelBase(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum identifier, |
| GLuint name, |
| GLsizei bufSize, |
| const GLsizei *length, |
| const GLchar *label); |
| |
| // Validation of ObjectPtrLabel |
| bool ValidateObjectPtrLabelBase(const Context *context, |
| angle::EntryPoint entryPoint, |
| const void *ptr, |
| GLsizei length, |
| const GLchar *label); |
| |
| // Validation of GetObjectPtrLabel |
| bool ValidateGetObjectPtrLabelBase(const Context *context, |
| angle::EntryPoint entryPoint, |
| const void *ptr, |
| GLsizei bufSize, |
| const GLsizei *length, |
| const GLchar *label); |
| |
| } // namespace gl |
| |
| #endif // LIBANGLE_VALIDATION_ES2_H_ |