| // |
| // Copyright 2019 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. |
| // |
| // validationESEXT.cpp: Validation functions for OpenGL ES extension entry points. |
| |
| #include "libANGLE/validationESEXT_autogen.h" |
| |
| #include "libANGLE/Context.h" |
| #include "libANGLE/ErrorStrings.h" |
| #include "libANGLE/MemoryObject.h" |
| #include "libANGLE/validationES.h" |
| #include "libANGLE/validationES2.h" |
| #include "libANGLE/validationES3.h" |
| #include "libANGLE/validationES31.h" |
| #include "libANGLE/validationES32.h" |
| |
| namespace gl |
| { |
| using namespace err; |
| |
| namespace |
| { |
| template <typename ObjectT> |
| bool ValidateGetImageFormatAndType(const Context *context, |
| angle::EntryPoint entryPoint, |
| ObjectT *obj, |
| GLenum format, |
| GLenum type) |
| { |
| GLenum implFormat = obj->getImplementationColorReadFormat(context); |
| if (!ValidES3Format(format) && (format != implFormat || format == GL_NONE)) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat); |
| return false; |
| } |
| |
| GLenum implType = obj->getImplementationColorReadType(context); |
| if (!ValidES3Type(type) && (type != implType || type == GL_NONE)) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); |
| return false; |
| } |
| |
| // Format/type combinations are not yet validated. |
| |
| return true; |
| } |
| |
| bool IsValidImageLayout(ImageLayout layout) |
| { |
| switch (layout) |
| { |
| case ImageLayout::Undefined: |
| case ImageLayout::General: |
| case ImageLayout::ColorAttachment: |
| case ImageLayout::DepthStencilAttachment: |
| case ImageLayout::DepthStencilReadOnlyAttachment: |
| case ImageLayout::ShaderReadOnly: |
| case ImageLayout::TransferSrc: |
| case ImageLayout::TransferDst: |
| case ImageLayout::DepthReadOnlyStencilAttachment: |
| case ImageLayout::DepthAttachmentStencilReadOnly: |
| return true; |
| |
| default: |
| return false; |
| } |
| } |
| |
| bool IsValidMemoryObjectParamater(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum pname) |
| { |
| switch (pname) |
| { |
| case GL_DEDICATED_MEMORY_OBJECT_EXT: |
| return true; |
| |
| case GL_PROTECTED_MEMORY_OBJECT_EXT: |
| if (!context->getExtensions().protectedTexturesEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| return true; |
| |
| default: |
| return false; |
| } |
| } |
| |
| bool ValidateObjectIdentifierAndName(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum identifier, |
| GLuint name) |
| { |
| bool isGLES11 = context->getClientVersion() == Version(1, 1); |
| bool isGLES3 = context->getClientMajorVersion() >= 3; |
| bool isGLES31 = context->getClientVersion() >= Version(3, 1); |
| switch (identifier) |
| { |
| case GL_BUFFER_OBJECT_EXT: |
| if (context->getBuffer({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName); |
| return false; |
| } |
| return true; |
| |
| case GL_SHADER_OBJECT_EXT: |
| if (isGLES11) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); |
| return false; |
| } |
| if (context->getShader({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShaderName); |
| return false; |
| } |
| return true; |
| |
| case GL_PROGRAM_OBJECT_EXT: |
| if (isGLES11) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); |
| return false; |
| } |
| if (context->getProgramNoResolveLink({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidProgramName); |
| return false; |
| } |
| return true; |
| |
| case GL_VERTEX_ARRAY_OBJECT_EXT: |
| if (!isGLES3 && !context->getExtensions().vertexArrayObjectOES) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); |
| return false; |
| } |
| if (context->getVertexArray({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidVertexArrayName); |
| return false; |
| } |
| return true; |
| |
| case GL_QUERY_OBJECT_EXT: |
| if (!isGLES3 && !context->getExtensions().occlusionQueryBooleanEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); |
| return false; |
| } |
| if (context->getQuery({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryName); |
| return false; |
| } |
| return true; |
| |
| case GL_TRANSFORM_FEEDBACK: |
| if (!isGLES3) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); |
| return false; |
| } |
| if (context->getTransformFeedback({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, |
| kInvalidTransformFeedbackName); |
| return false; |
| } |
| return true; |
| |
| case GL_SAMPLER: |
| if (!isGLES3) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); |
| return false; |
| } |
| if (context->getSampler({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSamplerName); |
| return false; |
| } |
| return true; |
| |
| case GL_TEXTURE: |
| if (context->getTexture({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); |
| return false; |
| } |
| return true; |
| |
| case GL_RENDERBUFFER: |
| if (!context->isRenderbuffer({name})) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, |
| kInvalidRenderbufferName); |
| return false; |
| } |
| return true; |
| |
| case GL_FRAMEBUFFER: |
| if (context->getFramebuffer({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFramebufferName); |
| return false; |
| } |
| return true; |
| |
| case GL_PROGRAM_PIPELINE_OBJECT_EXT: |
| if (!isGLES31 && !context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType); |
| return false; |
| } |
| if (context->getProgramPipeline({name}) == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, |
| kInvalidProgramPipelineName); |
| return false; |
| } |
| return true; |
| |
| default: |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidIndentifier); |
| return false; |
| } |
| } |
| } // namespace |
| |
| bool ValidateGetTexImageANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureTarget target, |
| GLint level, |
| GLenum format, |
| GLenum type, |
| const void *pixels) |
| { |
| if (!context->getExtensions().getImageANGLE) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageExtensionNotEnabled); |
| return false; |
| } |
| |
| if (!ValidTexture2DDestinationTarget(context, target) && |
| !ValidTexture3DDestinationTarget(context, target)) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget); |
| return false; |
| } |
| |
| if (level < 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel); |
| return false; |
| } |
| |
| TextureType textureType = TextureTargetToType(target); |
| if (!ValidMipLevel(context, textureType, level)) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); |
| return false; |
| } |
| |
| Texture *texture = context->getTextureByTarget(target); |
| |
| if (!ValidateGetImageFormatAndType(context, entryPoint, texture, format, type)) |
| { |
| return false; |
| } |
| |
| GLsizei width = static_cast<GLsizei>(texture->getWidth(target, level)); |
| GLsizei height = static_cast<GLsizei>(texture->getHeight(target, level)); |
| if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr, |
| pixels)) |
| { |
| return false; |
| } |
| |
| if (texture->getFormat(target, level).info->compressed) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageCompressed); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateGetCompressedTexImageANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureTarget target, |
| GLint level, |
| const void *pixels) |
| { |
| if (!context->getExtensions().getImageANGLE) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageExtensionNotEnabled); |
| return false; |
| } |
| |
| // TODO: Validate all the things. http://anglebug.com/6177 |
| return false; |
| } |
| |
| bool ValidateGetRenderbufferImageANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLenum format, |
| GLenum type, |
| const void *pixels) |
| { |
| if (!context->getExtensions().getImageANGLE) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageExtensionNotEnabled); |
| return false; |
| } |
| |
| if (target != GL_RENDERBUFFER) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget); |
| return false; |
| } |
| |
| Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); |
| |
| if (!ValidateGetImageFormatAndType(context, entryPoint, renderbuffer, format, type)) |
| { |
| return false; |
| } |
| |
| GLsizei width = renderbuffer->getWidth(); |
| GLsizei height = renderbuffer->getHeight(); |
| if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr, |
| pixels)) |
| { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateDrawElementsBaseVertexEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode mode, |
| GLsizei count, |
| DrawElementsType type, |
| const void *indices, |
| GLint basevertex) |
| { |
| if (!context->getExtensions().drawElementsBaseVertexAny()) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1); |
| } |
| |
| bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode mode, |
| GLsizei count, |
| DrawElementsType type, |
| const void *indices, |
| GLsizei instancecount, |
| GLint basevertex) |
| { |
| if (!context->getExtensions().drawElementsBaseVertexAny()) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, |
| instancecount); |
| } |
| |
| bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode mode, |
| GLuint start, |
| GLuint end, |
| GLsizei count, |
| DrawElementsType type, |
| const void *indices, |
| GLint basevertex) |
| { |
| if (!context->getExtensions().drawElementsBaseVertexAny()) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| if (end < start) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange); |
| return false; |
| } |
| |
| if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0)) |
| { |
| return false; |
| } |
| |
| // Skip range checks for no-op calls. |
| if (count <= 0) |
| { |
| return true; |
| } |
| |
| // Note that resolving the index range is a bit slow. We should probably optimize this. |
| IndexRange indexRange; |
| ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count, |
| indices, &indexRange)); |
| |
| if (indexRange.end > end || indexRange.start < start) |
| { |
| // GL spec says that behavior in this case is undefined - generating an error is fine. |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsElementRange); |
| return false; |
| } |
| return true; |
| } |
| |
| bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode mode, |
| const GLsizei *count, |
| DrawElementsType type, |
| const void *const *indices, |
| GLsizei drawcount, |
| const GLint *basevertex) |
| { |
| return true; |
| } |
| |
| bool ValidateMultiDrawArraysIndirectEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode modePacked, |
| const void *indirect, |
| GLsizei drawcount, |
| GLsizei stride) |
| { |
| if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride)) |
| { |
| return false; |
| } |
| |
| if (!ValidateDrawArraysIndirect(context, entryPoint, modePacked, indirect)) |
| { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateMultiDrawElementsIndirectEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode modePacked, |
| DrawElementsType typePacked, |
| const void *indirect, |
| GLsizei drawcount, |
| GLsizei stride) |
| { |
| if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride)) |
| { |
| return false; |
| } |
| |
| const State &state = context->getState(); |
| TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); |
| if (!ValidateDrawElementsIndirect(context, entryPoint, modePacked, typePacked, indirect)) |
| { |
| return false; |
| } |
| |
| if (curTransformFeedback && curTransformFeedback->isActive() && |
| !curTransformFeedback->isPaused()) |
| { |
| // EXT_geometry_shader allows transform feedback to work with all draw commands. |
| // [EXT_geometry_shader] Section 12.1, "Transform Feedback" |
| if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2) |
| { |
| if (!ValidateTransformFeedbackPrimitiveMode( |
| context, entryPoint, curTransformFeedback->getPrimitiveMode(), modePacked)) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, |
| kInvalidDrawModeTransformFeedback); |
| return false; |
| } |
| } |
| else |
| { |
| // An INVALID_OPERATION error is generated if transform feedback is active and not |
| // paused. |
| context->validationError(entryPoint, GL_INVALID_OPERATION, |
| kUnsupportedDrawModeForTransformFeedback); |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ValidateDrawElementsBaseVertexOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode mode, |
| GLsizei count, |
| DrawElementsType type, |
| const void *indices, |
| GLint basevertex) |
| { |
| if (!context->getExtensions().drawElementsBaseVertexAny()) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1); |
| } |
| |
| bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode mode, |
| GLsizei count, |
| DrawElementsType type, |
| const void *indices, |
| GLsizei instancecount, |
| GLint basevertex) |
| { |
| if (!context->getExtensions().drawElementsBaseVertexAny()) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices, |
| instancecount); |
| } |
| |
| bool ValidateDrawRangeElementsBaseVertexOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| PrimitiveMode mode, |
| GLuint start, |
| GLuint end, |
| GLsizei count, |
| DrawElementsType type, |
| const void *indices, |
| GLint basevertex) |
| { |
| if (!context->getExtensions().drawElementsBaseVertexAny()) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| if (end < start) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange); |
| return false; |
| } |
| |
| if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0)) |
| { |
| return false; |
| } |
| |
| // Skip range checks for no-op calls. |
| if (count <= 0) |
| { |
| return true; |
| } |
| |
| // Note that resolving the index range is a bit slow. We should probably optimize this. |
| IndexRange indexRange; |
| ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count, |
| indices, &indexRange)); |
| |
| if (indexRange.end > end || indexRange.start < start) |
| { |
| // GL spec says that behavior in this case is undefined - generating an error is fine. |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsElementRange); |
| return false; |
| } |
| return true; |
| } |
| |
| // GL_KHR_blend_equation_advanced |
| bool ValidateBlendBarrierKHR(const Context *context, angle::EntryPoint entryPoint) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| bool ValidateBlendEquationSeparateiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint buf, |
| GLenum modeRGB, |
| GLenum modeAlpha) |
| { |
| if (!context->getExtensions().drawBuffersIndexedEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateBlendEquationSeparatei(context, entryPoint, buf, modeRGB, modeAlpha); |
| } |
| |
| bool ValidateBlendEquationiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint buf, |
| GLenum mode) |
| { |
| if (!context->getExtensions().drawBuffersIndexedEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateBlendEquationi(context, entryPoint, buf, mode); |
| } |
| |
| bool ValidateBlendFuncSeparateiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint buf, |
| GLenum srcRGB, |
| GLenum dstRGB, |
| GLenum srcAlpha, |
| GLenum dstAlpha) |
| { |
| if (!context->getExtensions().drawBuffersIndexedEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateBlendFuncSeparatei(context, entryPoint, buf, srcRGB, dstRGB, srcAlpha, dstAlpha); |
| } |
| |
| bool ValidateBlendFunciEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint buf, |
| GLenum src, |
| GLenum dst) |
| { |
| if (!context->getExtensions().drawBuffersIndexedEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateBlendFunci(context, entryPoint, buf, src, dst); |
| } |
| |
| bool ValidateColorMaskiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLboolean r, |
| GLboolean g, |
| GLboolean b, |
| GLboolean a) |
| { |
| if (!context->getExtensions().drawBuffersIndexedEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateColorMaski(context, entryPoint, index, r, g, b, a); |
| } |
| |
| bool ValidateDisableiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLuint index) |
| { |
| if (!context->getExtensions().drawBuffersIndexedEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateDisablei(context, entryPoint, target, index); |
| } |
| |
| bool ValidateEnableiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLuint index) |
| { |
| if (!context->getExtensions().drawBuffersIndexedEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateEnablei(context, entryPoint, target, index); |
| } |
| |
| bool ValidateIsEnablediEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLuint index) |
| { |
| if (!context->getExtensions().drawBuffersIndexedEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateIsEnabledi(context, entryPoint, target, index); |
| } |
| |
| bool ValidateBlendEquationSeparateiOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint buf, |
| GLenum modeRGB, |
| GLenum modeAlpha) |
| { |
| if (!context->getExtensions().drawBuffersIndexedOES) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateBlendEquationSeparatei(context, entryPoint, buf, modeRGB, modeAlpha); |
| } |
| |
| bool ValidateBlendEquationiOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint buf, |
| GLenum mode) |
| { |
| if (!context->getExtensions().drawBuffersIndexedOES) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateBlendEquationi(context, entryPoint, buf, mode); |
| } |
| |
| bool ValidateBlendFuncSeparateiOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint buf, |
| GLenum srcRGB, |
| GLenum dstRGB, |
| GLenum srcAlpha, |
| GLenum dstAlpha) |
| { |
| if (!context->getExtensions().drawBuffersIndexedOES) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateBlendFuncSeparatei(context, entryPoint, buf, srcRGB, dstRGB, srcAlpha, dstAlpha); |
| } |
| |
| bool ValidateBlendFunciOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint buf, |
| GLenum src, |
| GLenum dst) |
| { |
| if (!context->getExtensions().drawBuffersIndexedOES) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateBlendFunci(context, entryPoint, buf, src, dst); |
| } |
| |
| bool ValidateColorMaskiOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint index, |
| GLboolean r, |
| GLboolean g, |
| GLboolean b, |
| GLboolean a) |
| { |
| if (!context->getExtensions().drawBuffersIndexedOES) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateColorMaski(context, entryPoint, index, r, g, b, a); |
| } |
| |
| bool ValidateDisableiOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLuint index) |
| { |
| if (!context->getExtensions().drawBuffersIndexedOES) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateDisablei(context, entryPoint, target, index); |
| } |
| |
| bool ValidateEnableiOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLuint index) |
| { |
| if (!context->getExtensions().drawBuffersIndexedOES) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateEnablei(context, entryPoint, target, index); |
| } |
| |
| bool ValidateIsEnablediOES(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLuint index) |
| { |
| if (!context->getExtensions().drawBuffersIndexedOES) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateIsEnabledi(context, entryPoint, target, index); |
| } |
| |
| bool ValidateGetInteger64vEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum pname, |
| const GLint64 *data) |
| { |
| if (!context->getExtensions().disjointTimerQueryEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| GLenum nativeType = GL_NONE; |
| unsigned int numParams = 0; |
| if (!ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams)) |
| { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateCopyImageSubDataEXT(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) |
| { |
| if (!context->getExtensions().copyImageEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX, |
| srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, |
| srcWidth, srcHeight, srcDepth); |
| } |
| |
| bool ValidateCopyImageSubDataOES(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) |
| { |
| if (!context->getExtensions().copyImageEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX, |
| srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, |
| srcWidth, srcHeight, srcDepth); |
| } |
| |
| bool ValidateBufferStorageMemEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLsizeiptr size, |
| MemoryObjectID memory, |
| GLuint64 offset) |
| { |
| if (!context->getExtensions().memoryObjectEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| bool ValidateCreateMemoryObjectsEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLsizei n, |
| const MemoryObjectID *memoryObjects) |
| { |
| if (!context->getExtensions().memoryObjectEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateGenOrDelete(context, entryPoint, n); |
| } |
| |
| bool ValidateDeleteMemoryObjectsEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLsizei n, |
| const MemoryObjectID *memoryObjects) |
| { |
| if (!context->getExtensions().memoryObjectEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateGenOrDelete(context, entryPoint, n); |
| } |
| |
| bool ValidateGetMemoryObjectParameterivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| MemoryObjectID memoryObject, |
| GLenum pname, |
| const GLint *params) |
| { |
| if (!context->getExtensions().memoryObjectEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| const MemoryObject *memory = context->getMemoryObject(memoryObject); |
| if (memory == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryObject); |
| } |
| |
| if (!IsValidMemoryObjectParamater(context, entryPoint, pname)) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMemoryObjectParameter); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateGetUnsignedBytevEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum pname, |
| const GLubyte *data) |
| { |
| if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| bool ValidateGetUnsignedBytei_vEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLuint index, |
| const GLubyte *data) |
| { |
| if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| bool ValidateIsMemoryObjectEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| MemoryObjectID memoryObject) |
| { |
| if (!context->getExtensions().memoryObjectEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateMemoryObjectParameterivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| MemoryObjectID memoryObject, |
| GLenum pname, |
| const GLint *params) |
| { |
| if (!context->getExtensions().memoryObjectEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| const MemoryObject *memory = context->getMemoryObject(memoryObject); |
| if (memory == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryObject); |
| return false; |
| } |
| |
| if (memory->isImmutable()) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kImmutableMemoryObject); |
| return false; |
| } |
| |
| if (!IsValidMemoryObjectParamater(context, entryPoint, pname)) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMemoryObjectParameter); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateTexStorageMem2DEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLsizei levels, |
| GLenum internalFormat, |
| GLsizei width, |
| GLsizei height, |
| MemoryObjectID memory, |
| GLuint64 offset) |
| { |
| if (!context->getExtensions().memoryObjectEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| if (context->getClientMajorVersion() < 3) |
| { |
| return ValidateES2TexStorageParametersBase(context, entryPoint, target, levels, |
| internalFormat, width, height); |
| } |
| |
| ASSERT(context->getClientMajorVersion() >= 3); |
| return ValidateES3TexStorage2DParameters(context, entryPoint, target, levels, internalFormat, |
| width, height, 1); |
| } |
| |
| bool ValidateTexStorageMem3DEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType target, |
| GLsizei levels, |
| GLenum internalFormat, |
| GLsizei width, |
| GLsizei height, |
| GLsizei depth, |
| MemoryObjectID memory, |
| GLuint64 offset) |
| { |
| if (!context->getExtensions().memoryObjectEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| bool ValidateImportMemoryFdEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| MemoryObjectID memory, |
| GLuint64 size, |
| HandleType handleType, |
| GLint fd) |
| { |
| if (!context->getExtensions().memoryObjectFdEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| switch (handleType) |
| { |
| case HandleType::OpaqueFd: |
| break; |
| default: |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateImportMemoryZirconHandleANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| MemoryObjectID memory, |
| GLuint64 size, |
| HandleType handleType, |
| GLuint handle) |
| { |
| if (!context->getExtensions().memoryObjectFuchsiaANGLE) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| switch (handleType) |
| { |
| case HandleType::ZirconVmo: |
| break; |
| default: |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateDeleteSemaphoresEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLsizei n, |
| const SemaphoreID *semaphores) |
| { |
| if (!context->getExtensions().semaphoreEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateGenOrDelete(context, entryPoint, n); |
| } |
| |
| bool ValidateGenSemaphoresEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLsizei n, |
| const SemaphoreID *semaphores) |
| { |
| if (!context->getExtensions().semaphoreEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateGenOrDelete(context, entryPoint, n); |
| } |
| |
| bool ValidateGetSemaphoreParameterui64vEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SemaphoreID semaphore, |
| GLenum pname, |
| const GLuint64 *params) |
| { |
| if (!context->getExtensions().semaphoreEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| bool ValidateIsSemaphoreEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SemaphoreID semaphore) |
| { |
| if (!context->getExtensions().semaphoreEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateSemaphoreParameterui64vEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SemaphoreID semaphore, |
| GLenum pname, |
| const GLuint64 *params) |
| { |
| if (!context->getExtensions().semaphoreEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| bool ValidateSignalSemaphoreEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SemaphoreID semaphore, |
| GLuint numBufferBarriers, |
| const BufferID *buffers, |
| GLuint numTextureBarriers, |
| const TextureID *textures, |
| const GLenum *dstLayouts) |
| { |
| if (!context->getExtensions().semaphoreEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| for (GLuint i = 0; i < numBufferBarriers; ++i) |
| { |
| if (!context->getBuffer(buffers[i])) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName); |
| return false; |
| } |
| } |
| |
| for (GLuint i = 0; i < numTextureBarriers; ++i) |
| { |
| if (!context->getTexture(textures[i])) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); |
| return false; |
| } |
| if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i]))) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout); |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ValidateWaitSemaphoreEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SemaphoreID semaphore, |
| GLuint numBufferBarriers, |
| const BufferID *buffers, |
| GLuint numTextureBarriers, |
| const TextureID *textures, |
| const GLenum *srcLayouts) |
| { |
| if (!context->getExtensions().semaphoreEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| for (GLuint i = 0; i < numBufferBarriers; ++i) |
| { |
| if (!context->getBuffer(buffers[i])) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName); |
| return false; |
| } |
| } |
| |
| for (GLuint i = 0; i < numTextureBarriers; ++i) |
| { |
| if (!context->getTexture(textures[i])) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); |
| return false; |
| } |
| if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i]))) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout); |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ValidateImportSemaphoreFdEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SemaphoreID semaphore, |
| HandleType handleType, |
| GLint fd) |
| { |
| if (!context->getExtensions().semaphoreFdEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| switch (handleType) |
| { |
| case HandleType::OpaqueFd: |
| break; |
| default: |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateGetSamplerParameterIivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SamplerID samplerPacked, |
| GLenum pname, |
| const GLint *params) |
| { |
| if (context->getClientMajorVersion() < 3) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); |
| return false; |
| } |
| return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr); |
| } |
| |
| bool ValidateGetSamplerParameterIuivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SamplerID samplerPacked, |
| GLenum pname, |
| const GLuint *params) |
| { |
| if (context->getClientMajorVersion() < 3) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); |
| return false; |
| } |
| return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr); |
| } |
| |
| bool ValidateGetTexParameterIivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType targetPacked, |
| GLenum pname, |
| const GLint *params) |
| { |
| if (context->getClientMajorVersion() < 3) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); |
| return false; |
| } |
| return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr); |
| } |
| |
| bool ValidateGetTexParameterIuivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType targetPacked, |
| GLenum pname, |
| const GLuint *params) |
| { |
| if (context->getClientMajorVersion() < 3) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); |
| return false; |
| } |
| return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr); |
| } |
| |
| bool ValidateSamplerParameterIivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SamplerID samplerPacked, |
| GLenum pname, |
| const GLint *param) |
| { |
| if (context->getClientMajorVersion() < 3) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); |
| return false; |
| } |
| return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param); |
| } |
| |
| bool ValidateSamplerParameterIuivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| SamplerID samplerPacked, |
| GLenum pname, |
| const GLuint *param) |
| { |
| if (context->getClientMajorVersion() < 3) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); |
| return false; |
| } |
| return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param); |
| } |
| |
| bool ValidateTexParameterIivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType targetPacked, |
| GLenum pname, |
| const GLint *params) |
| { |
| if (context->getClientMajorVersion() < 3) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); |
| return false; |
| } |
| return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params); |
| } |
| |
| bool ValidateTexParameterIuivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType targetPacked, |
| GLenum pname, |
| const GLuint *params) |
| { |
| if (context->getClientMajorVersion() < 3) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required); |
| return false; |
| } |
| return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params); |
| } |
| |
| bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| SemaphoreID semaphore, |
| HandleType handleType, |
| GLuint handle) |
| { |
| if (!context->getExtensions().semaphoreFuchsiaANGLE) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| switch (handleType) |
| { |
| case HandleType::ZirconEvent: |
| break; |
| default: |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint) |
| { |
| return true; |
| } |
| |
| bool ValidatePatchParameteriEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum pname, |
| GLint value) |
| { |
| if (!context->getExtensions().tessellationShaderEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, |
| kTessellationShaderExtensionNotEnabled); |
| return false; |
| } |
| |
| if (pname != GL_PATCH_VERTICES) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); |
| return false; |
| } |
| |
| if (value <= 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueNonPositive); |
| return false; |
| } |
| |
| if (value > context->getCaps().maxPatchVertices) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueExceedsMaxPatchSize); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateTexStorageMemFlags2DANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType targetPacked, |
| GLsizei levels, |
| GLenum internalFormat, |
| GLsizei width, |
| GLsizei height, |
| MemoryObjectID memoryPacked, |
| GLuint64 offset, |
| GLbitfield createFlags, |
| GLbitfield usageFlags, |
| const void *imageCreateInfoPNext) |
| { |
| if (!context->getExtensions().memoryObjectFlagsANGLE) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| if (!ValidateTexStorageMem2DEXT(context, entryPoint, targetPacked, levels, internalFormat, |
| width, height, memoryPacked, offset)) |
| { |
| return false; |
| } |
| |
| // |createFlags| and |usageFlags| must only have bits specified by the extension. |
| constexpr GLbitfield kAllCreateFlags = |
| GL_CREATE_SPARSE_BINDING_BIT_ANGLE | GL_CREATE_SPARSE_RESIDENCY_BIT_ANGLE | |
| GL_CREATE_SPARSE_ALIASED_BIT_ANGLE | GL_CREATE_MUTABLE_FORMAT_BIT_ANGLE | |
| GL_CREATE_CUBE_COMPATIBLE_BIT_ANGLE | GL_CREATE_ALIAS_BIT_ANGLE | |
| GL_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_ANGLE | GL_CREATE_2D_ARRAY_COMPATIBLE_BIT_ANGLE | |
| GL_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_ANGLE | GL_CREATE_EXTENDED_USAGE_BIT_ANGLE | |
| GL_CREATE_PROTECTED_BIT_ANGLE | GL_CREATE_DISJOINT_BIT_ANGLE | |
| GL_CREATE_CORNER_SAMPLED_BIT_ANGLE | GL_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_ANGLE | |
| GL_CREATE_SUBSAMPLED_BIT_ANGLE; |
| |
| if ((createFlags & ~kAllCreateFlags) != 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidExternalCreateFlags); |
| return false; |
| } |
| |
| constexpr GLbitfield kAllUsageFlags = |
| GL_USAGE_TRANSFER_SRC_BIT_ANGLE | GL_USAGE_TRANSFER_DST_BIT_ANGLE | |
| GL_USAGE_SAMPLED_BIT_ANGLE | GL_USAGE_STORAGE_BIT_ANGLE | |
| GL_USAGE_COLOR_ATTACHMENT_BIT_ANGLE | GL_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT_ANGLE | |
| GL_USAGE_TRANSIENT_ATTACHMENT_BIT_ANGLE | GL_USAGE_INPUT_ATTACHMENT_BIT_ANGLE | |
| GL_USAGE_SHADING_RATE_IMAGE_BIT_ANGLE | GL_USAGE_FRAGMENT_DENSITY_MAP_BIT_ANGLE; |
| |
| if ((usageFlags & ~kAllUsageFlags) != 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidExternalUsageFlags); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType targetPacked, |
| GLsizei samples, |
| GLenum internalFormat, |
| GLsizei width, |
| GLsizei height, |
| GLboolean fixedSampleLocations, |
| MemoryObjectID memoryPacked, |
| GLuint64 offset, |
| GLbitfield createFlags, |
| GLbitfield usageFlags, |
| const void *imageCreateInfoPNext) |
| { |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| bool ValidateTexStorageMemFlags3DANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType targetPacked, |
| GLsizei levels, |
| GLenum internalFormat, |
| GLsizei width, |
| GLsizei height, |
| GLsizei depth, |
| MemoryObjectID memoryPacked, |
| GLuint64 offset, |
| GLbitfield createFlags, |
| GLbitfield usageFlags, |
| const void *imageCreateInfoPNext) |
| { |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| TextureType targetPacked, |
| GLsizei samples, |
| GLenum internalFormat, |
| GLsizei width, |
| GLsizei height, |
| GLsizei depth, |
| GLboolean fixedSampleLocations, |
| MemoryObjectID memoryPacked, |
| GLuint64 offset, |
| GLbitfield createFlags, |
| GLbitfield usageFlags, |
| const void *imageCreateInfoPNext) |
| { |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| // GL_EXT_buffer_storage |
| bool ValidateBufferStorageEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| BufferBinding targetPacked, |
| GLsizeiptr size, |
| const void *data, |
| GLbitfield flags) |
| { |
| if (!context->isValidBufferBinding(targetPacked)) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes); |
| return false; |
| } |
| |
| if (size <= 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kNonPositiveSize); |
| return false; |
| } |
| |
| constexpr GLbitfield kAllUsageFlags = |
| (GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | |
| GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT | GL_CLIENT_STORAGE_BIT_EXT); |
| if ((flags & ~kAllUsageFlags) != 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags); |
| return false; |
| } |
| |
| if (((flags & GL_MAP_PERSISTENT_BIT_EXT) != 0) && |
| ((flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags); |
| return false; |
| } |
| |
| if (((flags & GL_MAP_COHERENT_BIT_EXT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT_EXT) == 0)) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags); |
| return false; |
| } |
| |
| Buffer *buffer = context->getState().getTargetBuffer(targetPacked); |
| |
| if (buffer == nullptr) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound); |
| return false; |
| } |
| |
| if (buffer->isImmutable()) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferImmutable); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| // GL_EXT_clip_control |
| bool ValidateClipControlEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum origin, |
| GLenum depth) |
| { |
| if ((origin != GL_LOWER_LEFT_EXT) && (origin != GL_UPPER_LEFT_EXT)) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidOriginEnum); |
| return false; |
| } |
| |
| if ((depth != GL_NEGATIVE_ONE_TO_ONE_EXT) && (depth != GL_ZERO_TO_ONE_EXT)) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDepthEnum); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| // GL_EXT_external_buffer |
| bool ValidateBufferStorageExternalEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| BufferBinding targetPacked, |
| GLintptr offset, |
| GLsizeiptr size, |
| GLeglClientBufferEXT clientBuffer, |
| GLbitfield flags) |
| { |
| if (!ValidateBufferStorageEXT(context, entryPoint, targetPacked, size, nullptr, flags)) |
| { |
| return false; |
| } |
| |
| if (offset != 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kExternalBufferInvalidOffset); |
| return false; |
| } |
| |
| if (clientBuffer == nullptr && size > 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kClientBufferInvalid); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateNamedBufferStorageExternalEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint buffer, |
| GLintptr offset, |
| GLsizeiptr size, |
| GLeglClientBufferEXT clientBuffer, |
| GLbitfield flags) |
| { |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| // GL_EXT_primitive_bounding_box |
| bool ValidatePrimitiveBoundingBoxEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLfloat minX, |
| GLfloat minY, |
| GLfloat minZ, |
| GLfloat minW, |
| GLfloat maxX, |
| GLfloat maxY, |
| GLfloat maxZ, |
| GLfloat maxW) |
| { |
| if (!context->getExtensions().primitiveBoundingBoxEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| // GL_EXT_separate_shader_objects |
| bool ValidateActiveShaderProgramEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ProgramPipelineID pipelinePacked, |
| ShaderProgramID programPacked) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked); |
| } |
| |
| bool ValidateBindProgramPipelineEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ProgramPipelineID pipelinePacked) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked); |
| } |
| |
| bool ValidateCreateShaderProgramvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderType typePacked, |
| GLsizei count, |
| const GLchar **strings) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings); |
| } |
| |
| bool ValidateDeleteProgramPipelinesEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLsizei n, |
| const ProgramPipelineID *pipelinesPacked) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked); |
| } |
| |
| bool ValidateGenProgramPipelinesEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLsizei n, |
| const ProgramPipelineID *pipelinesPacked) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked); |
| } |
| |
| bool ValidateGetProgramPipelineInfoLogEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ProgramPipelineID pipelinePacked, |
| GLsizei bufSize, |
| const GLsizei *length, |
| const GLchar *infoLog) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize, |
| length, infoLog); |
| } |
| |
| bool ValidateGetProgramPipelineivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ProgramPipelineID pipelinePacked, |
| GLenum pname, |
| const GLint *params) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params); |
| } |
| |
| bool ValidateIsProgramPipelineEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ProgramPipelineID pipelinePacked) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked); |
| } |
| |
| bool ValidateProgramParameteriEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| GLenum pname, |
| GLint value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramParameteriBase(context, entryPoint, programPacked, pname, value); |
| } |
| |
| bool ValidateProgramUniform1fEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLfloat v0) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0); |
| } |
| |
| bool ValidateProgramUniform1fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform1iEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLint v0) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0); |
| } |
| |
| bool ValidateProgramUniform1ivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLint *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform1uiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLuint v0) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0); |
| } |
| |
| bool ValidateProgramUniform1uivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLuint *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform2fEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLfloat v0, |
| GLfloat v1) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1); |
| } |
| |
| bool ValidateProgramUniform2fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform2iEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLint v0, |
| GLint v1) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1); |
| } |
| |
| bool ValidateProgramUniform2ivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLint *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform2uiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLuint v0, |
| GLuint v1) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0, |
| v1); |
| } |
| |
| bool ValidateProgramUniform2uivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLuint *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform3fEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLfloat v0, |
| GLfloat v1, |
| GLfloat v2) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1, |
| v2); |
| } |
| |
| bool ValidateProgramUniform3fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform3iEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLint v0, |
| GLint v1, |
| GLint v2) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1, |
| v2); |
| } |
| |
| bool ValidateProgramUniform3ivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLint *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform3uiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLuint v0, |
| GLuint v1, |
| GLuint v2) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1, |
| v2); |
| } |
| |
| bool ValidateProgramUniform3uivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLuint *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform4fEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLfloat v0, |
| GLfloat v1, |
| GLfloat v2, |
| GLfloat v3) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1, |
| v2, v3); |
| } |
| |
| bool ValidateProgramUniform4fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform4iEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLint v0, |
| GLint v1, |
| GLint v2, |
| GLint v3) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1, |
| v2, v3); |
| } |
| |
| bool ValidateProgramUniform4ivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLint *value) |
| { |
| return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniform4uiEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLuint v0, |
| GLuint v1, |
| GLuint v2, |
| GLuint v3) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1, |
| v2, v3); |
| } |
| |
| bool ValidateProgramUniform4uivEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| const GLuint *value) |
| { |
| return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count, |
| value); |
| } |
| |
| bool ValidateProgramUniformMatrix2fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked, |
| count, transpose, value); |
| } |
| |
| bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked, |
| count, transpose, value); |
| } |
| |
| bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked, |
| count, transpose, value); |
| } |
| |
| bool ValidateProgramUniformMatrix3fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked, |
| count, transpose, value); |
| } |
| |
| bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked, |
| count, transpose, value); |
| } |
| |
| bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked, |
| count, transpose, value); |
| } |
| |
| bool ValidateProgramUniformMatrix4fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked, |
| count, transpose, value); |
| } |
| |
| bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked, |
| count, transpose, value); |
| } |
| |
| bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ShaderProgramID programPacked, |
| UniformLocation locationPacked, |
| GLsizei count, |
| GLboolean transpose, |
| const GLfloat *value) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked, |
| count, transpose, value); |
| } |
| |
| bool ValidateUseProgramStagesEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ProgramPipelineID pipelinePacked, |
| GLbitfield stages, |
| ShaderProgramID programPacked) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked); |
| } |
| |
| bool ValidateValidateProgramPipelineEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| ProgramPipelineID pipelinePacked) |
| { |
| if (!context->getExtensions().separateShaderObjectsEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked); |
| } |
| |
| // GL_EXT_debug_label |
| bool ValidateGetObjectLabelEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum type, |
| GLuint object, |
| GLsizei bufSize, |
| const GLsizei *length, |
| const GLchar *label) |
| { |
| if (!context->getExtensions().debugLabelEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| if (bufSize < 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); |
| return false; |
| } |
| |
| return ValidateObjectIdentifierAndName(context, entryPoint, type, object); |
| } |
| |
| bool ValidateLabelObjectEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum type, |
| GLuint object, |
| GLsizei length, |
| const GLchar *label) |
| { |
| if (!context->getExtensions().debugLabelEXT) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| if (length < 0) |
| { |
| context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLength); |
| return false; |
| } |
| |
| return ValidateObjectIdentifierAndName(context, entryPoint, type, object); |
| } |
| |
| bool ValidateEGLImageTargetTextureStorageEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint texture, |
| GLeglImageOES image, |
| const GLint *attrib_list) |
| { |
| UNREACHABLE(); |
| return false; |
| } |
| |
| bool ValidateEGLImageTargetTexStorageEXT(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLeglImageOES image, |
| const GLint *attrib_list) |
| { |
| UNREACHABLE(); |
| return false; |
| } |
| |
| bool ValidateAcquireTexturesANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint numTextures, |
| const TextureID *textures, |
| const GLenum *layouts) |
| { |
| if (!context->getExtensions().vulkanImageANGLE) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| |
| for (GLuint i = 0; i < numTextures; ++i) |
| { |
| if (!context->getTexture(textures[i])) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); |
| return false; |
| } |
| if (!IsValidImageLayout(FromGLenum<ImageLayout>(layouts[i]))) |
| { |
| context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout); |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ValidateReleaseTexturesANGLE(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLuint numTextures, |
| const TextureID *textures, |
| const GLenum *layouts) |
| { |
| if (!context->getExtensions().vulkanImageANGLE) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); |
| return false; |
| } |
| for (GLuint i = 0; i < numTextures; ++i) |
| { |
| if (!context->getTexture(textures[i])) |
| { |
| context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName); |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ValidateFramebufferParameteriMESA(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLenum pname, |
| GLint param) |
| { |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| bool ValidateGetFramebufferParameterivMESA(const Context *context, |
| angle::EntryPoint entryPoint, |
| GLenum target, |
| GLenum pname, |
| const GLint *params) |
| { |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| } // namespace gl |