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

// validationES31.cpp: Validation functions for OpenGL ES 3.1 entry point parameters

#include "common/unsafe_buffers.h"
#include "libANGLE/validationES31_autogen.h"

#include "libANGLE/Context.h"
#include "libANGLE/ErrorStrings.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/ProgramExecutable.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/validationES.h"
#include "libANGLE/validationES2_autogen.h"
#include "libANGLE/validationES31.h"
#include "libANGLE/validationES3_autogen.h"

#include "common/utilities.h"

using namespace angle;

namespace gl
{
using namespace err;

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

namespace
{

bool ValidateNamedProgramInterface(GLenum programInterface)
{
    switch (programInterface)
    {
        case GL_UNIFORM:
        case GL_UNIFORM_BLOCK:
        case GL_PROGRAM_INPUT:
        case GL_PROGRAM_OUTPUT:
        case GL_TRANSFORM_FEEDBACK_VARYING:
        case GL_BUFFER_VARIABLE:
        case GL_SHADER_STORAGE_BLOCK:
            return true;
        default:
            return false;
    }
}

bool ValidateLocationProgramInterface(GLenum programInterface)
{
    switch (programInterface)
    {
        case GL_UNIFORM:
        case GL_PROGRAM_INPUT:
        case GL_PROGRAM_OUTPUT:
            return true;
        default:
            return false;
    }
}

bool ValidateProgramInterface(GLenum programInterface)
{
    return (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
            ValidateNamedProgramInterface(programInterface));
}

bool ValidateProgramResourceProperty(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     GLenum prop)
{
    ASSERT(context);
    switch (prop)
    {
        case GL_ACTIVE_VARIABLES:
        case GL_BUFFER_BINDING:
        case GL_NUM_ACTIVE_VARIABLES:

        case GL_ARRAY_SIZE:

        case GL_ARRAY_STRIDE:
        case GL_BLOCK_INDEX:
        case GL_IS_ROW_MAJOR:
        case GL_MATRIX_STRIDE:

        case GL_ATOMIC_COUNTER_BUFFER_INDEX:

        case GL_BUFFER_DATA_SIZE:

        case GL_LOCATION:

        case GL_NAME_LENGTH:

        case GL_OFFSET:

        case GL_REFERENCED_BY_VERTEX_SHADER:
        case GL_REFERENCED_BY_FRAGMENT_SHADER:
        case GL_REFERENCED_BY_COMPUTE_SHADER:

        case GL_TOP_LEVEL_ARRAY_SIZE:
        case GL_TOP_LEVEL_ARRAY_STRIDE:

        case GL_TYPE:
            return true;

        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
            return context->getExtensions().geometryShaderAny() ||
                   context->getClientVersion() >= ES_3_2;

        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
        case GL_IS_PER_PATCH_EXT:
            return context->getExtensions().tessellationShaderAny() ||
                   context->getClientVersion() >= ES_3_2;

        case GL_LOCATION_INDEX_EXT:
            return context->getExtensions().blendFuncExtendedEXT;

        default:
            return false;
    }
}

// GLES 3.10 spec: Page 82 -- Table 7.2
bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
{
    switch (prop)
    {
        case GL_ACTIVE_VARIABLES:
        case GL_BUFFER_BINDING:
        case GL_NUM_ACTIVE_VARIABLES:
        {
            switch (programInterface)
            {
                case GL_ATOMIC_COUNTER_BUFFER:
                case GL_SHADER_STORAGE_BLOCK:
                case GL_UNIFORM_BLOCK:
                    return true;
                default:
                    return false;
            }
        }

        case GL_ARRAY_SIZE:
        {
            switch (programInterface)
            {
                case GL_BUFFER_VARIABLE:
                case GL_PROGRAM_INPUT:
                case GL_PROGRAM_OUTPUT:
                case GL_TRANSFORM_FEEDBACK_VARYING:
                case GL_UNIFORM:
                    return true;
                default:
                    return false;
            }
        }

        case GL_ARRAY_STRIDE:
        case GL_BLOCK_INDEX:
        case GL_IS_ROW_MAJOR:
        case GL_MATRIX_STRIDE:
        {
            switch (programInterface)
            {
                case GL_BUFFER_VARIABLE:
                case GL_UNIFORM:
                    return true;
                default:
                    return false;
            }
        }

        case GL_ATOMIC_COUNTER_BUFFER_INDEX:
        {
            if (programInterface == GL_UNIFORM)
            {
                return true;
            }
            return false;
        }

        case GL_BUFFER_DATA_SIZE:
        {
            switch (programInterface)
            {
                case GL_ATOMIC_COUNTER_BUFFER:
                case GL_SHADER_STORAGE_BLOCK:
                case GL_UNIFORM_BLOCK:
                    return true;
                default:
                    return false;
            }
        }

        case GL_LOCATION:
        {
            return ValidateLocationProgramInterface(programInterface);
        }

        case GL_LOCATION_INDEX_EXT:
        {
            // EXT_blend_func_extended
            return (programInterface == GL_PROGRAM_OUTPUT);
        }

        case GL_NAME_LENGTH:
        {
            return ValidateNamedProgramInterface(programInterface);
        }

        case GL_OFFSET:
        {
            switch (programInterface)
            {
                case GL_BUFFER_VARIABLE:
                case GL_UNIFORM:
                    return true;
                default:
                    return false;
            }
        }

        case GL_REFERENCED_BY_VERTEX_SHADER:
        case GL_REFERENCED_BY_FRAGMENT_SHADER:
        case GL_REFERENCED_BY_COMPUTE_SHADER:
        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
        {
            switch (programInterface)
            {
                case GL_ATOMIC_COUNTER_BUFFER:
                case GL_BUFFER_VARIABLE:
                case GL_PROGRAM_INPUT:
                case GL_PROGRAM_OUTPUT:
                case GL_SHADER_STORAGE_BLOCK:
                case GL_UNIFORM:
                case GL_UNIFORM_BLOCK:
                    return true;
                default:
                    return false;
            }
        }

        case GL_TOP_LEVEL_ARRAY_SIZE:
        case GL_TOP_LEVEL_ARRAY_STRIDE:
        {
            if (programInterface == GL_BUFFER_VARIABLE)
            {
                return true;
            }
            return false;
        }

        case GL_TYPE:
        {
            switch (programInterface)
            {
                case GL_BUFFER_VARIABLE:
                case GL_PROGRAM_INPUT:
                case GL_PROGRAM_OUTPUT:
                case GL_TRANSFORM_FEEDBACK_VARYING:
                case GL_UNIFORM:
                    return true;
                default:
                    return false;
            }
        }
        case GL_IS_PER_PATCH_EXT:
            switch (programInterface)
            {
                case GL_PROGRAM_INPUT:
                case GL_PROGRAM_OUTPUT:
                    return true;
            }
            return false;

        default:
            return false;
    }
}

bool ValidateProgramResourceIndex(const Program *programObject,
                                  GLenum programInterface,
                                  GLuint index)
{
    const ProgramExecutable &executable = programObject->getExecutable();
    switch (programInterface)
    {
        case GL_PROGRAM_INPUT:
            return index < executable.getProgramInputs().size();

        case GL_PROGRAM_OUTPUT:
            return index < executable.getOutputVariables().size();

        case GL_UNIFORM:
            return index < executable.getUniforms().size();

        case GL_BUFFER_VARIABLE:
            return index < executable.getBufferVariables().size();

        case GL_SHADER_STORAGE_BLOCK:
            return index < executable.getShaderStorageBlocks().size();

        case GL_UNIFORM_BLOCK:
            return index < executable.getUniformBlocks().size();

        case GL_ATOMIC_COUNTER_BUFFER:
            return index < executable.getAtomicCounterBuffers().size();

        case GL_TRANSFORM_FEEDBACK_VARYING:
            return index < executable.getLinkedTransformFeedbackVaryings().size();

        default:
            UNREACHABLE();
            return false;
    }
}

bool ValidateProgramUniformBase(const Context *context,
                                angle::EntryPoint entryPoint,
                                GLenum valueType,
                                ShaderProgramID program,
                                UniformLocation location,
                                GLsizei count)
{
    Program *programObject = GetValidProgram(context, entryPoint, program);
    if (programObject == nullptr)
    {
        // Error already generated.
        return false;
    }

    const LinkedUniform *uniform = nullptr;
    if (!ValidateUniformCommonBase(context, entryPoint, programObject, location, count, &uniform))
    {
        // Error already generated.
        return false;
    }
    if (uniform == nullptr)
    {
        return true;  // no-op
    }
    return ValidateUniformValue(context, entryPoint, valueType, uniform->getType());
}

bool ValidateProgramUniformMatrixBase(const Context *context,
                                      angle::EntryPoint entryPoint,
                                      GLenum valueType,
                                      ShaderProgramID program,
                                      UniformLocation location,
                                      GLsizei count,
                                      GLboolean transpose)
{
    Program *programObject = GetValidProgram(context, entryPoint, program);
    if (programObject == nullptr)
    {
        // Error already generated.
        return false;
    }

    const LinkedUniform *uniform = nullptr;
    if (!ValidateUniformCommonBase(context, entryPoint, programObject, location, count, &uniform))
    {
        // Error already generated.
        return false;
    }
    if (uniform == nullptr)
    {
        return true;  // no-op
    }
    return ValidateUniformMatrixValue(context, entryPoint, valueType, uniform->getType());
}

bool ValidateVertexAttribFormatCommon(const PrivateState &privateState,
                                      ErrorSet *errors,
                                      angle::EntryPoint entryPoint,
                                      GLuint relativeOffset)
{
    const Caps &caps = privateState.getCaps();
    if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kRelativeOffsetTooLarge);
        return false;
    }

    // [OpenGL ES 3.1] Section 10.3.1 page 243:
    // An INVALID_OPERATION error is generated if the default vertex array object is bound.
    if (privateState.getVertexArrayId().value == 0)
    {
        errors->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
        return false;
    }

    return true;
}

}  // anonymous namespace

bool ValidateGetBooleani_v(const Context *context,
                           angle::EntryPoint entryPoint,
                           GLenum target,
                           GLuint index,
                           const GLboolean *data)
{
    return ValidateIndexedStateQuery(context, entryPoint, target, index, data, nullptr);
}

bool ValidateDrawIndirectBase(const Context *context,
                              angle::EntryPoint entryPoint,
                              PrimitiveMode mode,
                              const void *indirect)
{
    // Here the third parameter 1 is only to pass the count validation.
    if (!ValidateDrawBase(context, entryPoint, mode))
    {
        return false;
    }

    const State &state = context->getState();

    // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
    // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
    if (state.getVertexArrayId().value == 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultVertexArray);
        return false;
    }

    if (context->hasAnyActiveClientAttrib())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kClientDataInVertexArray);
        return false;
    }

    Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
    if (!drawIndirectBuffer)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDrawIndirectBufferNotBound);
        return false;
    }

    // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
    // machine units, of uint.
    GLint64 offset = reinterpret_cast<GLint64>(indirect);
    if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidIndirectOffset);
        return false;
    }

    return true;
}

bool ValidateDrawArraysIndirect(const Context *context,
                                angle::EntryPoint entryPoint,
                                PrimitiveMode mode,
                                const void *indirect)
{
    const State &state                      = context->getState();
    TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
    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;
        }
    }

    if (!ValidateDrawIndirectBase(context, entryPoint, mode, indirect))
        return false;

    Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
    CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
    // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
    // which's size is 4 * sizeof(uint).
    auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
    if (!checkedSum.IsValid() ||
        checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kParamOverflow);
        return false;
    }

    return true;
}

bool ValidateDrawElementsIndirect(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  PrimitiveMode mode,
                                  DrawElementsType type,
                                  const void *indirect)
{
    if (!ValidateDrawElementsBase(context, entryPoint, mode, type))
    {
        return false;
    }

    const State &state         = context->getState();
    const VertexArray *vao     = state.getVertexArray();
    Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
    if (!elementArrayBuffer)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
        return false;
    }

    if (!ValidateDrawIndirectBase(context, entryPoint, mode, indirect))
        return false;

    Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
    CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
    // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
    // which's size is 5 * sizeof(uint).
    auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
    if (!checkedSum.IsValid() ||
        checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kParamOverflow);
        return false;
    }

    return true;
}

bool ValidateMultiDrawIndirectBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   GLsizei drawcount,
                                   GLsizei stride)
{
    // An INVALID_VALUE error is generated if stride is neither 0 nor a multiple of 4.
    if ((stride & 3) != 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDrawBufferValue);
        return false;
    }

    // An INVALID_VALUE error is generated if drawcount is not positive.
    if (drawcount <= 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidValueNonPositive);
        return false;
    }

    return true;
}

bool ValidateProgramUniform1iBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  UniformLocation location,
                                  GLint v0)
{
    return ValidateProgramUniform1ivBase(context, entryPoint, program, location, 1, &v0);
}

bool ValidateProgramUniform2iBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  UniformLocation location,
                                  GLint v0,
                                  GLint v1)
{
    GLint xy[2] = {v0, v1};
    return ValidateProgramUniform2ivBase(context, entryPoint, program, location, 1, xy);
}

bool ValidateProgramUniform3iBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  UniformLocation location,
                                  GLint v0,
                                  GLint v1,
                                  GLint v2)
{
    GLint xyz[3] = {v0, v1, v2};
    return ValidateProgramUniform3ivBase(context, entryPoint, program, location, 1, xyz);
}

bool ValidateProgramUniform4iBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  UniformLocation location,
                                  GLint v0,
                                  GLint v1,
                                  GLint v2,
                                  GLint v3)
{
    GLint xyzw[4] = {v0, v1, v2, v3};
    return ValidateProgramUniform4ivBase(context, entryPoint, program, location, 1, xyzw);
}

bool ValidateProgramUniform1uiBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLuint v0)
{
    return ValidateProgramUniform1uivBase(context, entryPoint, program, location, 1, &v0);
}

bool ValidateProgramUniform2uiBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLuint v0,
                                   GLuint v1)
{
    GLuint xy[2] = {v0, v1};
    return ValidateProgramUniform2uivBase(context, entryPoint, program, location, 1, xy);
}

bool ValidateProgramUniform3uiBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLuint v0,
                                   GLuint v1,
                                   GLuint v2)
{
    GLuint xyz[3] = {v0, v1, v2};
    return ValidateProgramUniform3uivBase(context, entryPoint, program, location, 1, xyz);
}

bool ValidateProgramUniform4uiBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLuint v0,
                                   GLuint v1,
                                   GLuint v2,
                                   GLuint v3)
{
    GLuint xyzw[4] = {v0, v1, v2, v3};
    return ValidateProgramUniform4uivBase(context, entryPoint, program, location, 1, xyzw);
}

bool ValidateProgramUniform1fBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  UniformLocation location,
                                  GLfloat v0)
{
    return ValidateProgramUniform1fvBase(context, entryPoint, program, location, 1, &v0);
}

bool ValidateProgramUniform2fBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  UniformLocation location,
                                  GLfloat v0,
                                  GLfloat v1)
{
    GLfloat xy[2] = {v0, v1};
    return ValidateProgramUniform2fvBase(context, entryPoint, program, location, 1, xy);
}

bool ValidateProgramUniform3fBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  UniformLocation location,
                                  GLfloat v0,
                                  GLfloat v1,
                                  GLfloat v2)
{
    GLfloat xyz[3] = {v0, v1, v2};
    return ValidateProgramUniform3fvBase(context, entryPoint, program, location, 1, xyz);
}

bool ValidateProgramUniform4fBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  UniformLocation location,
                                  GLfloat v0,
                                  GLfloat v1,
                                  GLfloat v2,
                                  GLfloat v3)
{
    GLfloat xyzw[4] = {v0, v1, v2, v3};
    return ValidateProgramUniform4fvBase(context, entryPoint, program, location, 1, xyzw);
}

bool ValidateProgramUniform1ivBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLsizei count,
                                   const GLint *value)
{
    Program *programObject = GetValidProgram(context, entryPoint, program);
    if (programObject == nullptr)
    {
        // Error already generated.
        return false;
    }

    const LinkedUniform *uniform = nullptr;
    if (!ValidateUniformCommonBase(context, entryPoint, programObject, location, count, &uniform))
    {
        // Error already generated.
        return false;
    }
    if (uniform == nullptr)
    {
        return true;  // no-op
    }
    return ValidateUniform1ivValue(context, entryPoint, uniform->getType(), count, value);
}

bool ValidateProgramUniform2ivBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLsizei count,
                                   const GLint *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC2, program, location, count);
}

bool ValidateProgramUniform3ivBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLsizei count,
                                   const GLint *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC3, program, location, count);
}

bool ValidateProgramUniform4ivBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLsizei count,
                                   const GLint *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC4, program, location, count);
}

bool ValidateProgramUniform1uivBase(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    ShaderProgramID program,
                                    UniformLocation location,
                                    GLsizei count,
                                    const GLuint *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT, program, location,
                                      count);
}

bool ValidateProgramUniform2uivBase(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    ShaderProgramID program,
                                    UniformLocation location,
                                    GLsizei count,
                                    const GLuint *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC2, program, location,
                                      count);
}

bool ValidateProgramUniform3uivBase(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    ShaderProgramID program,
                                    UniformLocation location,
                                    GLsizei count,
                                    const GLuint *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC3, program, location,
                                      count);
}

bool ValidateProgramUniform4uivBase(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    ShaderProgramID program,
                                    UniformLocation location,
                                    GLsizei count,
                                    const GLuint *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC4, program, location,
                                      count);
}

bool ValidateProgramUniform1fvBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT, program, location, count);
}

bool ValidateProgramUniform2fvBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC2, program, location, count);
}

bool ValidateProgramUniform3fvBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC3, program, location, count);
}

bool ValidateProgramUniform4fvBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   UniformLocation location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC4, program, location, count);
}

bool ValidateProgramUniformMatrix2fvBase(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         ShaderProgramID program,
                                         UniformLocation location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLfloat *value)
{
    return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2, program, location,
                                            count, transpose);
}

bool ValidateProgramUniformMatrix3fvBase(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         ShaderProgramID program,
                                         UniformLocation location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLfloat *value)
{
    return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3, program, location,
                                            count, transpose);
}

bool ValidateProgramUniformMatrix4fvBase(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         ShaderProgramID program,
                                         UniformLocation location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLfloat *value)
{
    return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4, program, location,
                                            count, transpose);
}

bool ValidateProgramUniformMatrix2x3fvBase(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           ShaderProgramID program,
                                           UniformLocation location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2x3, program, location,
                                            count, transpose);
}

bool ValidateProgramUniformMatrix3x2fvBase(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           ShaderProgramID program,
                                           UniformLocation location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3x2, program, location,
                                            count, transpose);
}

bool ValidateProgramUniformMatrix2x4fvBase(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           ShaderProgramID program,
                                           UniformLocation location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2x4, program, location,
                                            count, transpose);
}

bool ValidateProgramUniformMatrix4x2fvBase(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           ShaderProgramID program,
                                           UniformLocation location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4x2, program, location,
                                            count, transpose);
}

bool ValidateProgramUniformMatrix3x4fvBase(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           ShaderProgramID program,
                                           UniformLocation location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3x4, program, location,
                                            count, transpose);
}

bool ValidateProgramUniformMatrix4x3fvBase(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           ShaderProgramID program,
                                           UniformLocation location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4x3, program, location,
                                            count, transpose);
}

bool ValidateGetTexLevelParameterfv(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    TextureTarget targetPacked,
                                    GLint level,
                                    TextureImageParameter pnamePacked,
                                    const GLfloat *params)
{
    return ValidateGetTexLevelParameterBase(context, entryPoint, targetPacked, level, pnamePacked,
                                            nullptr);
}

bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context,
                                               angle::EntryPoint entryPoint,
                                               TextureTarget targetPacked,
                                               GLint level,
                                               TextureImageParameter pnamePacked,
                                               GLsizei paramCount,
                                               const GLsizei *length,
                                               const GLfloat *params)
{
    // Make sure ValidateGetTexLevelParameterBase sets numParams
    GLsizei numParams = std::numeric_limits<GLsizei>::max();
    if (!ValidateGetTexLevelParameterBase(context, entryPoint, targetPacked, level, pnamePacked,
                                          &numParams))
    {
        return false;
    }
    ASSERT(numParams != std::numeric_limits<GLsizei>::max());

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

    return true;
}

bool ValidateGetTexLevelParameteriv(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    TextureTarget targetPacked,
                                    GLint level,
                                    TextureImageParameter pnamePacked,
                                    const GLint *params)
{
    return ValidateGetTexLevelParameterBase(context, entryPoint, targetPacked, level, pnamePacked,
                                            nullptr);
}

bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context,
                                               angle::EntryPoint entryPoint,
                                               TextureTarget targetPacked,
                                               GLint level,
                                               TextureImageParameter pnamePacked,
                                               GLsizei paramCount,
                                               const GLsizei *length,
                                               const GLint *params)
{
    // Make sure ValidateGetTexLevelParameterBase sets numParams
    GLsizei numParams = std::numeric_limits<GLsizei>::max();
    if (!ValidateGetTexLevelParameterBase(context, entryPoint, targetPacked, level, pnamePacked,
                                          &numParams))
    {
        return false;
    }
    ASSERT(numParams != std::numeric_limits<GLsizei>::max());

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

    return true;
}

bool ValidateTexStorage2DMultisample(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     TextureType target,
                                     GLsizei samples,
                                     GLenum internalFormat,
                                     GLsizei width,
                                     GLsizei height,
                                     GLboolean fixedSampleLocations)
{
    return ValidateTexStorage2DMultisampleBase(context, entryPoint, target, samples, internalFormat,
                                               width, height);
}

bool ValidateTexStorageMem2DMultisampleEXT(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           TextureType target,
                                           GLsizei samples,
                                           GLenum internalFormat,
                                           GLsizei width,
                                           GLsizei height,
                                           GLboolean fixedSampleLocations,
                                           MemoryObjectID memory,
                                           GLuint64 offset)
{
    UNIMPLEMENTED();
    return false;
}

bool ValidateGetMultisamplefv(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLenum pname,
                              GLuint index,
                              const GLfloat *val)
{
    return ValidateGetMultisamplefvBase(context, entryPoint, pname, index, nullptr);
}

bool ValidateGetMultisamplefvRobustANGLE(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         GLenum pname,
                                         GLuint index,
                                         GLsizei paramCount,
                                         const GLsizei *length,
                                         const GLfloat *val)
{
    // Make sure ValidateGetMultisamplefvBase sets numParams
    GLsizei numParams = std::numeric_limits<GLsizei>::max();
    if (!ValidateGetMultisamplefvBase(context, entryPoint, pname, index, &numParams))
    {
        return false;
    }
    ASSERT(numParams != std::numeric_limits<GLsizei>::max());

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

    return true;
}

bool ValidateFramebufferParameteri(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   GLenum target,
                                   FramebufferParameter pnamePacked,
                                   GLint param)
{
    return ValidateFramebufferParameteriBase(context, entryPoint, target, pnamePacked, param);
}

bool ValidateGetFramebufferParameteriv(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLenum target,
                                       FramebufferParameter pnamePacked,
                                       const GLint *params)
{
    return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pnamePacked, params);
}

bool ValidateGetProgramResourceIndex(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     ShaderProgramID program,
                                     GLenum programInterface,
                                     const GLchar *name)
{
    Program *programObject = GetValidProgram(context, entryPoint, program);
    if (programObject == nullptr)
    {
        // Error already generated.
        return false;
    }

    if (!ValidateNamedProgramInterface(programInterface))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
        return false;
    }

    return true;
}

bool ValidateBindVertexBuffer(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLuint bindingIndex,
                              BufferID buffer,
                              GLintptr offset,
                              GLsizei stride)
{
    if (!context->isBufferGenerated(buffer))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
        return false;
    }

    const Caps &caps = context->getCaps();
    if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
        return false;
    }

    if (offset < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
        return false;
    }

    if (stride < 0 || stride > caps.maxVertexAttribStride)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
        return false;
    }

    // [OpenGL ES 3.1] Section 10.3.1 page 244:
    // An INVALID_OPERATION error is generated if the default vertex array object is bound.
    if (context->getState().getVertexArrayId().value == 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultVertexArray);
        return false;
    }

    return true;
}

bool ValidateVertexBindingDivisor(const PrivateState &privateState,
                                  ErrorSet *errors,
                                  angle::EntryPoint entryPoint,
                                  GLuint bindingIndex,
                                  GLuint divisor)
{
    const Caps &caps = privateState.getCaps();
    if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
        return false;
    }

    // [OpenGL ES 3.1] Section 10.3.1 page 243:
    // An INVALID_OPERATION error is generated if the default vertex array object is bound.
    if (privateState.getVertexArrayId().value == 0)
    {
        errors->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
        return false;
    }

    return true;
}

bool ValidateVertexAttribFormat(const PrivateState &privateState,
                                const PrivateStateCache &privateStateCache,
                                ErrorSet *errors,
                                angle::EntryPoint entryPoint,
                                GLuint attribindex,
                                GLint size,
                                VertexAttribType type,
                                GLboolean normalized,
                                GLuint relativeoffset)
{
    if (!ValidateVertexAttribFormatCommon(privateState, errors, entryPoint, relativeoffset))
    {
        return false;
    }

    return ValidateFloatVertexFormat(privateState, privateStateCache, errors, entryPoint,
                                     attribindex, size, type);
}

bool ValidateVertexAttribIFormat(const PrivateState &privateState,
                                 const PrivateStateCache &privateStateCache,
                                 ErrorSet *errors,
                                 angle::EntryPoint entryPoint,
                                 GLuint attribindex,
                                 GLint size,
                                 VertexAttribType type,
                                 GLuint relativeoffset)
{
    if (!ValidateVertexAttribFormatCommon(privateState, errors, entryPoint, relativeoffset))
    {
        return false;
    }

    return ValidateIntegerVertexFormat(privateState, privateStateCache, errors, entryPoint,
                                       attribindex, size, type);
}

bool ValidateVertexAttribBinding(const PrivateState &privateState,
                                 ErrorSet *errors,
                                 angle::EntryPoint entryPoint,
                                 GLuint attribIndex,
                                 GLuint bindingIndex)
{
    // [OpenGL ES 3.1] Section 10.3.1 page 243:
    // An INVALID_OPERATION error is generated if the default vertex array object is bound.
    if (privateState.getVertexArrayId().value == 0)
    {
        errors->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
        return false;
    }

    const Caps &caps = privateState.getCaps();
    if (attribIndex >= static_cast<GLuint>(caps.maxVertexAttributes))
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
        return false;
    }

    if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
        return false;
    }

    return true;
}

bool ValidateGetProgramResourceName(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    ShaderProgramID program,
                                    GLenum programInterface,
                                    GLuint index,
                                    GLsizei bufSize,
                                    const GLsizei *length,
                                    const GLchar *name)
{
    Program *programObject = GetValidProgram(context, entryPoint, program);
    if (programObject == nullptr)
    {
        // Error already generated.
        return false;
    }

    if (!ValidateNamedProgramInterface(programInterface))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
        return false;
    }

    if (!ValidateProgramResourceIndex(programObject, programInterface, index))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
        return false;
    }

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

    return true;
}

bool ValidateDispatchCompute(const Context *context,
                             angle::EntryPoint entryPoint,
                             GLuint numGroupsX,
                             GLuint numGroupsY,
                             GLuint numGroupsZ)
{
    const State &state                  = context->getState();
    const ProgramExecutable *executable = state.getLinkedProgramExecutable(context);

    if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
        return false;
    }

    const Caps &caps = context->getCaps();
    if (numGroupsX > static_cast<GLuint>(caps.maxComputeWorkGroupCount[0]))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountX);
        return false;
    }
    if (numGroupsY > static_cast<GLuint>(caps.maxComputeWorkGroupCount[1]))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountY);
        return false;
    }
    if (numGroupsZ > static_cast<GLuint>(caps.maxComputeWorkGroupCount[2]))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountZ);
        return false;
    }

    return true;
}

bool ValidateDispatchComputeIndirect(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     GLintptr indirect)
{
    const State &state                  = context->getState();
    const ProgramExecutable *executable = state.getProgramExecutable();

    if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
        return false;
    }

    if (indirect < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
        return false;
    }

    if ((indirect & (sizeof(GLuint) - 1)) != 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint);
        return false;
    }

    Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
    if (!dispatchIndirectBuffer)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound);
        return false;
    }

    CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
    auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
    if (!checkedSum.IsValid() ||
        checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
        return false;
    }

    return true;
}

bool ValidateBindImageTexture(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLuint unit,
                              TextureID texture,
                              GLint level,
                              GLboolean layered,
                              GLint layer,
                              GLenum access,
                              GLenum format)
{
    GLuint maxImageUnits = static_cast<GLuint>(context->getCaps().maxImageUnits);
    if (unit >= maxImageUnits)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxImageUnits);
        return false;
    }

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

    if (layer < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLayer);
        return false;
    }

    if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageAccess);
        return false;
    }

    switch (format)
    {
        case GL_RGBA32F:
        case GL_RGBA16F:
        case GL_R32F:
        case GL_RGBA32UI:
        case GL_RGBA16UI:
        case GL_RGBA8UI:
        case GL_R32UI:
        case GL_RGBA32I:
        case GL_RGBA16I:
        case GL_RGBA8I:
        case GL_R32I:
        case GL_RGBA8:
        case GL_RGBA8_SNORM:
            break;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidImageFormat);
            return false;
    }

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

        if (tex == nullptr)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kMissingTextureName);
            return false;
        }

        if (tex->getType() != gl::TextureType::External &&
            tex->getType() != gl::TextureType::Buffer && !tex->getImmutableFormat())
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
                                   kTextureIsNeitherImmutableNorTextureBuffer);
            return false;
        }

        if (context->getExtensions().textureStorageCompressionEXT &&
            tex->getType() != gl::TextureType::Buffer)
        {
            if (tex->getImageCompressionRate(context) != GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE,
                                       kTextureFixedCompressedNotSupportBindImageTexture);
                return false;
            }
        }
    }

    return true;
}

bool ValidateGetProgramResourceLocation(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        ShaderProgramID program,
                                        GLenum programInterface,
                                        const GLchar *name)
{
    Program *programObject = GetValidProgram(context, entryPoint, program);
    if (programObject == nullptr)
    {
        // Error already generated.
        return false;
    }

    if (!programObject->isLinked())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
        return false;
    }

    if (!ValidateLocationProgramInterface(programInterface))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
        return false;
    }
    return true;
}

bool ValidateGetProgramResourceiv(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  GLenum programInterface,
                                  GLuint index,
                                  GLsizei propCount,
                                  const GLenum *props,
                                  GLsizei count,
                                  const GLsizei *length,
                                  const GLint *params)
{
    Program *programObject = GetValidProgram(context, entryPoint, program);
    if (programObject == nullptr)
    {
        // Error already generated.
        return false;
    }

    if (!ValidateProgramInterface(programInterface))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
        return false;
    }
    if (propCount <= 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPropCount);
        return false;
    }
    if (count < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
        return false;
    }
    if (!ValidateProgramResourceIndex(programObject, programInterface, index))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
        return false;
    }
    for (GLsizei i = 0; i < propCount; i++)
    {
        if (!ValidateProgramResourceProperty(context, entryPoint, ANGLE_UNSAFE_TODO(props[i])))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramResourceProperty);
            return false;
        }
        if (!ValidateProgramResourcePropertyByInterface(ANGLE_UNSAFE_TODO(props[i]),
                                                        programInterface))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidPropertyForProgramInterface);
            return false;
        }
    }
    return true;
}

bool ValidateGetProgramInterfaceiv(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   ShaderProgramID program,
                                   GLenum programInterface,
                                   GLenum pname,
                                   const GLint *params)
{
    Program *programObject = GetValidProgram(context, entryPoint, program);
    if (programObject == nullptr)
    {
        // Error already generated.
        return false;
    }

    if (!ValidateProgramInterface(programInterface))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
        return false;
    }

    switch (pname)
    {
        case GL_ACTIVE_RESOURCES:
        case GL_MAX_NAME_LENGTH:
        case GL_MAX_NUM_ACTIVE_VARIABLES:
            break;

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

    if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kAtomicCounterResourceName);
        return false;
    }

    if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
    {
        switch (programInterface)
        {
            case GL_ATOMIC_COUNTER_BUFFER:
            case GL_SHADER_STORAGE_BLOCK:
            case GL_UNIFORM_BLOCK:
                break;

            default:
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMaxActiveVariablesInterface);
                return false;
        }
    }

    return true;
}

bool ValidateGenProgramPipelinesBase(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     GLsizei n,
                                     const ProgramPipelineID *pipelines)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               pipelines);
}

bool ValidateDeleteProgramPipelinesBase(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        GLsizei n,
                                        const ProgramPipelineID *pipelines)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               pipelines);
}

bool ValidateBindProgramPipelineBase(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     ProgramPipelineID pipeline)
{
    if (!context->isProgramPipelineGenerated({pipeline}))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
        return false;
    }

    return true;
}

bool ValidateUseProgramStagesBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ProgramPipelineID pipeline,
                                  GLbitfield stages,
                                  ShaderProgramID programId)
{
    // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is
    // not the reserved value GL_ALL_SHADER_BITS.
    GLbitfield knownShaderBits =
        GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT;

    if (context->getClientVersion() >= ES_3_2 || context->getExtensions().geometryShaderAny())
    {
        knownShaderBits |= GL_GEOMETRY_SHADER_BIT;
    }

    if (context->getClientVersion() >= ES_3_2 || context->getExtensions().tessellationShaderAny())
    {
        knownShaderBits |= GL_TESS_CONTROL_SHADER_BIT;
        knownShaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
    }

    if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kUnrecognizedShaderStageBit);
        return false;
    }

    // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call
    // to glGenProgramPipelines or if such a name has been deleted by a call to
    // glDeleteProgramPipelines.
    if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated({pipeline})))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
        return false;
    }

    // If program is zero, or refers to a program object with no valid shader executable for a given
    // stage, it is as if the pipeline object has no programmable stage configured for the indicated
    // shader stages.
    if (programId.value == 0)
    {
        return true;
    }

    Program *program = context->getProgramNoResolveLink(programId);
    if (!program)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramDoesNotExist);
        return false;
    }

    // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked
    // with its GL_PROGRAM_SEPARABLE status set.
    // resolveLink() may not have been called if glCreateShaderProgramv() was not used and
    // glDetachShader() was not called.
    program->resolveLink(context);
    if (!program->isSeparable())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotSeparable);
        return false;
    }

    // GL_INVALID_OPERATION is generated if program refers to a program object that has not been
    // successfully linked.
    if (!program->isLinked())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
        return false;
    }

    return true;
}

bool ValidateActiveShaderProgramBase(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     ProgramPipelineID pipeline,
                                     ShaderProgramID programId)
{
    // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
    // call to GenProgramPipelines or if such a name has since been deleted by
    // DeleteProgramPipelines.
    if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated({pipeline})))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
        return false;
    }

    // An INVALID_VALUE error is generated if program is not zero and is not the name of either a
    // program or shader object.
    if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramDoesNotExist);
        return false;
    }

    // An INVALID_OPERATION error is generated if program is the name of a shader object.
    if (context->isShader(programId))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExpectedProgramName);
        return false;
    }

    // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or
    // was last linked unsuccessfully. The active program is not modified.
    Program *program = context->getProgramNoResolveLink(programId);
    if ((programId.value != 0) && !program->isLinked())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
        return false;
    }

    return true;
}

bool ValidateCreateShaderProgramvBase(const Context *context,
                                      angle::EntryPoint entryPoint,
                                      ShaderType type,
                                      GLsizei count,
                                      const GLchar *const *strings)
{
    switch (type)
    {
        case ShaderType::InvalidEnum:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
            return false;
        case ShaderType::Vertex:
        case ShaderType::Fragment:
        case ShaderType::Compute:
            break;
        case ShaderType::Geometry:
            if (!context->getExtensions().geometryShaderAny() &&
                context->getClientVersion() < ES_3_2)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
                return false;
            }
            break;
        case ShaderType::TessControl:
        case ShaderType::TessEvaluation:
            if (!context->getExtensions().tessellationShaderAny() &&
                context->getClientVersion() < ES_3_2)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
                return false;
            }
            break;
        default:
            UNREACHABLE();
    }

    // GL_INVALID_VALUE is generated if count is negative.
    if (count < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
        return false;
    }

    return true;
}

bool ValidateGetProgramPipelineivBase(const Context *context,
                                      angle::EntryPoint entryPoint,
                                      ProgramPipelineID pipeline,
                                      GLenum pname,
                                      const GLint *params)
{
    // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
    // call to GenProgramPipelines or if such a name has since been deleted by
    // DeleteProgramPipelines.
    if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
        return false;
    }

    // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM,
    // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in
    // table 7.1.
    switch (pname)
    {
        case GL_ACTIVE_PROGRAM:
        case GL_INFO_LOG_LENGTH:
        case GL_VALIDATE_STATUS:
        case GL_VERTEX_SHADER:
        case GL_FRAGMENT_SHADER:
        case GL_COMPUTE_SHADER:
            break;
        case GL_GEOMETRY_SHADER:
            return context->getExtensions().geometryShaderAny() ||
                   context->getClientVersion() >= ES_3_2;
        case GL_TESS_CONTROL_SHADER:
        case GL_TESS_EVALUATION_SHADER:
            return context->getExtensions().tessellationShaderAny() ||
                   context->getClientVersion() >= ES_3_2;

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

    return true;
}

bool ValidateValidateProgramPipelineBase(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         ProgramPipelineID pipeline)
{
    // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
    // call to GenProgramPipelines or if such a name has since been deleted by
    // DeleteProgramPipelines.
    if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
        return false;
    }

    return true;
}

bool ValidateGetProgramPipelineInfoLogBase(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           ProgramPipelineID pipeline,
                                           GLsizei bufSize,
                                           const GLsizei *length,
                                           const GLchar *infoLog)
{
    if (bufSize < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
        return false;
    }

    if (bufSize > 0 && infoLog == nullptr)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramPipelineInfoLogNULL);
        return false;
    }

    if (!context->isProgramPipelineGenerated(pipeline))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramPipelineDoesNotExist);
        return false;
    }

    return true;
}

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

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

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

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

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

bool ValidateGetProgramPipelineInfoLog(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 ValidateGetProgramPipelineiv(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ProgramPipelineID pipelinePacked,
                                  GLenum pname,
                                  const GLint *params)
{
    return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
}

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

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

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

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

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

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

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

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

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

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

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

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

bool ValidateProgramUniform3f(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 ValidateProgramUniform3fv(const Context *context,
                               angle::EntryPoint entryPoint,
                               ShaderProgramID programPacked,
                               UniformLocation locationPacked,
                               GLsizei count,
                               const GLfloat *value)
{
    return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
                                         value);
}

bool ValidateProgramUniform3i(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 ValidateProgramUniform3iv(const Context *context,
                               angle::EntryPoint entryPoint,
                               ShaderProgramID programPacked,
                               UniformLocation locationPacked,
                               GLsizei count,
                               const GLint *value)
{
    return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
                                         value);
}

bool ValidateProgramUniform3ui(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 ValidateProgramUniform3uiv(const Context *context,
                                angle::EntryPoint entryPoint,
                                ShaderProgramID programPacked,
                                UniformLocation locationPacked,
                                GLsizei count,
                                const GLuint *value)
{
    return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
                                          value);
}

bool ValidateProgramUniform4f(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 ValidateProgramUniform4fv(const Context *context,
                               angle::EntryPoint entryPoint,
                               ShaderProgramID programPacked,
                               UniformLocation locationPacked,
                               GLsizei count,
                               const GLfloat *value)
{
    return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
                                         value);
}

bool ValidateProgramUniform4i(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 ValidateProgramUniform4iv(const Context *context,
                               angle::EntryPoint entryPoint,
                               ShaderProgramID programPacked,
                               UniformLocation locationPacked,
                               GLsizei count,
                               const GLint *value)
{
    return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
                                         value);
}

bool ValidateProgramUniform4ui(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 ValidateProgramUniform4uiv(const Context *context,
                                angle::EntryPoint entryPoint,
                                ShaderProgramID programPacked,
                                UniformLocation locationPacked,
                                GLsizei count,
                                const GLuint *value)
{
    return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
                                          value);
}

bool ValidateProgramUniformMatrix2fv(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 ValidateProgramUniformMatrix2x3fv(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 ValidateProgramUniformMatrix2x4fv(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 ValidateProgramUniformMatrix3fv(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 ValidateProgramUniformMatrix3x2fv(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 ValidateProgramUniformMatrix3x4fv(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 ValidateProgramUniformMatrix4fv(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 ValidateProgramUniformMatrix4x2fv(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 ValidateProgramUniformMatrix4x3fv(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 ValidateUseProgramStages(const Context *context,
                              angle::EntryPoint entryPoint,
                              ProgramPipelineID pipelinePacked,
                              GLbitfield stages,
                              ShaderProgramID programPacked)
{
    return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
}

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

bool ValidateMemoryBarrier(const Context *context,
                           angle::EntryPoint entryPoint,
                           GLbitfield barriers)
{
    if (barriers == GL_ALL_BARRIER_BITS)
    {
        return true;
    }

    GLbitfield supported_barrier_bits =
        GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
        GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
        GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
        GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
        GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;

    if (context->getExtensions().bufferStorageEXT)
    {
        supported_barrier_bits |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT;
    }

    if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
        return false;
    }

    return true;
}

bool ValidateMemoryBarrierByRegion(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   GLbitfield barriers)
{
    if (barriers == GL_ALL_BARRIER_BITS)
    {
        return true;
    }

    GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
                                        GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
                                        GL_SHADER_STORAGE_BARRIER_BIT |
                                        GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
    if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
        return false;
    }

    return true;
}

bool ValidateSampleMaski(const PrivateState &state,
                         ErrorSet *errors,
                         angle::EntryPoint entryPoint,
                         GLuint maskNumber,
                         GLbitfield mask)
{
    return ValidateSampleMaskiBase(state, errors, entryPoint, maskNumber, mask);
}

bool ValidateFramebufferTextureCommon(const Context *context,
                                      angle::EntryPoint entryPoint,
                                      GLenum target,
                                      GLenum attachment,
                                      TextureID texture,
                                      GLint level)
{
    if (texture.value != 0)
    {
        Texture *tex = context->getTexture(texture);

        // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
        // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
        // We put this validation before ValidateFramebufferTextureBase because it is an
        // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
        // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
        // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
        // existing texture object of type matching textarget.
        // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
        // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
        // three-dimensional or two-dimensional array texture.
        if (tex == nullptr)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
            return false;
        }

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

        // GLES spec 3.2, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
        // * If textarget is TEXTURE_2D_MULTISAMPLE, then level must be zero.
        // * If texture is a two-dimensional multisample array texture, then level must be zero.
        // Already validated in ValidMipLevel.
        ASSERT(level == 0 || !IsMultisampled(tex->getType()));
    }

    if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
    {
        return false;
    }

    return true;
}

bool ValidateFramebufferTextureEXT(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   GLenum target,
                                   GLenum attachment,
                                   TextureID texture,
                                   GLint level)
{
    return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
                                            level);
}

bool ValidateFramebufferTextureOES(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   GLenum target,
                                   GLenum attachment,
                                   TextureID texture,
                                   GLint level)
{
    return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
                                            level);
}

bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           TextureType target,
                                           GLsizei samples,
                                           GLenum internalFormat,
                                           GLsizei width,
                                           GLsizei height,
                                           GLsizei depth,
                                           GLboolean fixedSampleLocations,
                                           MemoryObjectID memory,
                                           GLuint64 offset)
{
    UNIMPLEMENTED();
    return false;
}

bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
                                                angle::EntryPoint entryPoint,
                                                ShaderProgramID program,
                                                GLenum programInterface,
                                                const char *name)
{
    if (context->getClientVersion() < ES_3_1)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
        return false;
    }
    if (programInterface != GL_PROGRAM_OUTPUT)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
        return false;
    }

    Program *programObject = GetValidProgram(context, entryPoint, program);
    if (programObject == nullptr)
    {
        // Error already generated.
        return false;
    }

    if (!programObject->isLinked())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
        return false;
    }

    return true;
}

// GL_OES_texture_buffer
bool ValidateTexBufferOES(const Context *context,
                          angle::EntryPoint entryPoint,
                          TextureType target,
                          GLenum internalformat,
                          BufferID bufferPacked)
{
    return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
}

bool ValidateTexBufferRangeOES(const Context *context,
                               angle::EntryPoint entryPoint,
                               TextureType target,
                               GLenum internalformat,
                               BufferID bufferPacked,
                               GLintptr offset,
                               GLsizeiptr size)
{
    return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
                                      offset, size);
}

// GL_EXT_texture_buffer
bool ValidateTexBufferEXT(const Context *context,
                          angle::EntryPoint entryPoint,
                          TextureType target,
                          GLenum internalformat,
                          BufferID bufferPacked)
{
    return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
}

bool ValidateTexBufferRangeEXT(const Context *context,
                               angle::EntryPoint entryPoint,
                               TextureType target,
                               GLenum internalformat,
                               BufferID bufferPacked,
                               GLintptr offset,
                               GLsizeiptr size)
{
    return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
                                      offset, size);
}

bool ValidateTexBufferBase(const Context *context,
                           angle::EntryPoint entryPoint,
                           TextureType target,
                           GLenum internalformat,
                           BufferID bufferPacked)
{
    if (target != TextureType::Buffer)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferTarget);
        return false;
    }

    switch (internalformat)
    {
        case GL_R8:
        case GL_R16F:
        case GL_R32F:
        case GL_R8I:
        case GL_R16I:
        case GL_R32I:
        case GL_R8UI:
        case GL_R16UI:
        case GL_R32UI:
        case GL_RG8:
        case GL_RG16F:
        case GL_RG32F:
        case GL_RG8I:
        case GL_RG16I:
        case GL_RG32I:
        case GL_RG8UI:
        case GL_RG16UI:
        case GL_RG32UI:
        case GL_RGB32F:
        case GL_RGB32I:
        case GL_RGB32UI:
        case GL_RGBA8:
        case GL_RGBA16F:
        case GL_RGBA32F:
        case GL_RGBA8I:
        case GL_RGBA16I:
        case GL_RGBA32I:
        case GL_RGBA8UI:
        case GL_RGBA16UI:
        case GL_RGBA32UI:
            break;
        case GL_R16_EXT:
        case GL_RG16_EXT:
        case GL_RGBA16_EXT:
        {
            if (!context->getExtensions().textureNorm16EXT)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferInternalFormat);
                return false;
            }
            break;
        }

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

    if (bufferPacked.value != 0)
    {
        if (!context->isBufferGenerated(bufferPacked))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferInvalidBuffer);
            return false;
        }
    }

    return true;
}

bool ValidateTexBufferRangeBase(const Context *context,
                                angle::EntryPoint entryPoint,
                                TextureType target,
                                GLenum internalformat,
                                BufferID bufferPacked,
                                GLintptr offset,
                                GLsizeiptr size)
{
    const Caps &caps = context->getCaps();

    if (offset < 0 || (offset % caps.textureBufferOffsetAlignment) != 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferOffsetAlignment);
        return false;
    }
    if (size <= 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferSize);
        return false;
    }
    const Buffer *buffer = context->getBuffer(bufferPacked);

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

    if (offset + size > buffer->getSize())
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferSizeOffset);
        return false;
    }

    return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
}

bool ValidatePatchParameteriBase(const PrivateState &state,
                                 ErrorSet *errors,
                                 angle::EntryPoint entryPoint,
                                 GLenum pname,
                                 GLint value)
{
    if (ANGLE_UNLIKELY(pname != GL_PATCH_VERTICES))
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
        return false;
    }

    if (ANGLE_UNLIKELY(value <= 0 || value > state.getCaps().maxPatchVertices))
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPatchVerticesValue);
        return false;
    }

    return true;
}

}  // namespace gl
