//
// 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.
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

#include "libANGLE/validationESEXT_autogen.h"

#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/ErrorStrings.h"
#include "libANGLE/MemoryObject.h"
#include "libANGLE/PixelLocalStorage.h"
#include "libANGLE/validationES.h"
#include "libANGLE/validationES2.h"
#include "libANGLE/validationES3.h"
#include "libANGLE/validationES31.h"
#include "libANGLE/validationES32.h"

#include <optional>

namespace gl
{
using namespace err;

void RecordVersionErrorESEXT(const Context *context, angle::EntryPoint entryPoint)
{
    ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEntryPointRequiresESEXT);
}

void RecordEntryPointBaseUnsupportedError(const Context *context, angle::EntryPoint entryPoint)
{
    ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEntryPointBaseUnsupported);
}

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))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
        return false;
    }

    GLenum implType = obj->getImplementationColorReadType(context);
    if (!ValidES3Type(type) && (type != implType || type == GL_NONE))
    {
        ANGLE_VALIDATION_ERROR(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 IsValidMemoryObjectParameter(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)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
                return false;
            }
            return true;

        default:
            return false;
    }
}

bool ValidateObjectIdentifierAndName(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     GLenum identifier,
                                     GLuint name)
{
    const bool isGLES11 = context->getClientVersion() == ES_1_1;
    const bool isGLES3  = context->getClientVersion() >= ES_3_0;
    const bool isGLES31 = context->getClientVersion() >= ES_3_1;
    switch (identifier)
    {
        case GL_BUFFER_OBJECT_EXT:
            if (context->getBuffer({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidBufferName);
                return false;
            }
            return true;

        case GL_SHADER_OBJECT_EXT:
            if (isGLES11)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
                return false;
            }
            if (context->getShaderNoResolveCompile({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidShaderName);
                return false;
            }
            return true;

        case GL_PROGRAM_OBJECT_EXT:
            if (isGLES11)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
                return false;
            }
            if (context->getProgramNoResolveLink({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidProgramName);
                return false;
            }
            return true;

        case GL_VERTEX_ARRAY_OBJECT_EXT:
            if (!isGLES3 && !context->getExtensions().vertexArrayObjectOES)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
                return false;
            }
            if (context->getPrivateState().getVertexArray({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidVertexArrayName);
                return false;
            }
            return true;

        case GL_QUERY_OBJECT_EXT:
            if (!isGLES3 && !(context->getExtensions().disjointTimerQueryEXT ||
                              context->getExtensions().occlusionQueryBooleanEXT))
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
                return false;
            }
            if (context->getQuery({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryName);
                return false;
            }
            return true;

        case GL_TRANSFORM_FEEDBACK:
            if (!isGLES3)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
                return false;
            }
            if (context->getTransformFeedback({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTransformFeedbackName);
                return false;
            }
            return true;

        case GL_SAMPLER:
            if (!isGLES3)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
                return false;
            }
            if (context->getSampler({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSamplerName);
                return false;
            }
            return true;

        case GL_TEXTURE:
            if (context->getTexture({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
                return false;
            }
            return true;

        case GL_RENDERBUFFER:
            if (!context->isRenderbuffer({name}))
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidRenderbufferName);
                return false;
            }
            return true;

        case GL_FRAMEBUFFER:
            if (context->getFramebuffer({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFramebufferName);
                return false;
            }
            return true;

        case GL_PROGRAM_PIPELINE_OBJECT_EXT:
            if (!isGLES31 && !context->getExtensions().separateShaderObjectsEXT)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
                return false;
            }
            if (context->getProgramPipeline({name}) == nullptr)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidProgramPipelineName);
                return false;
            }
            return true;

        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidIndentifier);
            return false;
    }
}

bool ValidateClearTexImageFormat(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 TextureType textureType,
                                 const Format &textureFormat,
                                 GLenum format,
                                 GLenum type)
{
    if (textureFormat.info->compressed)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsCompressed);
        return false;
    }

    if (!ValidateTexImageFormatCombination(context, entryPoint, textureType,
                                           textureFormat.info->internalFormat, format, type))
    {
        return false;
    }

    return true;
}

bool ValidateClearTexImageCommon(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 TextureID texturePacked,
                                 GLint level,
                                 const std::optional<Box> &area,
                                 GLenum format,
                                 GLenum type,
                                 const void *data)
{
    if (texturePacked.value == 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTextureName);
        return false;
    }

    Texture *tex = context->getTexture(texturePacked);
    if (tex == nullptr)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTextureName);
        return false;
    }

    if (tex->getType() == TextureType::Buffer)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferTextureNotAllowed);
        return false;
    }

    if (!ValidMipLevel(context, tex->getType(), level))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
        return false;
    }

    if (area.has_value() && (area->x < 0 || area->y < 0 || area->z < 0 || area->width < 0 ||
                             area->height < 0 || area->depth < 0))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNegativeOffset);
        return false;
    }

    if (tex->getType() == TextureType::CubeMap)
    {
        if (area.has_value() && area->z + area->depth > 6)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationTextureTooSmall);
            return false;
        }

        ImageIndexIterator it = ImageIndexIterator::MakeGeneric(
            tex->getType(), level, level + 1, area.has_value() ? area->z : ImageIndex::kEntireLevel,
            area.has_value() ? area->z + area->depth : ImageIndex::kEntireLevel);
        while (it.hasNext())
        {
            const ImageIndex index = it.next();
            TextureTarget target   = index.getTarget();
            const Extents extents  = tex->getExtents(target, level);

            if (!tex->getState().getImageDesc(index).format.valid())
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
                return false;
            }

            if (area.has_value() &&
                (area->x + area->width > extents.width || area->y + area->height > extents.height))
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationTextureTooSmall);
                return false;
            }

            if (!ValidateClearTexImageFormat(context, entryPoint, tex->getType(),
                                             tex->getFormat(target, level), format, type))
            {
                return false;
            }
        }
    }
    else
    {
        TextureTarget target  = NonCubeTextureTypeToTarget(tex->getType());
        const Extents extents = tex->getExtents(target, level);

        if (!tex->getState().getImageDesc(target, level).format.valid())
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
            return false;
        }

        if (area.has_value() &&
            (area->x + area->width > extents.width || area->y + area->height > extents.height ||
             area->z + area->depth > extents.depth))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationTextureTooSmall);
            return false;
        }

        if (!ValidateClearTexImageFormat(context, entryPoint, tex->getType(),
                                         tex->getFormat(target, level), format, type))
        {
            return false;
        }
    }

    return true;
}

}  // namespace

bool ValidateGetTexImage(const Context *context,
                         angle::EntryPoint entryPoint,
                         TextureTarget target,
                         GLint level)
{
    if (!ValidTexture2DDestinationTarget(context, target) &&
        !ValidTexture3DDestinationTarget(context, target))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
        return false;
    }

    if (level < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLevel);
        return false;
    }

    TextureType textureType = TextureTargetToType(target);
    if (!ValidMipLevel(context, textureType, level))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
        return false;
    }

    return true;
}

bool ValidateGetTexImageANGLE(const Context *context,
                              angle::EntryPoint entryPoint,
                              TextureTarget target,
                              GLint level,
                              GLenum format,
                              GLenum type,
                              const void *pixels)
{
    if (!ValidateGetTexImage(context, entryPoint, target, level))
    {
        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)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageCompressed);
        return false;
    }

    return true;
}

bool ValidateGetCompressedTexImageANGLE(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        TextureTarget target,
                                        GLint level,
                                        const void *pixels)
{
    if (!ValidateGetTexImage(context, entryPoint, target, level))
    {
        return false;
    }

    Texture *texture = context->getTextureByTarget(target);
    if (!texture->getFormat(target, level).info->compressed)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageNotCompressed);
        return false;
    }

    return true;
}

bool ValidateGetRenderbufferImageANGLE(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLenum target,
                                       GLenum format,
                                       GLenum type,
                                       const void *pixels)
{
    if (target != GL_RENDERBUFFER)
    {
        ANGLE_VALIDATION_ERROR(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)
{
    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->getClientVersion() < ES_3_0 && !context->getExtensions().drawInstancedEXT &&
        !context->getExtensions().instancedArraysANGLE &&
        !context->getExtensions().instancedArraysEXT)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
        return false;
    }

    return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
                                             instancecount, 0);
}

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->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    if (end < start)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidElementRange);
        return false;
    }

    if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1))
    {
        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{IndexRange::Undefined()};
    ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(
        context, type, count, indices, context->getState().isPrimitiveRestartEnabled(),
        &indexRange));
    if (!indexRange.isEmpty() && (indexRange.end() > end || indexRange.start() < start))
    {
        // GL spec says that behavior in this case is undefined - generating an error is fine.
        ANGLE_VALIDATION_ERROR(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)
{
    if (!context->getExtensions().multiDrawArraysEXT)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
        return false;
    }

    UNIMPLEMENTED();
    return true;
}

bool ValidateMultiDrawArraysEXT(const Context *context,
                                angle::EntryPoint entryPoint,
                                PrimitiveMode modePacked,
                                const GLint *first,
                                const GLsizei *count,
                                GLsizei primcount)
{
    UNIMPLEMENTED();
    return false;
}

bool ValidateMultiDrawElementsEXT(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  PrimitiveMode modePacked,
                                  const GLsizei *count,
                                  DrawElementsType typePacked,
                                  const void *const *indices,
                                  GLsizei primcount)
{
    UNIMPLEMENTED();
    return false;
}

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)
        {
            // An INVALID_OPERATION error is generated if transform feedback is active and not
            // paused.
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kUnsupportedDrawModeForTransformFeedback);
            return false;
        }
    }

    return true;
}

bool ValidateDrawArraysInstancedBaseInstanceEXT(const Context *context,
                                                angle::EntryPoint entryPoint,
                                                PrimitiveMode mode,
                                                GLint first,
                                                GLsizei count,
                                                GLsizei instanceCount,
                                                GLuint baseInstance)
{
    return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, instanceCount,
                                           baseInstance);
}

bool ValidateDrawElementsInstancedBaseInstanceEXT(const Context *context,
                                                  angle::EntryPoint entryPoint,
                                                  PrimitiveMode mode,
                                                  GLsizei count,
                                                  DrawElementsType type,
                                                  void const *indices,
                                                  GLsizei instancecount,
                                                  GLuint baseinstance)
{
    return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
                                             instancecount, baseinstance);
}

bool ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context *context,
                                                            angle::EntryPoint entryPoint,
                                                            PrimitiveMode mode,
                                                            GLsizei count,
                                                            DrawElementsType typePacked,
                                                            const void *indices,
                                                            GLsizei instancecount,
                                                            GLint basevertex,
                                                            GLuint baseinstance)
{
    return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, typePacked, indices,
                                             instancecount, baseinstance);
}

bool ValidateDrawElementsBaseVertexOES(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       PrimitiveMode mode,
                                       GLsizei count,
                                       DrawElementsType type,
                                       const void *indices,
                                       GLint basevertex)
{
    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->getClientVersion() < ES_3_0 && !context->getExtensions().drawInstancedEXT &&
        !context->getExtensions().instancedArraysANGLE &&
        !context->getExtensions().instancedArraysEXT)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
        return false;
    }

    return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
                                             instancecount, 0);
}

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->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    if (end < start)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidElementRange);
        return false;
    }

    if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1))
    {
        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{IndexRange::Undefined()};
    ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(
        context, type, count, indices, context->getState().isPrimitiveRestartEnabled(),
        &indexRange));
    if (!indexRange.isEmpty() && (indexRange.end() > end || indexRange.start() < start))
    {
        // GL spec says that behavior in this case is undefined - generating an error is fine.
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsElementRange);
        return false;
    }
    return true;
}

// GL_KHR_blend_equation_advanced
bool ValidateBlendBarrierKHR(const Context *context, angle::EntryPoint entryPoint)
{
    return true;
}

bool ValidateGetGraphicsResetStatusKHR(const Context *context, angle::EntryPoint entryPoint)
{
    if (context->getClientVersion() < ES_2_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
        return false;
    }

    return true;
}

bool ValidateGetnUniformfvKHR(const Context *context,
                              angle::EntryPoint entryPoint,
                              ShaderProgramID programPacked,
                              UniformLocation locationPacked,
                              GLsizei bufSize,
                              const GLfloat *params)
{
    if (context->getClientVersion() < ES_2_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
        return false;
    }

    return ValidateSizedGetUniform(context, entryPoint, programPacked, locationPacked, bufSize);
}

bool ValidateGetnUniformivKHR(const Context *context,
                              angle::EntryPoint entryPoint,
                              ShaderProgramID programPacked,
                              UniformLocation locationPacked,
                              GLsizei bufSize,
                              const GLint *params)
{
    if (context->getClientVersion() < ES_2_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
        return false;
    }

    return ValidateSizedGetUniform(context, entryPoint, programPacked, locationPacked, bufSize);
}

bool ValidateGetnUniformuivKHR(const Context *context,
                               angle::EntryPoint entryPoint,
                               ShaderProgramID programPacked,
                               UniformLocation locationPacked,
                               GLsizei bufSize,
                               const GLuint *params)
{
    // Based on the spec, if ES 3.0 or later is not supported, all references to GetnUniformuiv
    // should be removed.
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateSizedGetUniform(context, entryPoint, programPacked, locationPacked, bufSize);
}

bool ValidateReadnPixelsKHR(const Context *context,
                            angle::EntryPoint entryPoint,
                            GLint x,
                            GLint y,
                            GLsizei width,
                            GLsizei height,
                            GLenum format,
                            GLenum type,
                            GLsizei bufSize,
                            const void *data)
{
    if (context->getClientVersion() < ES_2_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
        return false;
    }

    if (bufSize < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
        return false;
    }

    return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
                                  nullptr, nullptr, nullptr, data);
}

bool ValidateBlendEquationOES(const PrivateState &state,
                              ErrorSet *errors,
                              angle::EntryPoint entryPoint,
                              GLenum mode)
{
    switch (mode)
    {
        case GL_FUNC_ADD_OES:
        case GL_FUNC_SUBTRACT_OES:
        case GL_FUNC_REVERSE_SUBTRACT_OES:
            return true;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation);
            return false;
    }
}

bool ValidateBlendEquationSeparateiEXT(const PrivateState &state,
                                       ErrorSet *errors,
                                       angle::EntryPoint entryPoint,
                                       GLuint buf,
                                       GLenum modeRGB,
                                       GLenum modeAlpha)
{
    return ValidateBlendEquationSeparatei(state, errors, entryPoint, buf, modeRGB, modeAlpha);
}

bool ValidateBlendEquationiEXT(const PrivateState &state,
                               ErrorSet *errors,
                               angle::EntryPoint entryPoint,
                               GLuint buf,
                               GLenum mode)
{
    return ValidateBlendEquationi(state, errors, entryPoint, buf, mode);
}

bool ValidateBlendFuncSeparateiEXT(const PrivateState &state,
                                   ErrorSet *errors,
                                   angle::EntryPoint entryPoint,
                                   GLuint buf,
                                   GLenum srcRGB,
                                   GLenum dstRGB,
                                   GLenum srcAlpha,
                                   GLenum dstAlpha)
{
    return ValidateBlendFuncSeparatei(state, errors, entryPoint, buf, srcRGB, dstRGB, srcAlpha,
                                      dstAlpha);
}

bool ValidateBlendFunciEXT(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLuint buf,
                           GLenum src,
                           GLenum dst)
{
    return ValidateBlendFunci(state, errors, entryPoint, buf, src, dst);
}

bool ValidateColorMaskiEXT(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLuint index,
                           GLboolean r,
                           GLboolean g,
                           GLboolean b,
                           GLboolean a)
{
    return ValidateColorMaski(state, errors, entryPoint, index, r, g, b, a);
}

bool ValidateDisableiEXT(const PrivateState &state,
                         ErrorSet *errors,
                         angle::EntryPoint entryPoint,
                         GLenum target,
                         GLuint index)
{
    return ValidateDisablei(state, errors, entryPoint, target, index);
}

bool ValidateEnableiEXT(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLenum target,
                        GLuint index)
{
    return ValidateEnablei(state, errors, entryPoint, target, index);
}

bool ValidateIsEnablediEXT(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLenum target,
                           GLuint index)
{
    return ValidateIsEnabledi(state, errors, entryPoint, target, index);
}

bool ValidateBlendEquationSeparateiOES(const PrivateState &state,
                                       ErrorSet *errors,
                                       angle::EntryPoint entryPoint,
                                       GLuint buf,
                                       GLenum modeRGB,
                                       GLenum modeAlpha)
{
    return ValidateBlendEquationSeparatei(state, errors, entryPoint, buf, modeRGB, modeAlpha);
}

bool ValidateBlendEquationiOES(const PrivateState &state,
                               ErrorSet *errors,
                               angle::EntryPoint entryPoint,
                               GLuint buf,
                               GLenum mode)
{
    return ValidateBlendEquationi(state, errors, entryPoint, buf, mode);
}

bool ValidateBlendFuncSeparateiOES(const PrivateState &state,
                                   ErrorSet *errors,
                                   angle::EntryPoint entryPoint,
                                   GLuint buf,
                                   GLenum srcRGB,
                                   GLenum dstRGB,
                                   GLenum srcAlpha,
                                   GLenum dstAlpha)
{
    return ValidateBlendFuncSeparatei(state, errors, entryPoint, buf, srcRGB, dstRGB, srcAlpha,
                                      dstAlpha);
}

bool ValidateBlendFunciOES(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLuint buf,
                           GLenum src,
                           GLenum dst)
{
    return ValidateBlendFunci(state, errors, entryPoint, buf, src, dst);
}

bool ValidateColorMaskiOES(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLuint index,
                           GLboolean r,
                           GLboolean g,
                           GLboolean b,
                           GLboolean a)
{
    return ValidateColorMaski(state, errors, entryPoint, index, r, g, b, a);
}

bool ValidateDisableiOES(const PrivateState &state,
                         ErrorSet *errors,
                         angle::EntryPoint entryPoint,
                         GLenum target,
                         GLuint index)
{
    return ValidateDisablei(state, errors, entryPoint, target, index);
}

bool ValidateEnableiOES(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLenum target,
                        GLuint index)
{
    return ValidateEnablei(state, errors, entryPoint, target, index);
}

bool ValidateIsEnablediOES(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLenum target,
                           GLuint index)
{
    return ValidateIsEnabledi(state, errors, entryPoint, target, index);
}

bool ValidateProvokingVertexANGLE(const PrivateState &state,
                                  ErrorSet *errors,
                                  angle::EntryPoint entryPoint,
                                  ProvokingVertexConvention provokeModePacked)
{
    switch (provokeModePacked)
    {
        case ProvokingVertexConvention::FirstVertexConvention:
        case ProvokingVertexConvention::LastVertexConvention:
            break;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProvokingVertex);
            return false;
    }

    return true;
}

bool ValidateGetInteger64vEXT(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLenum pname,
                              const GLint64 *data)
{
    return ValidateStateQuery(context, entryPoint, pname, data, nullptr);
}

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)
{
    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)
{
    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)
{
    UNIMPLEMENTED();
    return false;
}

bool ValidateCreateMemoryObjectsEXT(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    GLsizei n,
                                    const MemoryObjectID *memoryObjects)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               memoryObjects);
}

bool ValidateDeleteMemoryObjectsEXT(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    GLsizei n,
                                    const MemoryObjectID *memoryObjects)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               memoryObjects);
}

bool ValidateGetMemoryObjectParameterivEXT(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           MemoryObjectID memoryObject,
                                           GLenum pname,
                                           const GLint *params)
{
    const MemoryObject *memory = context->getMemoryObject(memoryObject);
    if (memory == nullptr)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryObject);
        return false;
    }

    if (!IsValidMemoryObjectParameter(context, entryPoint, pname))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
        return false;
    }

    return true;
}

bool ValidateGetUnsignedBytevEXT(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 GLenum pname,
                                 const GLubyte *data)
{
    UNIMPLEMENTED();
    return false;
}

bool ValidateGetUnsignedBytei_vEXT(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   GLenum target,
                                   GLuint index,
                                   const GLubyte *data)
{
    UNIMPLEMENTED();
    return false;
}

bool ValidateIsMemoryObjectEXT(const Context *context,
                               angle::EntryPoint entryPoint,
                               MemoryObjectID memoryObject)
{
    return true;
}

bool ValidateMemoryObjectParameterivEXT(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        MemoryObjectID memoryObject,
                                        GLenum pname,
                                        const GLint *params)
{
    const MemoryObject *memory = context->getMemoryObject(memoryObject);
    if (memory == nullptr)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryObject);
        return false;
    }

    if (memory->isImmutable())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kImmutableMemoryObject);
        return false;
    }

    if (!IsValidMemoryObjectParameter(context, entryPoint, pname))
    {
        ANGLE_VALIDATION_ERROR(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->getClientVersion() < ES_3_0)
    {
        return ValidateES2TexStorageParametersBase(context, entryPoint, target, levels,
                                                   internalFormat, width, height);
    }

    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)
{
    UNIMPLEMENTED();
    return false;
}

bool ValidateImportMemoryFdEXT(const Context *context,
                               angle::EntryPoint entryPoint,
                               MemoryObjectID memory,
                               GLuint64 size,
                               HandleType handleType,
                               GLint fd)
{
    switch (handleType)
    {
        case HandleType::OpaqueFd:
            break;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
            return false;
    }

    return true;
}

bool ValidateImportMemoryZirconHandleANGLE(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           MemoryObjectID memory,
                                           GLuint64 size,
                                           HandleType handleType,
                                           GLuint handle)
{
    switch (handleType)
    {
        case HandleType::ZirconVmo:
            break;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
            return false;
    }

    return true;
}

bool ValidateDeleteSemaphoresEXT(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 GLsizei n,
                                 const SemaphoreID *semaphores)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               semaphores);
}

bool ValidateGenSemaphoresEXT(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLsizei n,
                              const SemaphoreID *semaphores)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               semaphores);
}

bool ValidateGetSemaphoreParameterui64vEXT(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           SemaphoreID semaphore,
                                           GLenum pname,
                                           const GLuint64 *params)
{
    UNIMPLEMENTED();
    return false;
}

bool ValidateIsSemaphoreEXT(const Context *context,
                            angle::EntryPoint entryPoint,
                            SemaphoreID semaphore)
{
    return true;
}

bool ValidateSemaphoreParameterui64vEXT(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        SemaphoreID semaphore,
                                        GLenum pname,
                                        const GLuint64 *params)
{
    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)
{
    for (GLuint i = 0; i < numBufferBarriers; ++i)
    {
        if (!context->getBuffer(buffers[i]))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidBufferName);
            return false;
        }
    }

    for (GLuint i = 0; i < numTextureBarriers; ++i)
    {
        if (!context->getTexture(textures[i]))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
            return false;
        }
        if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
        {
            ANGLE_VALIDATION_ERROR(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)
{
    for (GLuint i = 0; i < numBufferBarriers; ++i)
    {
        if (!context->getBuffer(buffers[i]))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidBufferName);
            return false;
        }
    }

    for (GLuint i = 0; i < numTextureBarriers; ++i)
    {
        if (!context->getTexture(textures[i]))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
            return false;
        }
        if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageLayout);
            return false;
        }
    }

    return true;
}

bool ValidateImportSemaphoreFdEXT(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  SemaphoreID semaphore,
                                  HandleType handleType,
                                  GLint fd)
{
    switch (handleType)
    {
        case HandleType::OpaqueFd:
            break;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
            return false;
    }

    return true;
}

bool ValidateGetTexParameterIivOES(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   TextureType targetPacked,
                                   GLenum pname,
                                   const GLint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
}

bool ValidateGetTexParameterIuivOES(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    TextureType targetPacked,
                                    GLenum pname,
                                    const GLuint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
}

bool ValidateTexParameterIivOES(const Context *context,
                                angle::EntryPoint entryPoint,
                                TextureType targetPacked,
                                GLenum pname,
                                const GLint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, params);
}

bool ValidateTexParameterIuivOES(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 TextureType targetPacked,
                                 GLenum pname,
                                 const GLuint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, params);
}

bool ValidateGetSamplerParameterIivOES(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       SamplerID samplerPacked,
                                       SamplerParameter pnamePacked,
                                       const GLint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pnamePacked, params,
                                           nullptr);
}

bool ValidateGetSamplerParameterIuivOES(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        SamplerID samplerPacked,
                                        SamplerParameter pnamePacked,
                                        const GLuint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pnamePacked, params,
                                           nullptr);
}

bool ValidateSamplerParameterIivOES(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    SamplerID samplerPacked,
                                    SamplerParameter pnamePacked,
                                    const GLint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pnamePacked, params);
}

bool ValidateSamplerParameterIuivOES(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     SamplerID samplerPacked,
                                     SamplerParameter pnamePacked,
                                     const GLuint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pnamePacked, params);
}

bool ValidateGetSamplerParameterIivEXT(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       SamplerID samplerPacked,
                                       SamplerParameter pnamePacked,
                                       const GLint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pnamePacked, params,
                                           nullptr);
}

bool ValidateGetSamplerParameterIuivEXT(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        SamplerID samplerPacked,
                                        SamplerParameter pnamePacked,
                                        const GLuint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pnamePacked, params,
                                           nullptr);
}

bool ValidateGetTexParameterIivEXT(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   TextureType targetPacked,
                                   GLenum pname,
                                   const GLint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(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->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
}

bool ValidateSamplerParameterIivEXT(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    SamplerID samplerPacked,
                                    SamplerParameter pnamePacked,
                                    const GLint *param)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pnamePacked, param);
}

bool ValidateSamplerParameterIuivEXT(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     SamplerID samplerPacked,
                                     SamplerParameter pnamePacked,
                                     const GLuint *param)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pnamePacked, param);
}

bool ValidateTexParameterIivEXT(const Context *context,
                                angle::EntryPoint entryPoint,
                                TextureType targetPacked,
                                GLenum pname,
                                const GLint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, params);
}

bool ValidateTexParameterIuivEXT(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 TextureType targetPacked,
                                 GLenum pname,
                                 const GLuint *params)
{
    if (context->getClientVersion() < ES_3_0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
        return false;
    }

    return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, params);
}

bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
                                              angle::EntryPoint entryPoint,
                                              SemaphoreID semaphore,
                                              HandleType handleType,
                                              GLuint handle)
{
    switch (handleType)
    {
        case HandleType::ZirconEvent:
            break;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
            return false;
    }

    return true;
}

namespace
{
constexpr static GLbitfield kValidPLSUsages = GL_PIXEL_LOCAL_USAGE_ALWAYS_NONCOHERENT_BIT_ANGLE;

enum class PLSExpectedStatus
{
    Inactive,
    Active,
    Any
};

bool ValidatePLSCommon(const Context *context,
                       angle::EntryPoint entryPoint,
                       PLSExpectedStatus expectedStatus)
{
    Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
    if (expectedStatus != PLSExpectedStatus::Active)
    {
        // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is
        // bound to DRAW_FRAMEBUFFER.
        if (framebuffer->id().value == 0)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSDefaultFramebufferBound);
            return false;
        }
    }

    // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
    // in an interrupted state.
    const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
    if (pls != nullptr && pls->interruptCount() != 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSInterrupted);
        return false;
    }

    if (expectedStatus == PLSExpectedStatus::Active)
    {
        // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is zero.
        if (context->getState().getPixelLocalStorageActivePlanes() == 0)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSInactive);
            return false;
        }
    }
    else if (expectedStatus == PLSExpectedStatus::Inactive)
    {
        // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero.
        if (context->getState().getPixelLocalStorageActivePlanes() != 0)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSActive);
            return false;
        }
    }

    return true;
}

bool ValidatePLSCommon(const Context *context,
                       angle::EntryPoint entryPoint,
                       GLint plane,
                       PLSExpectedStatus expectedStatus)
{
    if (!ValidatePLSCommon(context, entryPoint, expectedStatus))
    {
        return false;
    }

    // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
    if (plane < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneLessThanZero);
        return false;
    }
    if (plane >= static_cast<GLint>(context->getCaps().maxPixelLocalStoragePlanes))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneOutOfRange);
        return false;
    }

    return true;
}

bool ValidateGetFramebufferPixelLocalStorageParameterBase(const Context *context,
                                                          angle::EntryPoint entryPoint,
                                                          GLint plane,
                                                          PlaneParameter pnamePacked,
                                                          const void *params,
                                                          GLsizei *outNumParams)
{
    if (ANGLE_UNLIKELY(context->getState().getDrawFramebuffer()->id().value == 0))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSDefaultFramebufferBound);
        return false;
    }

    if (ANGLE_UNLIKELY(plane < 0))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneLessThanZero);
        return false;
    }

    if (ANGLE_UNLIKELY(plane >= static_cast<GLint>(context->getCaps().maxPixelLocalStoragePlanes)))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneOutOfRange);
        return false;
    }

    if (ANGLE_UNLIKELY(pnamePacked == PlaneParameter::InvalidEnum))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kParameterNameUnknown);
        return false;
    }

    if (ANGLE_UNLIKELY(params == nullptr))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kParamsNULL);
        return false;
    }

    if (outNumParams != nullptr)
    {
        switch (pnamePacked)
        {
            case PlaneParameter::ClearValueFloat:
            case PlaneParameter::ClearValueInt:
            case PlaneParameter::ClearValueUnsignedInt:
                *outNumParams = 4;
                break;
            default:
                *outNumParams = 1;
                break;
        }
    }

    return true;
}

bool ValidateGetFramebufferPixelLocalStorageParameterRobustBase(const Context *context,
                                                                angle::EntryPoint entryPoint,
                                                                GLint plane,
                                                                PlaneParameter pnamePacked,
                                                                GLsizei paramCount,
                                                                const void *params)
{
    // Make sure ValidateGetFramebufferPixelLocalStorageParameterBase sets numParams
    GLsizei numParams = std::numeric_limits<GLsizei>::max();
    if (!ValidateGetFramebufferPixelLocalStorageParameterBase(context, entryPoint, plane,
                                                              pnamePacked, params, &numParams))
    {
        return false;
    }
    ASSERT(numParams != std::numeric_limits<GLsizei>::max());

    if (!ValidateRobustParamCount(context, entryPoint, paramCount, numParams))
    {
        return false;
    }

    return true;
}

bool ValidatePLSInternalformat(const Context *context,
                               angle::EntryPoint entryPoint,
                               GLenum internalformat)
{
    // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
    // X.2, or NONE.
    switch (internalformat)
    {
        case GL_RGBA8:
        case GL_RGBA8I:
        case GL_RGBA8UI:
        case GL_R32F:
        case GL_R32I:
        case GL_R32UI:
            return true;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kPLSInvalidInternalformat);
            return false;
    }
}

bool ValidatePLSTextureType(const Context *context,
                            angle::EntryPoint entryPoint,
                            Texture *tex,
                            size_t *textureDepth)
{
    // INVALID_OPERATION is generated if <backingtexture> is nonzero
    // and not of type TEXTURE_2D, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP,
    // or TEXTURE_CUBE_MAP_ARRAY.
    switch (tex->getType())
    {
        case TextureType::_2D:
            *textureDepth = 1;
            return true;
        case TextureType::_2DArray:
            *textureDepth = tex->getDepth(TextureTarget::_2DArray, 0);
            return true;
        case TextureType::CubeMap:
            *textureDepth = 6;
            return true;
        case TextureType::CubeMapArray:
            *textureDepth = tex->getDepth(TextureTarget::CubeMapArray, 0);
            return true;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSInvalidTextureType);
            return false;
    }
}

bool ValidatePLSActiveBlendFunc(const Context *context,
                                angle::EntryPoint entryPoint,
                                gl::BlendFactorType blendFunc)
{
    // INVALID_OPERATION is generated if BLEND_DST_ALPHA, BLEND_DST_RGB, BLEND_SRC_ALPHA, or
    // BLEND_SRC_RGB, for any draw buffer, is a blend function requiring the secondary color input,
    // as specified in EXT_blend_func_extended.
    ASSERT(context->getState().getExtensions().blendFuncExtendedEXT);
    switch (blendFunc)
    {
        case gl::BlendFactorType::Src1Color:
        case gl::BlendFactorType::OneMinusSrc1Color:
        case gl::BlendFactorType::Src1Alpha:
        case gl::BlendFactorType::OneMinusSrc1Alpha:
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSSecondaryBlendEnabled);
            return false;
        default:
            return true;
    }
}
bool ValidatePLSActiveBlendEquation(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    gl::BlendEquationType blendEquation)
{
    // INVALID_OPERATION is generated if BLEND_EQUATION_RGB and/or BLEND_EQUATION_ALPHA is an
    // advanced blend equation defined in KHR_blend_equation_advanced.
    ASSERT(context->getState().getExtensions().blendEquationAdvancedKHR ||
           context->getClientVersion() >= ES_3_2);
    switch (blendEquation)
    {
        case gl::BlendEquationType::Multiply:
        case gl::BlendEquationType::Screen:
        case gl::BlendEquationType::Overlay:
        case gl::BlendEquationType::Darken:
        case gl::BlendEquationType::Lighten:
        case gl::BlendEquationType::Colordodge:
        case gl::BlendEquationType::Colorburn:
        case gl::BlendEquationType::Hardlight:
        case gl::BlendEquationType::Softlight:
        case gl::BlendEquationType::Difference:
        case gl::BlendEquationType::Exclusion:
        case gl::BlendEquationType::HslHue:
        case gl::BlendEquationType::HslSaturation:
        case gl::BlendEquationType::HslColor:
        case gl::BlendEquationType::HslLuminosity:
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSAdvancedBlendEnabled);
            return false;
        default:
            return true;
    }
}

bool ValidatePLSLoadOperation(const Context *context, angle::EntryPoint entryPoint, GLenum loadop)
{
    // INVALID_ENUM is generated if <loadops>[0..<n>-1] is not one of the Load Operations enumerated
    // in Table X.1.
    switch (loadop)
    {
        case GL_LOAD_OP_ZERO_ANGLE:
        case GL_LOAD_OP_CLEAR_ANGLE:
        case GL_LOAD_OP_LOAD_ANGLE:
        case GL_DONT_CARE:
            return true;
        default:
            ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kPLSInvalidLoadOperation, loadop);
            return false;
    }
}

bool ValidatePLSStoreOperation(const Context *context, angle::EntryPoint entryPoint, GLenum storeop)
{
    // INVALID_ENUM is generated if <storeops>[0..PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE-1] is not
    // one of the Store Operations enumerated in Table X.2.
    switch (storeop)
    {
        case GL_STORE_OP_STORE_ANGLE:
        case GL_DONT_CARE:
            return true;
        default:
            ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kPLSInvalidStoreOperation, storeop);
            return false;
    }
}
}  // namespace

bool ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context *context,
                                                         angle::EntryPoint entryPoint,
                                                         GLint plane,
                                                         GLenum internalformat,
                                                         GLbitfield usage)
{
    if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
    {
        return false;
    }

    // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
    // X.2, or NONE.
    if (internalformat != GL_NONE)
    {
        if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
        {
            return false;
        }

        // INVALID_OPERATION is generated if <internalformat> is not NONE and not color-renderable.
        if (!context->getTextureCaps().get(internalformat).textureAttachment)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFormatNotRenderable);
            return false;
        }
    }

    if ((usage & kValidPLSUsages) != usage)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSInvalidUsage);
        return false;
    }

    return true;
}

bool ValidateFramebufferTexturePixelLocalStorageANGLE(const Context *context,
                                                      angle::EntryPoint entryPoint,
                                                      GLint plane,
                                                      TextureID backingtexture,
                                                      GLint level,
                                                      GLint layer,
                                                      GLbitfield usage)
{
    if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
    {
        return false;
    }

    if (backingtexture.value != 0)
    {
        Texture *tex = context->getTexture(backingtexture);

        // INVALID_OPERATION is generated if <backingtexture> is not the name of an existing
        // immutable texture object, or zero.
        if (!tex)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
            return false;
        }
        if (!tex->getImmutableFormat())
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsNotImmutable);
            return false;
        }

        // INVALID_OPERATION is generated if <backingtexture> is nonzero
        // and not of type GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP,
        // or GL_TEXTURE_CUBE_MAP_ARRAY.
        size_t textureDepth;
        if (!ValidatePLSTextureType(context, entryPoint, tex, &textureDepth))
        {
            return false;
        }

        // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> < 0.
        if (level < 0)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLevel);
            return false;
        }

        // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> >= the
        // immutable number of mipmap levels in <backingtexture>.
        if (static_cast<GLuint>(level) >= tex->getImmutableLevels())
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureLevelOutOfRange);
            return false;
        }

        // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> < 0.
        if (layer < 0)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLayer);
            return false;
        }

        // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> >= the immutable
        // number of texture layers in <backingtexture>.
        if ((size_t)layer >= textureDepth)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureLayerOutOfRange);
            return false;
        }

        // INVALID_ENUM is generated if <backingtexture> is nonzero and its internalformat is not
        // one of the acceptable values in Table X.2.
        ASSERT(tex->getImmutableFormat());
        GLenum internalformat = tex->getState().getBaseLevelDesc().format.info->internalFormat;
        if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
        {
            return false;
        }

        // INVALID_OPERATION is generated if <backingtexture> is nonzero and its internalformat
        // is not color-renderable.
        if (!context->getTextureCaps().get(internalformat).textureAttachment)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFormatNotRenderable);
            return false;
        }
    }

    if ((usage & kValidPLSUsages) != usage)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSInvalidUsage);
        return false;
    }

    return true;
}

bool ValidateFramebufferPixelLocalClearValuefvANGLE(const Context *context,
                                                    angle::EntryPoint entryPoint,
                                                    GLint plane,
                                                    const GLfloat[])
{
    return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
}

bool ValidateFramebufferPixelLocalClearValueivANGLE(const Context *context,
                                                    angle::EntryPoint entryPoint,
                                                    GLint plane,
                                                    const GLint[])
{
    return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
}

bool ValidateFramebufferPixelLocalClearValueuivANGLE(const Context *context,
                                                     angle::EntryPoint entryPoint,
                                                     GLint plane,
                                                     const GLuint[])
{
    return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
}

bool ValidateBeginPixelLocalStorageANGLE(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         GLsizei n,
                                         const GLenum loadops[])
{
    if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive))
    {
        return false;
    }

    const State &state             = context->getState();
    const Framebuffer *framebuffer = state.getDrawFramebuffer();

    // INVALID_OPERATION is generated if the value of SAMPLE_BUFFERS is 1 (i.e., if rendering to a
    // multisampled framebuffer).
    if (framebuffer->getSamples(context) != 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSMultisamplingEnabled);
        return false;
    }

    // INVALID_OPERATION is generated if DITHER is enabled.
    if (state.isDitherEnabled())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSDitherEnabled);
        return false;
    }

    // INVALID_OPERATION is generated if TRANSFORM_FEEDBACK_ACTIVE is true.
    if (state.isTransformFeedbackActive())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSTransformFeedbackActive);
        return false;
    }

    // INVALID_OPERATION is generated if QCOM_tiled_rendering is active.
    if (context->getPrivateState().isTiledRendering())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSTiledRenderingActive);
        return false;
    }

    // INVALID_OPERATION is generated if BLEND_DST_ALPHA, BLEND_DST_RGB, BLEND_SRC_ALPHA, or
    // BLEND_SRC_RGB, for any draw buffer, is a blend function requiring the secondary color input,
    // as specified in EXT_blend_func_extended.
    if (state.getExtensions().blendFuncExtendedEXT)
    {
        for (GLsizei i = 0; i < state.getCaps().maxDrawBuffers; ++i)
        {
            const BlendStateExt &blend = state.getBlendStateExt();
            if (!ValidatePLSActiveBlendFunc(context, entryPoint, blend.getDstAlphaIndexed(i)) ||
                !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getDstColorIndexed(i)) ||
                !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getSrcAlphaIndexed(i)) ||
                !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getSrcColorIndexed(i)))
            {
                return false;
            }
        }
    }

    // INVALID_OPERATION is generated if BLEND_EQUATION_RGB and/or BLEND_EQUATION_ALPHA is an
    // advanced blend equation defined in KHR_blend_equation_advanced.
    if (state.getExtensions().blendEquationAdvancedKHR || context->getClientVersion() >= ES_3_2)
    {
        if (!ValidatePLSActiveBlendEquation(context, entryPoint,
                                            state.getBlendStateExt().getEquationColorIndexed(0)) ||
            !ValidatePLSActiveBlendEquation(context, entryPoint,
                                            state.getBlendStateExt().getEquationAlphaIndexed(0)))
        {
            return false;
        }
    }
    // INVALID_VALUE is generated if <n> < 1 or <n> > MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
    if (n < 1)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlanesLessThanOne);
        return false;
    }
    if (n > static_cast<GLsizei>(context->getCaps().maxPixelLocalStoragePlanes))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlanesOutOfRange);
        return false;
    }

    // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
    // any color attachment point on or after:
    //
    //   COLOR_ATTACHMENT0 + MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE - <n>
    //
    const Caps &caps = context->getCaps();
    for (int i = caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - n; i < caps.maxDrawBuffers;
         ++i)
    {
        if (framebuffer->getColorAttachment(i))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION,
                                   kPLSMaxCombinedDrawBuffersAndPlanesExceded);
            return false;
        }
    }

    // INVALID_VALUE is generated if <loadops> is NULL.
    if (loadops == nullptr)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSLoadOpsNULL);
        return false;
    }

    const PixelLocalStorage *pls   = framebuffer->peekPixelLocalStorage();
    bool hasTextureBackedPLSPlanes = false;
    Extents textureBackedPLSExtents{};

    for (GLsizei i = 0; i < n; ++i)
    {
        // INVALID_ENUM is generated if <loadops>[0..<n>-1] is not one of the Load Operations
        // enumerated in Table X.1.
        if (!ValidatePLSLoadOperation(context, entryPoint, loadops[i]))
        {
            return false;
        }

        // INVALID_OPERATION is generated if a pixel local storage plane at index [0..<n>-1] is in a
        // deinitialized state.
        if (pls == nullptr || pls->getPlane(i).isDeinitialized())
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSEnablingDeinitializedPlane);
            return false;
        }

        // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage
        // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to
        // which it was bound is automatically converted to a memoryless plane of matching
        // internalformat.
        const PixelLocalStoragePlane &plane = pls->getPlane(i);

        Extents textureExtents;
        if (plane.getTextureImageExtents(context, &textureExtents))
        {
            // INVALID_OPERATION is generated if all enabled, texture-backed pixel local storage
            // planes do not have the same width and height.
            if (!hasTextureBackedPLSPlanes)
            {
                textureBackedPLSExtents   = textureExtents;
                hasTextureBackedPLSPlanes = true;
            }
            else if (textureExtents != textureBackedPLSExtents)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSMismatchedBackingTextureSizes);
                return false;
            }
        }
        else
        {
            // INVALID_OPERATION is generated if <loadops>[0..<n>-1] is LOAD_OP_LOAD_ANGLE and the
            // pixel local storage plane at that same index is memoryless.
            if (loadops[i] == GL_LOAD_OP_LOAD_ANGLE)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSKeepingMemorylessPlane);
                return false;
            }
        }

        if (!plane.isMemoryless())
        {
            ASSERT(plane.getTextureID() != TextureID());

            const ImageIndex &planeImageIdx = plane.getTextureImageIndex();
            ASSERT(planeImageIdx.getLayerCount() == 1);
            ASSERT(planeImageIdx.getLevelIndex() >= 0);

            // INVALID_OPERATION is generated if, for any active backing texture, the mipmap level
            // bound to pixel local storage is outside the effective base/max range of that texture.
            const Texture *const backingTexture = plane.getBackingTexture(context);
            if (planeImageIdx.getLevelIndex() <
                    static_cast<GLint>(backingTexture->getState().getEffectiveBaseLevel()) ||
                planeImageIdx.getLevelIndex() >
                    static_cast<GLint>(backingTexture->getState().getEffectiveMaxLevel()))
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSLevelIndexOutOfRange);
                return false;
            }

            // INVALID_OPERATION is generated if a single texture slice is bound to more than one
            // active pixel local storage plane.
            for (GLsizei j = i + 1; j < n; ++j)
            {
                const PixelLocalStoragePlane &otherPlane = pls->getPlane(j);
                if (!otherPlane.isMemoryless() &&
                    plane.getTextureID() == otherPlane.getTextureID() &&
                    planeImageIdx == otherPlane.getTextureImageIndex())
                {
                    ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSSingleTexImageMultiplePlanes);
                    return false;
                }
            }

            // INVALID_OPERATION is generated if a single texture slice is simultaneously bound to
            // an active pixel local storage plane and attached to an enabled drawbuffer.
            const GLuint maxDrawBuffersWithPLSPlanes = std::min<GLuint>(
                caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - n, caps.maxDrawBuffers);
            for (GLuint j = 0; j < maxDrawBuffersWithPLSPlanes; ++j)
            {
                if (framebuffer->getDrawBufferMask().test(j) &&
                    framebuffer->getColorAttachment(j)->isTextureWithId(plane.getTextureID()))
                {
                    // Compare the ImageIndex values for the PLS plane and framebuffer attachment
                    // manually; the framebuffer uses a layer index of -1 for texture2d attachments,
                    // whereas PLS uses a layer index of 0.
                    const ImageIndex &attachmentImageIdx =
                        framebuffer->getColorAttachment(j)->getTextureImageIndex();
                    ASSERT(attachmentImageIdx.getLayerCount() == 1);
                    if (planeImageIdx.getType() == attachmentImageIdx.getType() &&
                        planeImageIdx.getLevelIndex() == attachmentImageIdx.getLevelIndex() &&
                        planeImageIdx.getLayerIndex() ==
                            std::max(attachmentImageIdx.getLayerIndex(), 0))
                    {
                        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
                                               kPLSSingleTexImagePLSAndAttachment);
                        return false;
                    }
                }
            }
        }
    }

    const FramebufferAttachment *firstAttachment =
        framebuffer->getState().getFirstNonNullAttachment();
    if (firstAttachment)
    {
        // INVALID_OPERATION is generated if the draw framebuffer has other attachments, and its
        // enabled, texture-backed pixel local storage planes do not have identical dimensions
        // with the rendering area.
        if (hasTextureBackedPLSPlanes &&
            textureBackedPLSExtents != framebuffer->getState().getAttachmentExtentsIntersection())
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSDimensionsDontMatchRenderingArea);
            return false;
        }
    }
    else
    {
        // INVALID_OPERATION is generated if the draw framebuffer has no attachments and no
        // enabled, texture-backed pixel local storage planes.
        if (!hasTextureBackedPLSPlanes)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSNoAttachmentsNoTextureBacked);
            return false;
        }
    }

    // INVALID_OPERATION is generated if color attachment zero is present, but draw buffer zero is
    // disabled.
    if (framebuffer->getColorAttachment(0) != nullptr && !framebuffer->getDrawBufferMask().test(0))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
                               kPLSColorAttachment0PresentButDrawBufferDisabled);
        return false;
    }

    return true;
}

bool ValidateEndPixelLocalStorageANGLE(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLsizei n,
                                       const GLenum storeops[])
{
    if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active))
    {
        return false;
    }

    // INVALID_VALUE is generated if <n> != PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE.
    if (n != context->getState().getPixelLocalStorageActivePlanes())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSNNotEqualActivePlanes);
        return false;
    }

    // INVALID_ENUM is generated if <storeops>[0..PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE-1] is not
    // one of the Store Operations enumerated in Table X.2.
    for (GLsizei i = 0; i < n; ++i)
    {
        if (!ValidatePLSStoreOperation(context, entryPoint, storeops[i]))
        {
            return false;
        }
    }

    return true;
}

bool ValidateEndPixelLocalStorageImplicitANGLE(const Context *context, angle::EntryPoint entryPoint)
{
    // The entry point for implicitly ending PLS deliberately does not generate GL errors.
    return true;
}

bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint)
{
    return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active);
}

bool ValidateFramebufferPixelLocalStorageInterruptANGLE(const Context *context,
                                                        angle::EntryPoint entryPoint)
{
    // INVALID_FRAMEBUFFER_OPERATION is generated if the current interrupt count on the draw
    // framebuffer is greater than or equal to 255.
    const PixelLocalStorage *pls =
        context->getState().getDrawFramebuffer()->peekPixelLocalStorage();
    if (pls != nullptr && pls->interruptCount() >= 255)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSInterruptOverflow);
        return false;
    }

    return true;
}

bool ValidateFramebufferPixelLocalStorageRestoreANGLE(const Context *context,
                                                      angle::EntryPoint entryPoint)
{
    // This command is ignored when the default framebuffer object name 0 is bound.
    const Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
    if (context->getState().getDrawFramebuffer()->id().value == 0)
    {
        return true;
    }

    // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
    // not in an interrupted state.
    const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
    if (pls == nullptr || pls->interruptCount() == 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSNotInterrupted);
        return false;
    }

    return true;
}

bool ValidateGetFramebufferPixelLocalStorageParameterfvANGLE(const Context *context,
                                                             angle::EntryPoint entryPoint,
                                                             GLint plane,
                                                             PlaneParameter pnamePacked,
                                                             const GLfloat *params)
{
    return ValidateGetFramebufferPixelLocalStorageParameterBase(context, entryPoint, plane,
                                                                pnamePacked, params, nullptr);
}

bool ValidateGetFramebufferPixelLocalStorageParameterivANGLE(const Context *context,
                                                             angle::EntryPoint entryPoint,
                                                             GLint plane,
                                                             PlaneParameter pnamePacked,
                                                             const GLint *params)
{
    return ValidateGetFramebufferPixelLocalStorageParameterBase(context, entryPoint, plane,
                                                                pnamePacked, params, nullptr);
}

bool ValidateGetFramebufferPixelLocalStorageParameteruivANGLE(const Context *context,
                                                              angle::EntryPoint entryPoint,
                                                              GLint plane,
                                                              PlaneParameter pnamePacked,
                                                              const GLuint *params)
{
    return ValidateGetFramebufferPixelLocalStorageParameterBase(context, entryPoint, plane,
                                                                pnamePacked, params, nullptr);
}

bool ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(const Context *context,
                                                                   angle::EntryPoint entryPoint,
                                                                   GLint plane,
                                                                   PlaneParameter pnamePacked,
                                                                   GLsizei paramCount,
                                                                   const GLsizei *length,
                                                                   const GLfloat *params)
{
    return ValidateGetFramebufferPixelLocalStorageParameterRobustBase(
        context, entryPoint, plane, pnamePacked, paramCount, params);
}

bool ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(const Context *context,
                                                                   angle::EntryPoint entryPoint,
                                                                   GLint plane,
                                                                   PlaneParameter pnamePacked,
                                                                   GLsizei paramCount,
                                                                   const GLsizei *length,
                                                                   const GLint *params)
{
    return ValidateGetFramebufferPixelLocalStorageParameterRobustBase(
        context, entryPoint, plane, pnamePacked, paramCount, params);
}

bool ValidateGetFramebufferPixelLocalStorageParameteruivRobustANGLE(const Context *context,
                                                                    angle::EntryPoint entryPoint,
                                                                    GLint plane,
                                                                    PlaneParameter pnamePacked,
                                                                    GLsizei paramCount,
                                                                    const GLsizei *length,
                                                                    const GLuint *params)
{
    return ValidateGetFramebufferPixelLocalStorageParameterRobustBase(
        context, entryPoint, plane, pnamePacked, paramCount, params);
}

bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint)
{
    return true;
}

bool ValidatePatchParameteriEXT(const PrivateState &state,
                                ErrorSet *errors,
                                angle::EntryPoint entryPoint,
                                GLenum pname,
                                GLint value)
{
    return ValidatePatchParameteriBase(state, errors, entryPoint, pname, value);
}

bool ValidatePatchParameteriOES(const PrivateState &state,
                                ErrorSet *errors,
                                angle::EntryPoint entryPoint,
                                GLenum pname,
                                GLint value)
{
    return ValidatePatchParameteriBase(state, errors, entryPoint, pname, value);
}

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 (!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)
    {
        ANGLE_VALIDATION_ERROR(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)
    {
        ANGLE_VALIDATION_ERROR(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))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTarget);
        return false;
    }

    if (size <= 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNonPositiveSize);
        return false;
    }

    const Limitations &limitations = context->getLimitations();
    if (size > limitations.bufferSizeLimit)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferSizeLimitation);
        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)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
        return false;
    }

    if (((flags & GL_MAP_PERSISTENT_BIT_EXT) != 0) &&
        ((flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
        return false;
    }

    if (((flags & GL_MAP_COHERENT_BIT_EXT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT_EXT) == 0))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
        return false;
    }

    Buffer *buffer = context->getState().getTargetBuffer(targetPacked);

    if (buffer == nullptr)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
        return false;
    }

    if (buffer->isImmutable())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferImmutable);
        return false;
    }

    return true;
}

// GL_EXT_clear_texture
bool ValidateClearTexImageEXT(const Context *context,
                              angle::EntryPoint entryPoint,
                              TextureID texturePacked,
                              GLint level,
                              GLenum format,
                              GLenum type,
                              const void *data)
{
    return ValidateClearTexImageCommon(context, entryPoint, texturePacked, level, std::nullopt,
                                       format, type, data);
}

bool ValidateClearTexSubImageEXT(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 TextureID texturePacked,
                                 GLint level,
                                 GLint xoffset,
                                 GLint yoffset,
                                 GLint zoffset,
                                 GLsizei width,
                                 GLsizei height,
                                 GLsizei depth,
                                 GLenum format,
                                 GLenum type,
                                 const void *data)
{
    return ValidateClearTexImageCommon(context, entryPoint, texturePacked, level,
                                       Box(xoffset, yoffset, zoffset, width, height, depth), format,
                                       type, data);
}

// GL_EXT_clip_control
bool ValidateClipControlEXT(const PrivateState &state,
                            ErrorSet *errors,
                            angle::EntryPoint entryPoint,
                            ClipOrigin originPacked,
                            ClipDepthMode depthPacked)
{
    if (originPacked == ClipOrigin::InvalidEnum)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidOriginEnum);
        return false;
    }

    if (depthPacked == ClipDepthMode::InvalidEnum)
    {
        errors->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)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExternalBufferInvalidOffset);
        return false;
    }

    if (clientBuffer == nullptr && size > 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kClientBufferInvalid);
        return false;
    }

    const Limitations &limitations = context->getLimitations();
    if (size > limitations.bufferSizeLimit)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kBufferSizeLimitation);
        return false;
    }

    return true;
}

// GL_EXT_fragment_shading_rate
bool ValidateFramebufferShadingRateEXT(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLenum target,
                                       GLenum attachment,
                                       GLuint texture,
                                       GLint baseLayer,
                                       GLsizei numLayers,
                                       GLsizei texelWidth,
                                       GLsizei texelHeight)
{
    return false;
}

bool ValidateGetFragmentShadingRatesEXT(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        GLsizei samples,
                                        GLsizei maxCount,
                                        const GLsizei *count,
                                        const GLenum *shadingRates)
{
    // If a negative number is provided where an argument of type sizei or
    // sizeiptr is specified, an INVALID_VALUE error is generated.
    if ((samples < 0) || (maxCount < 0))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
        return false;
    }
    return true;
}

bool ValidateShadingRateEXT(const PrivateState &state,
                            ErrorSet *errors,
                            angle::EntryPoint entryPoint,
                            ShadingRate ratePacked)
{
    // INVALID_ENUM is generated by ShadingRateEXT if <rate> is not a valid shading rate.
    if (ratePacked == gl::ShadingRate::Undefined || ratePacked == gl::ShadingRate::InvalidEnum)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingRate);
        return false;
    }

    return true;
}

bool ValidateShadingRateCombinerOpsEXT(const PrivateState &state,
                                       ErrorSet *errors,
                                       angle::EntryPoint entryPoint,
                                       CombinerOp combinerOp0Packed,
                                       CombinerOp combinerOp1Packed)
{

    // An INVALID_ENUM error is generated if <combinerOp0>/<combinerOp1> is not
    // FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT,
    // FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT,
    // FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_EXT,
    // FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT or
    // FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_EXT
    if (combinerOp0Packed == gl::CombinerOp::Undefined ||
        combinerOp0Packed == gl::CombinerOp::InvalidEnum ||
        combinerOp1Packed == gl::CombinerOp::Undefined ||
        combinerOp1Packed == gl::CombinerOp::InvalidEnum)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingCombinerOp);
        return false;
    }

    // An INVALID_OPERATION error is generated if the value of
    // FRAGMENT_SHADING_RATE_NON_TRIVIAL_COMBINERS_SUPPORTED_EXT
    // is FALSE and <combinerOp0>/<combinerOp1> is not
    // FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT or
    // FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT
    if (!state.getCaps()
             .fragmentShadingRateProperties.fragmentShadingRateNonTrivialCombinersSupport)
    {
        if ((combinerOp0Packed != gl::CombinerOp::Keep &&
             combinerOp0Packed != gl::CombinerOp::Replace) ||
            (combinerOp1Packed != gl::CombinerOp::Keep &&
             combinerOp1Packed != gl::CombinerOp::Replace))
        {
            errors->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShadingCombinerOp);
            return false;
        }
    }

    // If GL_EXT_fragment_shading_rate_primitive is not supported
    // An INVALID_OPERATION error is generated if <combinerOp0> is not
    // FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT
    if (!state.getExtensions().fragmentShadingRatePrimitiveEXT)
    {
        if (combinerOp0Packed != gl::CombinerOp::Keep)
        {
            errors->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShadingCombinerOp);
            return false;
        }
    }

    // If GL_EXT_fragment_shading_rate_attachment is not supported
    // An INVALID_OPERATION error is generated if <combinerOp1> is not
    // FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT
    if (!state.getExtensions().fragmentShadingRateAttachmentEXT)
    {
        if (combinerOp1Packed != gl::CombinerOp::Keep)
        {
            errors->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShadingCombinerOp);
            return false;
        }
    }

    return true;
}

// GL_ANGLE_polygon_mode
bool ValidatePolygonModeANGLE(const PrivateState &state,
                              ErrorSet *errors,
                              angle::EntryPoint entryPoint,
                              GLenum face,
                              PolygonMode modePacked)
{
    if (face != GL_FRONT_AND_BACK)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
        return false;
    }

    if (modePacked == PolygonMode::Point || modePacked == PolygonMode::InvalidEnum)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPolygonMode);
        return false;
    }

    return true;
}

// GL_NV_polygon_mode
bool ValidatePolygonModeNV(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLenum face,
                           PolygonMode modePacked)
{
    if (face != GL_FRONT_AND_BACK)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
        return false;
    }

    if (modePacked == PolygonMode::InvalidEnum)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPolygonMode);
        return false;
    }

    return true;
}

// GL_EXT_polygon_offset_clamp
bool ValidatePolygonOffsetClampEXT(const PrivateState &state,
                                   ErrorSet *errors,
                                   angle::EntryPoint entryPoint,
                                   GLfloat factor,
                                   GLfloat units,
                                   GLfloat clamp)
{
    return true;
}

// GL_EXT_primitive_bounding_box
bool ValidatePrimitiveBoundingBoxEXT(const PrivateState &state,
                                     ErrorSet *errors,
                                     angle::EntryPoint entryPoint,
                                     GLfloat minX,
                                     GLfloat minY,
                                     GLfloat minZ,
                                     GLfloat minW,
                                     GLfloat maxX,
                                     GLfloat maxY,
                                     GLfloat maxZ,
                                     GLfloat maxW)
{
    return true;
}

// GL_OES_primitive_bounding_box
bool ValidatePrimitiveBoundingBoxOES(const PrivateState &state,
                                     ErrorSet *errors,
                                     angle::EntryPoint entryPoint,
                                     GLfloat minX,
                                     GLfloat minY,
                                     GLfloat minZ,
                                     GLfloat minW,
                                     GLfloat maxX,
                                     GLfloat maxY,
                                     GLfloat maxZ,
                                     GLfloat maxW)
{
    return true;
}

// GL_OES_texture_storage_multisample_2d_array
bool ValidateTexStorage3DMultisampleOES(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        TextureType target,
                                        GLsizei samples,
                                        GLenum internalformat,
                                        GLsizei width,
                                        GLsizei height,
                                        GLsizei depth,
                                        GLboolean fixedsamplelocations)
{
    return ValidateTexStorage3DMultisampleBase(context, entryPoint, target, samples, internalformat,
                                               width, height, depth);
}

// GL_EXT_separate_shader_objects
bool ValidateActiveShaderProgramEXT(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    ProgramPipelineID pipelinePacked,
                                    ShaderProgramID programPacked)
{
    return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
}

bool ValidateBindProgramPipelineEXT(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    ProgramPipelineID pipelinePacked)
{
    return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
}

bool ValidateCreateShaderProgramvEXT(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     ShaderType typePacked,
                                     GLsizei count,
                                     const GLchar *const *strings)
{
    return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
}

bool ValidateDeleteProgramPipelinesEXT(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLsizei n,
                                       const ProgramPipelineID *pipelinesPacked)
{
    return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
}

bool ValidateGenProgramPipelinesEXT(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    GLsizei n,
                                    const ProgramPipelineID *pipelinesPacked)
{
    return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
}

bool ValidateGetProgramPipelineInfoLogEXT(const Context *context,
                                          angle::EntryPoint entryPoint,
                                          ProgramPipelineID pipelinePacked,
                                          GLsizei bufSize,
                                          const GLsizei *length,
                                          const GLchar *infoLog)
{
    return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
                                                 length, infoLog);
}

bool ValidateGetProgramPipelineivEXT(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     ProgramPipelineID pipelinePacked,
                                     GLenum pname,
                                     const GLint *params)
{
    return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
}

bool ValidateIsProgramPipelineEXT(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ProgramPipelineID pipelinePacked)
{
    return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
}

bool ValidateProgramParameteriEXT(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID programPacked,
                                  GLenum pname,
                                  GLint value)
{
    return ValidateProgramParameteriBase(context, entryPoint, programPacked, pname, value);
}

bool ValidateProgramUniform1fEXT(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 ShaderProgramID programPacked,
                                 UniformLocation locationPacked,
                                 GLfloat v0)
{
    return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
}

bool ValidateProgramUniform1fvEXT(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID programPacked,
                                  UniformLocation locationPacked,
                                  GLsizei count,
                                  const GLfloat *value)
{
    return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
                                         value);
}

bool ValidateProgramUniform1iEXT(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 ShaderProgramID programPacked,
                                 UniformLocation locationPacked,
                                 GLint v0)
{
    return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
}

bool ValidateProgramUniform1ivEXT(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID programPacked,
                                  UniformLocation locationPacked,
                                  GLsizei count,
                                  const GLint *value)
{
    return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
                                         value);
}

bool ValidateProgramUniform1uiEXT(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID programPacked,
                                  UniformLocation locationPacked,
                                  GLuint v0)
{
    return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
}

bool ValidateProgramUniform1uivEXT(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID programPacked,
                                   UniformLocation locationPacked,
                                   GLsizei count,
                                   const GLuint *value)
{
    return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
                                          value);
}

bool ValidateProgramUniform2fEXT(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 ShaderProgramID programPacked,
                                 UniformLocation locationPacked,
                                 GLfloat v0,
                                 GLfloat v1)
{
    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)
{
    return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
                                         value);
}

bool ValidateProgramUniform2iEXT(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 ShaderProgramID programPacked,
                                 UniformLocation locationPacked,
                                 GLint v0,
                                 GLint v1)
{
    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)
{
    return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
                                         value);
}

bool ValidateProgramUniform2uiEXT(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID programPacked,
                                  UniformLocation locationPacked,
                                  GLuint v0,
                                  GLuint v1)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
                                                 count, transpose, value);
}

bool ValidateUseProgramStagesEXT(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 ProgramPipelineID pipelinePacked,
                                 GLbitfield stages,
                                 ShaderProgramID programPacked)
{
    return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
}

bool ValidateValidateProgramPipelineEXT(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        ProgramPipelineID pipelinePacked)
{
    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 (bufSize < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
        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 (length < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLength);
        return false;
    }

    return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
}

bool ValidateEGLImageTargetTexStorageEXT(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         GLenum target,
                                         egl::ImageID image,
                                         const GLint *attrib_list)
{
    gl::TextureType targetType = FromGLenum<TextureType>(target);
    switch (targetType)
    {
        case TextureType::External:
            if (!context->getExtensions().EGLImageExternalOES)
            {
                ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(targetType));
                return false;
            }
            break;
        case TextureType::CubeMapArray:
            if (!context->getExtensions().textureCubeMapArrayAny() &&
                context->getClientVersion() < ES_3_2)
            {
                ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(targetType));
                return false;
            }
            break;
        case TextureType::_2D:
        case TextureType::_2DArray:
        case TextureType::_3D:
        case TextureType::CubeMap:
            break;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
            return false;
    }

    // Validate egl source image is valid
    egl::Image *imageObject = context->getDisplay()->getImage(image);
    if (!ValidateEGLImageObject(context, entryPoint, targetType, image))
    {
        return false;
    }

    if (attrib_list != nullptr)
    {
        for (const GLint *attrib = attrib_list; attrib[0] != GL_NONE; attrib += 2)
        {
            switch (attrib[0])
            {
                case GL_SURFACE_COMPRESSION_EXT:
                    switch (attrib[1])
                    {
                        case GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT:
                            if (imageObject->isFixedRatedCompression(context))
                            {
                                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kAttributeNotMatch);
                                return false;
                            }
                            break;
                        case GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT:
                            break;
                        default:
                            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kAttributeNotValid);
                            return false;
                    }
                    break;
                default:
                    ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kAttributeNotValid);
                    return false;
            }
        }
    }

    GLsizei levelCount    = imageObject->getLevelCount();
    Extents size          = imageObject->getExtents();
    GLsizei width         = static_cast<GLsizei>(size.width);
    GLsizei height        = static_cast<GLsizei>(size.height);
    GLsizei depth         = static_cast<GLsizei>(size.depth);
    GLenum internalformat = imageObject->getFormat().info->sizedInternalFormat;

    if (width < 1 || height < 1 || depth < 1 || levelCount < 1)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
        return false;
    }

    if (!ValidateES3TexStorageParametersLevel(context, entryPoint, targetType, levelCount, width,
                                              height, depth))
    {
        // Error already generated.
        return false;
    }

    if (targetType == TextureType::External)
    {
        const Caps &caps = context->getCaps();
        if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
            return false;
        }
    }
    else if (!ValidateES3TexStorageParametersExtent(context, entryPoint, targetType, levelCount,
                                                    width, height, depth))
    {
        // Error already generated.
        return false;
    }

    if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, targetType))
    {
        // Error already generated.
        return false;
    }

    if (!ValidateES3TexStorageParametersFormat(context, entryPoint, targetType, levelCount,
                                               internalformat, width, height, depth))
    {
        // Error already generated.
        return false;
    }

    return true;
}

bool ValidateAcquireTexturesANGLE(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  GLuint numTextures,
                                  const TextureID *textures,
                                  const GLenum *layouts)
{
    for (GLuint i = 0; i < numTextures; ++i)
    {
        if (!context->getTexture(textures[i]))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
            return false;
        }
        if (!IsValidImageLayout(FromGLenum<ImageLayout>(layouts[i])))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageLayout);
            return false;
        }
    }

    return true;
}

bool ValidateReleaseTexturesANGLE(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  GLuint numTextures,
                                  const TextureID *textures,
                                  const GLenum *layouts)
{
    for (GLuint i = 0; i < numTextures; ++i)
    {
        if (!context->getTexture(textures[i]))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
            return false;
        }
    }

    return true;
}

bool ValidateFramebufferParameteriMESA(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLenum target,
                                       GLenum pname,
                                       GLint param)
{
    if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
        return false;
    }
    return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param);
}

bool ValidateGetFramebufferParameterivMESA(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           GLenum target,
                                           GLenum pname,
                                           const GLint *params)
{
    if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
        return false;
    }
    return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params);
}

// GL_AMD_performance_monitor
bool ValidateBeginPerfMonitorAMD(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 GLuint monitor)
{
    return true;
}

bool ValidateDeletePerfMonitorsAMD(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   GLsizei n,
                                   const GLuint *monitors)
{
    // Note: ANGLE does not really create monitor objects or track ids.
    return true;
}

bool ValidateEndPerfMonitorAMD(const Context *context, angle::EntryPoint entryPoint, GLuint monitor)
{
    if (!context->getState().isPerfMonitorActive())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPerfMonitorNotActive);
        return false;
    }

    return true;
}

bool ValidateGenPerfMonitorsAMD(const Context *context,
                                angle::EntryPoint entryPoint,
                                GLsizei n,
                                const GLuint *monitors)
{
    return true;
}

bool ValidateGetPerfMonitorCounterDataAMD(const Context *context,
                                          angle::EntryPoint entryPoint,
                                          GLuint monitor,
                                          GLenum pname,
                                          GLsizei dataSize,
                                          const GLuint *data,
                                          const GLint *bytesWritten)
{
    if (monitor != 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitor);
        return false;
    }

    switch (pname)
    {
        case GL_PERFMON_RESULT_AVAILABLE_AMD:
        case GL_PERFMON_RESULT_SIZE_AMD:
        case GL_PERFMON_RESULT_AMD:
            break;

        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
            return false;
    }

    return true;
}

bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context,
                                          angle::EntryPoint entryPoint,
                                          GLuint group,
                                          GLuint counter,
                                          GLenum pname,
                                          const void *data)
{
    const angle::PerfMonitorCounterGroupsInfo &groups = context->getPerfMonitorCounterGroups();

    if (group >= groups.size())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
        return false;
    }

    if (counter >= groups[group].counters.size())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
        return false;
    }

    switch (pname)
    {
        case GL_COUNTER_TYPE_AMD:
        case GL_COUNTER_RANGE_AMD:
            break;

        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
            return false;
    }

    return true;
}

bool ValidateGetPerfMonitorCounterStringAMD(const Context *context,
                                            angle::EntryPoint entryPoint,
                                            GLuint group,
                                            GLuint counter,
                                            GLsizei bufSize,
                                            const GLsizei *length,
                                            const GLchar *counterString)
{
    const angle::PerfMonitorCounterGroupsInfo &groups = context->getPerfMonitorCounterGroups();

    if (group >= groups.size())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
        return false;
    }

    if (counter >= groups[group].counters.size())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
        return false;
    }

    return true;
}

bool ValidateGetPerfMonitorCountersAMD(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLuint group,
                                       const GLint *numCounters,
                                       const GLint *maxActiveCounters,
                                       GLsizei counterSize,
                                       const GLuint *counters)
{
    const angle::PerfMonitorCounterGroupsInfo &groups = context->getPerfMonitorCounterGroups();

    if (group >= groups.size())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
        return false;
    }

    return true;
}

bool ValidateGetPerfMonitorGroupStringAMD(const Context *context,
                                          angle::EntryPoint entryPoint,
                                          GLuint group,
                                          GLsizei bufSize,
                                          const GLsizei *length,
                                          const GLchar *groupString)
{
    const angle::PerfMonitorCounterGroupsInfo &groups = context->getPerfMonitorCounterGroups();

    if (group >= groups.size())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
        return false;
    }

    return true;
}

bool ValidateGetPerfMonitorGroupsAMD(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     const GLint *numGroups,
                                     GLsizei groupsSize,
                                     const GLuint *groups)
{
    return true;
}

bool ValidateSelectPerfMonitorCountersAMD(const Context *context,
                                          angle::EntryPoint entryPoint,
                                          GLuint monitor,
                                          GLboolean enable,
                                          GLuint group,
                                          GLint numCounters,
                                          const GLuint *counterList)
{
    UNIMPLEMENTED();
    return false;
}

bool ValidateShadingRateQCOM(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             ShadingRate ratePacked)
{
    // Allowed in the <rate> parameter in ShadingRateQCOM:
    // SHADING_RATE_1X1_PIXELS_QCOM
    // SHADING_RATE_1X2_PIXELS_QCOM
    // SHADING_RATE_2X1_PIXELS_QCOM
    // SHADING_RATE_2X2_PIXELS_QCOM
    // SHADING_RATE_4X2_PIXELS_QCOM
    // SHADING_RATE_4X4_PIXELS_QCOM
    switch (ratePacked)
    {
        case gl::ShadingRate::_1x1:
        case gl::ShadingRate::_1x2:
        case gl::ShadingRate::_2x1:
        case gl::ShadingRate::_2x2:
        case gl::ShadingRate::_4x2:
        case gl::ShadingRate::_4x4:
            return true;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingRate);
            return false;
    }
}

bool ValidateLogicOpANGLE(const PrivateState &state,
                          ErrorSet *errors,
                          angle::EntryPoint entryPoint,
                          LogicalOperation opcodePacked)
{
    return ValidateLogicOpCommon(state, errors, entryPoint, opcodePacked);
}

bool ValidateFramebufferFoveationConfigQCOM(const Context *context,
                                            angle::EntryPoint entryPoint,
                                            FramebufferID framebufferPacked,
                                            GLuint numLayers,
                                            GLuint focalPointsPerLayer,
                                            GLuint requestedFeatures,
                                            const GLuint *providedFeatures)
{
    Framebuffer *framebuffer = context->getFramebuffer(framebufferPacked);

    // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'fbo' is not a valid
    // framebuffer.
    if (framebuffer == nullptr)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferName);
        return false;
    }

    // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'numLayers' is greater than
    // GL_MAX_ARRAY_TEXTURE_LAYERS - 1.
    if (numLayers > static_cast<GLuint>(context->getState().getCaps().maxArrayTextureLayers) - 1)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationLayersExceedMaxArrayLayers);
        return false;
    }

    // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'numFocalPoints' is greater
    // than implementation can support.
    if (focalPointsPerLayer > gl::IMPLEMENTATION_MAX_FOCAL_POINTS)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
        return false;
    }

    // INVALID_OPERATION is generated by FramebufferFoveationConfigQCOM if it is called for a fbo
    // that has already been cofigured for foveated rendering.
    if (framebuffer->isFoveationConfigured())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationAlreadyConfigured);
        return false;
    }

    return true;
}

bool ValidateFramebufferFoveationParametersQCOM(const Context *context,
                                                angle::EntryPoint entryPoint,
                                                FramebufferID framebufferPacked,
                                                GLuint layer,
                                                GLuint focalPoint,
                                                GLfloat focalX,
                                                GLfloat focalY,
                                                GLfloat gainX,
                                                GLfloat gainY,
                                                GLfloat foveaArea)
{
    Framebuffer *framebuffer = context->getFramebuffer(framebufferPacked);

    // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'fbo' is not a valid
    // framebuffer.
    if (framebuffer == nullptr)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferName);
        return false;
    }

    // INVALID_OPERATION is generated by FramebufferFoveationParametersQCOM if 'fbo' has not been
    // configured for foveated rendering.
    if (!framebuffer->isFoveationConfigured())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFramebufferFoveationNotConfigured);
        return false;
    }

    // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'layer' is greater than
    // or equal to the numLayers that the fbo was previously configured for in
    // FramebufferFoveationConfigQCOM.
    if (layer >= gl::IMPLEMENTATION_MAX_NUM_LAYERS)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationLayersExceedMaxArrayLayers);
        return false;
    }

    // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'numFocalPoints' is
    // greater than implementation can support. INVALID_OPERATION is generated by
    if (focalPoint >= gl::IMPLEMENTATION_MAX_FOCAL_POINTS)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
        return false;
    }
    return true;
}

bool ValidateTextureFoveationParametersQCOM(const Context *context,
                                            angle::EntryPoint entryPoint,
                                            TextureID texturePacked,
                                            GLuint layer,
                                            GLuint focalPoint,
                                            GLfloat focalX,
                                            GLfloat focalY,
                                            GLfloat gainX,
                                            GLfloat gainY,
                                            GLfloat foveaArea)
{
    Texture *texture = context->getTexture(texturePacked);

    // INVALID_VALUE is generated by TextureFoveationParametersQCOM if 'texture' is not a valid
    // texture object.
    if (texture == nullptr)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
        return false;
    }

    // INVALID_OPERATION is generated by TextureFoveationParametersQCOM if 'texture' has not been
    // set as foveated. i.e. 'texture's parameter TEXTURE_FOVEATED_FEATURE_BITS_QCOM does not
    // contain FOVEATION_ENABLE_BIT_QCOM.
    if (!texture->isFoveationEnabled())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureFoveationNotEnabled);
        return false;
    }

    // INVALID_VALUE is generated by TextureFoveationParametersQCOM if 'focalPoint' is larger than
    // TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM minus one.
    if (focalPoint > texture->getNumFocalPoints() - 1)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
        return false;
    }

    return true;
}

bool ValidateEndTilingQCOM(const Context *context,
                           angle::EntryPoint entryPoint,
                           GLbitfield preserveMask)
{
    const gl::PrivateState &privateState = context->getPrivateState();
    if (!privateState.isTiledRendering())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTilingEndCalledWithoutStart);
        return false;
    }

    // preserveMask does not need to be validated. The bitfield covers the entire 32 bits of
    // GLbitfield and unbound attachments are siliently ignored like in glClear

    return true;
}

bool ValidateStartTilingQCOM(const Context *context,
                             angle::EntryPoint entryPoint,
                             GLuint x,
                             GLuint y,
                             GLuint width,
                             GLuint height,
                             GLbitfield preserveMask)
{
    const gl::PrivateState &privateState = context->getPrivateState();
    if (privateState.isTiledRendering())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTilingStartCalledWithoutEnd);
        return false;
    }

    Framebuffer *framebuffer                   = context->getState().getDrawFramebuffer();
    const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
    if (!framebufferStatus.isComplete())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, framebufferStatus.reason);
        return false;
    }

    // preserveMask does not need to be validated. The bitfield covers the entire 32 bits of
    // GLbitfield and unbound attachments are siliently ignored like in glClear

    return true;
}

bool ValidateTexStorageAttribs(const GLint *attrib_list)
{
    if (nullptr != attrib_list && GL_NONE != *attrib_list)
    {
        attrib_list++;
        if (nullptr == attrib_list)
        {
            return false;
        }

        if (*attrib_list == GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT ||
            *attrib_list == GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT)
        {
            return true;
        }
        else if (*attrib_list >= GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT &&
                 *attrib_list <= GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    return true;
}

bool ValidateTexStorageAttribs2DEXT(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    GLenum target,
                                    GLsizei levels,
                                    GLenum internalformat,
                                    GLsizei width,
                                    GLsizei height,
                                    const GLint *attrib_list)
{
    if (!ValidateTexStorageAttribs(attrib_list))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAttribList);
        return false;
    }

    return ValidateES3TexStorage2DParameters(context, entryPoint, FromGLenum<TextureType>(target),
                                             levels, internalformat, width, height, 1);
}

bool ValidateTexStorageAttribs3DEXT(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    GLenum target,
                                    GLsizei levels,
                                    GLenum internalformat,
                                    GLsizei width,
                                    GLsizei height,
                                    GLsizei depth,
                                    const GLint *attrib_list)
{
    if (!ValidateTexStorageAttribs(attrib_list))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAttribList);
        return false;
    }

    return ValidateES3TexStorage3DParameters(context, entryPoint, FromGLenum<TextureType>(target),
                                             levels, internalformat, width, height, depth);
}

}  // namespace gl
