//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// validationES1.cpp: Validation functions for OpenGL ES 1.0 entry point parameters

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

#include "common/debug.h"
#include "libANGLE/Context.h"
#include "libANGLE/ErrorStrings.h"
#include "libANGLE/GLES1State.h"
#include "libANGLE/queryconversions.h"
#include "libANGLE/queryutils.h"
#include "libANGLE/validationES.h"
#include "libANGLE/validationES2.h"

namespace gl
{
using namespace err;

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

bool ValidateAlphaFuncCommon(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             AlphaTestFunc func)
{
    switch (func)
    {
        case AlphaTestFunc::AlwaysPass:
        case AlphaTestFunc::Equal:
        case AlphaTestFunc::Gequal:
        case AlphaTestFunc::Greater:
        case AlphaTestFunc::Lequal:
        case AlphaTestFunc::Less:
        case AlphaTestFunc::Never:
        case AlphaTestFunc::NotEqual:
            return true;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kEnumInvalid);
            return false;
    }
}

bool ValidateClientStateCommon(const Context *context,
                               angle::EntryPoint entryPoint,
                               ClientVertexArrayType arrayType)
{
    switch (arrayType)
    {
        case ClientVertexArrayType::Vertex:
        case ClientVertexArrayType::Normal:
        case ClientVertexArrayType::Color:
        case ClientVertexArrayType::TextureCoord:
            return true;
        case ClientVertexArrayType::PointSize:
            if (!context->getExtensions().pointSizeArrayOES)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kPointSizeArrayExtensionNotEnabled);
                return false;
            }
            return true;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidClientState);
            return false;
    }
}

bool ValidateBuiltinVertexAttributeCommon(const Context *context,
                                          angle::EntryPoint entryPoint,
                                          ClientVertexArrayType arrayType,
                                          GLint size,
                                          VertexAttribType type,
                                          GLsizei stride,
                                          const void *pointer)
{
    if (stride < 0)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidVertexPointerStride);
        return false;
    }

    int minSize = 1;
    int maxSize = 4;

    switch (arrayType)
    {
        case ClientVertexArrayType::Vertex:
        case ClientVertexArrayType::TextureCoord:
            minSize = 2;
            maxSize = 4;
            break;
        case ClientVertexArrayType::Normal:
            minSize = 3;
            maxSize = 3;
            break;
        case ClientVertexArrayType::Color:
            minSize = 4;
            maxSize = 4;
            break;
        case ClientVertexArrayType::PointSize:
            if (!context->getExtensions().pointSizeArrayOES)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kPointSizeArrayExtensionNotEnabled);
                return false;
            }

            minSize = 1;
            maxSize = 1;
            break;
        default:
            UNREACHABLE();
            return false;
    }

    if (size < minSize || size > maxSize)
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidVertexPointerSize);
        return false;
    }

    switch (type)
    {
        case VertexAttribType::Byte:
            if (arrayType == ClientVertexArrayType::PointSize)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidVertexPointerType);
                return false;
            }
            break;
        case VertexAttribType::Short:
            if (arrayType == ClientVertexArrayType::PointSize ||
                arrayType == ClientVertexArrayType::Color)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidVertexPointerType);
                return false;
            }
            break;
        case VertexAttribType::Fixed:
        case VertexAttribType::Float:
            break;
        case VertexAttribType::UnsignedByte:
            if (arrayType != ClientVertexArrayType::Color)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidVertexPointerType);
                return false;
            }
            break;
        default:
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidVertexPointerType);
            return false;
    }

    return true;
}

bool ValidateLightCaps(const PrivateState &state,
                       ErrorSet *errors,
                       angle::EntryPoint entryPoint,
                       GLenum light)
{
    if (light < GL_LIGHT0 || light >= GL_LIGHT0 + state.getCaps().maxLights)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLight);
        return false;
    }

    return true;
}

bool ValidateLightCommon(const PrivateState &state,
                         ErrorSet *errors,
                         angle::EntryPoint entryPoint,
                         GLenum light,
                         LightParameter pname,
                         const GLfloat *params)
{
    if (!ValidateLightCaps(state, errors, entryPoint, light))
    {
        return false;
    }

    switch (pname)
    {
        case LightParameter::Ambient:
        case LightParameter::Diffuse:
        case LightParameter::Specular:
        case LightParameter::Position:
        case LightParameter::SpotDirection:
            return true;
        case LightParameter::SpotExponent:
            if (isOutsideOfBounds(params[0], 0.0f, 128.0f))
            {
                errors->validationError(entryPoint, GL_INVALID_VALUE, kLightParameterOutOfRange);
                return false;
            }
            return true;
        case LightParameter::SpotCutoff:
            if (params[0] == 180.0f)
            {
                return true;
            }
            if (isOutsideOfBounds(params[0], 0.0f, 90.0f))
            {
                errors->validationError(entryPoint, GL_INVALID_VALUE, kLightParameterOutOfRange);
                return false;
            }
            return true;
        case LightParameter::ConstantAttenuation:
        case LightParameter::LinearAttenuation:
        case LightParameter::QuadraticAttenuation:
            if (params[0] < 0.0f || isNaN(params[0]))
            {
                errors->validationError(entryPoint, GL_INVALID_VALUE, kLightParameterOutOfRange);
                return false;
            }
            return true;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightParameter);
            return false;
    }
}

bool ValidateLightSingleComponent(const PrivateState &state,
                                  ErrorSet *errors,
                                  angle::EntryPoint entryPoint,
                                  GLenum light,
                                  LightParameter pname,
                                  GLfloat param)
{
    if (!ValidateLightCommon(state, errors, entryPoint, light, pname, &param))
    {
        return false;
    }

    if (GetLightParameterCount(pname) > 1)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightParameter);
        return false;
    }

    return true;
}

bool ValidateMaterialCommon(const PrivateState &state,
                            ErrorSet *errors,
                            angle::EntryPoint entryPoint,
                            GLenum face,
                            MaterialParameter pname,
                            const GLfloat *params)
{
    switch (pname)
    {
        case MaterialParameter::Ambient:
        case MaterialParameter::AmbientAndDiffuse:
        case MaterialParameter::Diffuse:
        case MaterialParameter::Specular:
        case MaterialParameter::Emission:
            return true;
        case MaterialParameter::Shininess:
            if (isOutsideOfBounds(params[0], 0.0f, 128.0f))
            {
                errors->validationError(entryPoint, GL_INVALID_VALUE, kMaterialParameterOutOfRange);
                return false;
            }
            return true;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialParameter);
            return false;
    }
}

bool ValidateMaterialSetting(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             GLenum face,
                             MaterialParameter pname,
                             const GLfloat *params)
{
    if (face != GL_FRONT_AND_BACK)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialFace);
        return false;
    }

    return ValidateMaterialCommon(state, errors, entryPoint, face, pname, params);
}

bool ValidateMaterialQuery(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLenum face,
                           MaterialParameter pname)
{
    if (face != GL_FRONT && face != GL_BACK)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialFace);
        return false;
    }

    GLfloat validateParams[4] = {0.0f, 0.0f, 0.0f, 0.0f};

    return ValidateMaterialCommon(state, errors, entryPoint, face, pname, validateParams);
}

bool ValidateMaterialSingleComponent(const PrivateState &state,
                                     ErrorSet *errors,
                                     angle::EntryPoint entryPoint,
                                     GLenum face,
                                     MaterialParameter pname,
                                     GLfloat param)
{
    if (!ValidateMaterialSetting(state, errors, entryPoint, face, pname, &param))
    {
        return false;
    }

    if (GetMaterialParameterCount(pname) > 1)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialParameter);
        return false;
    }

    return true;
}

bool ValidateLightModelCommon(const PrivateState &state,
                              ErrorSet *errors,
                              angle::EntryPoint entryPoint,
                              GLenum pname)
{
    switch (pname)
    {
        case GL_LIGHT_MODEL_AMBIENT:
        case GL_LIGHT_MODEL_TWO_SIDE:
            return true;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightModelParameter);
            return false;
    }
}

bool ValidateLightModelSingleComponent(const PrivateState &state,
                                       ErrorSet *errors,
                                       angle::EntryPoint entryPoint,
                                       GLenum pname)
{
    if (!ValidateLightModelCommon(state, errors, entryPoint, pname))
    {
        return false;
    }

    switch (pname)
    {
        case GL_LIGHT_MODEL_TWO_SIDE:
            return true;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightModelParameter);
            return false;
    }
}

bool ValidateClipPlaneCommon(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             GLenum plane)
{
    if (plane < GL_CLIP_PLANE0 || plane >= GL_CLIP_PLANE0 + state.getCaps().maxClipPlanes)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidClipPlane);
        return false;
    }

    return true;
}

bool ValidateFogCommon(const PrivateState &state,
                       ErrorSet *errors,
                       angle::EntryPoint entryPoint,
                       GLenum pname,
                       const GLfloat *params)
{
    switch (pname)
    {
        case GL_FOG_MODE:
        {
            GLenum modeParam = static_cast<GLenum>(params[0]);
            switch (modeParam)
            {
                case GL_EXP:
                case GL_EXP2:
                case GL_LINEAR:
                    return true;
                default:
                    errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFogMode);
                    return false;
            }
        }
        case GL_FOG_START:
        case GL_FOG_END:
        case GL_FOG_COLOR:
            break;
        case GL_FOG_DENSITY:
            if (params[0] < 0.0f || isNaN(params[0]))
            {
                errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFogDensity);
                return false;
            }
            break;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFogParameter);
            return false;
    }
    return true;
}

bool ValidateTexEnvCommon(const PrivateState &state,
                          ErrorSet *errors,
                          angle::EntryPoint entryPoint,
                          TextureEnvTarget target,
                          TextureEnvParameter pname,
                          const GLfloat *params)
{
    switch (target)
    {
        case TextureEnvTarget::Env:
            switch (pname)
            {
                case TextureEnvParameter::Mode:
                {
                    TextureEnvMode mode = FromGLenum<TextureEnvMode>(ConvertToGLenum(params[0]));
                    switch (mode)
                    {
                        case TextureEnvMode::Add:
                        case TextureEnvMode::Blend:
                        case TextureEnvMode::Combine:
                        case TextureEnvMode::Decal:
                        case TextureEnvMode::Modulate:
                        case TextureEnvMode::Replace:
                            break;
                        default:
                            errors->validationError(entryPoint, GL_INVALID_VALUE,
                                                    kInvalidTextureEnvMode);
                            return false;
                    }
                    break;
                }
                case TextureEnvParameter::CombineRgb:
                case TextureEnvParameter::CombineAlpha:
                {
                    TextureCombine combine = FromGLenum<TextureCombine>(ConvertToGLenum(params[0]));
                    switch (combine)
                    {
                        case TextureCombine::Add:
                        case TextureCombine::AddSigned:
                        case TextureCombine::Interpolate:
                        case TextureCombine::Modulate:
                        case TextureCombine::Replace:
                        case TextureCombine::Subtract:
                            break;
                        case TextureCombine::Dot3Rgb:
                        case TextureCombine::Dot3Rgba:
                            if (pname == TextureEnvParameter::CombineAlpha)
                            {
                                errors->validationError(entryPoint, GL_INVALID_VALUE,
                                                        kInvalidTextureCombine);
                                return false;
                            }
                            break;
                        default:
                            errors->validationError(entryPoint, GL_INVALID_VALUE,
                                                    kInvalidTextureCombine);
                            return false;
                    }
                    break;
                }
                case TextureEnvParameter::Src0Rgb:
                case TextureEnvParameter::Src1Rgb:
                case TextureEnvParameter::Src2Rgb:
                case TextureEnvParameter::Src0Alpha:
                case TextureEnvParameter::Src1Alpha:
                case TextureEnvParameter::Src2Alpha:
                {
                    TextureSrc combine = FromGLenum<TextureSrc>(ConvertToGLenum(params[0]));
                    switch (combine)
                    {
                        case TextureSrc::Constant:
                        case TextureSrc::Previous:
                        case TextureSrc::PrimaryColor:
                        case TextureSrc::Texture:
                            break;
                        default:
                            errors->validationError(entryPoint, GL_INVALID_VALUE,
                                                    kInvalidTextureCombineSrc);
                            return false;
                    }
                    break;
                }
                case TextureEnvParameter::Op0Rgb:
                case TextureEnvParameter::Op1Rgb:
                case TextureEnvParameter::Op2Rgb:
                case TextureEnvParameter::Op0Alpha:
                case TextureEnvParameter::Op1Alpha:
                case TextureEnvParameter::Op2Alpha:
                {
                    TextureOp operand = FromGLenum<TextureOp>(ConvertToGLenum(params[0]));
                    switch (operand)
                    {
                        case TextureOp::SrcAlpha:
                        case TextureOp::OneMinusSrcAlpha:
                            break;
                        case TextureOp::SrcColor:
                        case TextureOp::OneMinusSrcColor:
                            if (pname == TextureEnvParameter::Op0Alpha ||
                                pname == TextureEnvParameter::Op1Alpha ||
                                pname == TextureEnvParameter::Op2Alpha)
                            {
                                errors->validationError(entryPoint, GL_INVALID_VALUE,
                                                        kInvalidTextureCombine);
                                return false;
                            }
                            break;
                        default:
                            errors->validationError(entryPoint, GL_INVALID_VALUE,
                                                    kInvalidTextureCombineOp);
                            return false;
                    }
                    break;
                }
                case TextureEnvParameter::RgbScale:
                case TextureEnvParameter::AlphaScale:
                    if (params[0] != 1.0f && params[0] != 2.0f && params[0] != 4.0f)
                    {
                        errors->validationError(entryPoint, GL_INVALID_VALUE,
                                                kInvalidTextureEnvScale);
                        return false;
                    }
                    break;
                case TextureEnvParameter::Color:
                    break;
                default:
                    errors->validationError(entryPoint, GL_INVALID_ENUM,
                                            kInvalidTextureEnvParameter);
                    return false;
            }
            break;
        case TextureEnvTarget::PointSprite:
            if (!state.getExtensions().pointSpriteOES)
            {
                errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureEnvTarget);
                return false;
            }
            switch (pname)
            {
                case TextureEnvParameter::PointCoordReplace:
                    break;
                default:
                    errors->validationError(entryPoint, GL_INVALID_ENUM,
                                            kInvalidTextureEnvParameter);
                    return false;
            }
            break;
        case TextureEnvTarget::TextureFilterControl:
            if (!state.getExtensions().textureLodBiasEXT)
            {
                errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureEnvTarget);
                return false;
            }
            switch (pname)
            {
                case TextureEnvParameter::LodBias:
                    break;
                default:
                    errors->validationError(entryPoint, GL_INVALID_ENUM,
                                            kInvalidTextureEnvParameter);
                    return false;
            }
            break;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureEnvTarget);
            return false;
    }
    return true;
}

bool ValidateGetTexEnvCommon(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             TextureEnvTarget target,
                             TextureEnvParameter pname)
{
    GLfloat validateParams[4] = {};
    switch (pname)
    {
        case TextureEnvParameter::Mode:
            ConvertPackedEnum(TextureEnvMode::Add, validateParams);
            break;
        case TextureEnvParameter::CombineRgb:
        case TextureEnvParameter::CombineAlpha:
            ConvertPackedEnum(TextureCombine::Add, validateParams);
            break;
        case TextureEnvParameter::Src0Rgb:
        case TextureEnvParameter::Src1Rgb:
        case TextureEnvParameter::Src2Rgb:
        case TextureEnvParameter::Src0Alpha:
        case TextureEnvParameter::Src1Alpha:
        case TextureEnvParameter::Src2Alpha:
            ConvertPackedEnum(TextureSrc::Constant, validateParams);
            break;
        case TextureEnvParameter::Op0Rgb:
        case TextureEnvParameter::Op1Rgb:
        case TextureEnvParameter::Op2Rgb:
        case TextureEnvParameter::Op0Alpha:
        case TextureEnvParameter::Op1Alpha:
        case TextureEnvParameter::Op2Alpha:
            ConvertPackedEnum(TextureOp::SrcAlpha, validateParams);
            break;
        case TextureEnvParameter::RgbScale:
        case TextureEnvParameter::AlphaScale:
        case TextureEnvParameter::PointCoordReplace:
            validateParams[0] = 1.0f;
            break;
        default:
            break;
    }

    return ValidateTexEnvCommon(state, errors, entryPoint, target, pname, validateParams);
}

bool ValidatePointParameterCommon(const PrivateState &state,
                                  ErrorSet *errors,
                                  angle::EntryPoint entryPoint,
                                  PointParameter pname,
                                  const GLfloat *params)
{
    switch (pname)
    {
        case PointParameter::PointSizeMin:
        case PointParameter::PointSizeMax:
        case PointParameter::PointFadeThresholdSize:
        case PointParameter::PointDistanceAttenuation:
            for (unsigned int i = 0; i < GetPointParameterCount(pname); i++)
            {
                const GLfloat paramValue = ANGLE_UNSAFE_TODO(params[i]);
                if (paramValue < 0.0f || isNaN(paramValue))
                {
                    errors->validationError(entryPoint, GL_INVALID_VALUE,
                                            kInvalidPointParameterValue);
                    return false;
                }
            }
            break;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointParameter);
            return false;
    }

    return true;
}

bool ValidatePointSizeCommon(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             GLfloat size)
{
    if (size <= 0.0f || isNaN(size))
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPointSizeValue);
        return false;
    }

    return true;
}

bool ValidateDrawTexCommon(const Context *context,
                           angle::EntryPoint entryPoint,
                           float width,
                           float height)
{
    if (width <= 0.0f || height <= 0.0f || isNaN(width) || isNaN(height))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNonPositiveDrawTextureDimension);
        return false;
    }

    return true;
}

}  // namespace gl

namespace gl
{

bool ValidateAlphaFunc(const PrivateState &state,
                       ErrorSet *errors,
                       angle::EntryPoint entryPoint,
                       AlphaTestFunc func,
                       GLfloat ref)
{
    return ValidateAlphaFuncCommon(state, errors, entryPoint, func);
}

bool ValidateAlphaFuncx(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        AlphaTestFunc func,
                        GLfixed ref)
{
    return ValidateAlphaFuncCommon(state, errors, entryPoint, func);
}

bool ValidateClientActiveTexture(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 GLenum texture)
{
    return ValidateMultitextureUnit(context->getPrivateState(),
                                    context->getMutableErrorSetForValidation(), entryPoint,
                                    texture);
}

bool ValidateClipPlanef(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLenum plane,
                        const GLfloat *eqn)
{
    return ValidateClipPlaneCommon(state, errors, entryPoint, plane);
}

bool ValidateClipPlanex(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLenum plane,
                        const GLfixed *equation)
{
    return ValidateClipPlaneCommon(state, errors, entryPoint, plane);
}

bool ValidateColorPointer(const Context *context,
                          angle::EntryPoint entryPoint,
                          GLint size,
                          VertexAttribType type,
                          GLsizei stride,
                          const void *pointer)
{
    return ValidateBuiltinVertexAttributeCommon(context, entryPoint, ClientVertexArrayType::Color,
                                                size, type, stride, pointer);
}

bool ValidateDisableClientState(const Context *context,
                                angle::EntryPoint entryPoint,
                                ClientVertexArrayType arrayType)
{
    return ValidateClientStateCommon(context, entryPoint, arrayType);
}

bool ValidateEnableClientState(const Context *context,
                               angle::EntryPoint entryPoint,
                               ClientVertexArrayType arrayType)
{
    return ValidateClientStateCommon(context, entryPoint, arrayType);
}

bool ValidateFogf(const PrivateState &state,
                  ErrorSet *errors,
                  angle::EntryPoint entryPoint,
                  GLenum pname,
                  GLfloat param)
{
    return ValidateFogCommon(state, errors, entryPoint, pname, &param);
}

bool ValidateFogfv(const PrivateState &state,
                   ErrorSet *errors,
                   angle::EntryPoint entryPoint,
                   GLenum pname,
                   const GLfloat *params)
{
    return ValidateFogCommon(state, errors, entryPoint, pname, params);
}

bool ValidateFogx(const PrivateState &state,
                  ErrorSet *errors,
                  angle::EntryPoint entryPoint,
                  GLenum pname,
                  GLfixed param)
{
    GLfloat asFloat =
        pname == GL_FOG_MODE ? static_cast<GLfloat>(param) : ConvertFixedToFloat(param);
    return ValidateFogCommon(state, errors, entryPoint, pname, &asFloat);
}

bool ValidateFogxv(const PrivateState &state,
                   ErrorSet *errors,
                   angle::EntryPoint entryPoint,
                   GLenum pname,
                   const GLfixed *params)
{
    unsigned int paramCount = GetFogParameterCount(pname);
    GLfloat paramsf[4]      = {};

    if (pname == GL_FOG_MODE)
    {
        paramsf[0] = static_cast<GLfloat>(params[0]);
    }
    else
    {
        for (unsigned int i = 0; i < paramCount; i++)
        {
            ANGLE_UNSAFE_TODO(paramsf[i] = ConvertFixedToFloat(params[i]));
        }
    }

    return ValidateFogCommon(state, errors, entryPoint, pname, paramsf);
}

bool ValidateFrustumf(const PrivateState &state,
                      ErrorSet *errors,
                      angle::EntryPoint entryPoint,
                      GLfloat l,
                      GLfloat r,
                      GLfloat b,
                      GLfloat t,
                      GLfloat n,
                      GLfloat f)
{
    if (l == r || b == t || n == f || n <= 0.0f || f <= 0.0f)
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix);
        return false;
    }
    return true;
}

bool ValidateFrustumx(const PrivateState &state,
                      ErrorSet *errors,
                      angle::EntryPoint entryPoint,
                      GLfixed l,
                      GLfixed r,
                      GLfixed b,
                      GLfixed t,
                      GLfixed n,
                      GLfixed f)
{
    if (l == r || b == t || n == f || n <= 0 || f <= 0)
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix);
        return false;
    }
    return true;
}

bool ValidateGetClipPlanef(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLenum plane,
                           const GLfloat *equation)
{
    return ValidateClipPlaneCommon(state, errors, entryPoint, plane);
}

bool ValidateGetClipPlanex(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLenum plane,
                           const GLfixed *equation)
{
    return ValidateClipPlaneCommon(state, errors, entryPoint, plane);
}

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

bool ValidateGetLightfv(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLenum light,
                        LightParameter pname,
                        const GLfloat *params)
{
    GLfloat validateParams[4] = {0.0f, 0.0f, 0.0f, 0.0f};
    return ValidateLightCommon(state, errors, entryPoint, light, pname, validateParams);
}

bool ValidateGetLightxv(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLenum light,
                        LightParameter pname,
                        const GLfixed *params)
{
    GLfloat validateParams[4] = {0.0f, 0.0f, 0.0f, 0.0f};
    return ValidateLightCommon(state, errors, entryPoint, light, pname, validateParams);
}

bool ValidateGetMaterialfv(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLenum face,
                           MaterialParameter pname,
                           const GLfloat *params)
{
    return ValidateMaterialQuery(state, errors, entryPoint, face, pname);
}

bool ValidateGetMaterialxv(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           GLenum face,
                           MaterialParameter pname,
                           const GLfixed *params)
{
    return ValidateMaterialQuery(state, errors, entryPoint, face, pname);
}

bool ValidateGetTexEnvfv(const PrivateState &state,
                         ErrorSet *errors,
                         angle::EntryPoint entryPoint,
                         TextureEnvTarget target,
                         TextureEnvParameter pname,
                         const GLfloat *params)
{
    return ValidateGetTexEnvCommon(state, errors, entryPoint, target, pname);
}

bool ValidateGetTexEnviv(const PrivateState &state,
                         ErrorSet *errors,
                         angle::EntryPoint entryPoint,
                         TextureEnvTarget target,
                         TextureEnvParameter pname,
                         const GLint *params)
{
    return ValidateGetTexEnvCommon(state, errors, entryPoint, target, pname);
}

bool ValidateGetTexEnvxv(const PrivateState &state,
                         ErrorSet *errors,
                         angle::EntryPoint entryPoint,
                         TextureEnvTarget target,
                         TextureEnvParameter pname,
                         const GLfixed *params)
{
    return ValidateGetTexEnvCommon(state, errors, entryPoint, target, pname);
}

bool ValidateGetTexParameterxv(const Context *context,
                               angle::EntryPoint entryPoint,
                               TextureType targetPacked,
                               GLenum pname,
                               const GLfixed *params)
{
    return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
}

bool ValidateLightModelf(const PrivateState &state,
                         ErrorSet *errors,
                         angle::EntryPoint entryPoint,
                         GLenum pname,
                         GLfloat param)
{
    return ValidateLightModelSingleComponent(state, errors, entryPoint, pname);
}

bool ValidateLightModelfv(const PrivateState &state,
                          ErrorSet *errors,
                          angle::EntryPoint entryPoint,
                          GLenum pname,
                          const GLfloat *params)
{
    return ValidateLightModelCommon(state, errors, entryPoint, pname);
}

bool ValidateLightModelx(const PrivateState &state,
                         ErrorSet *errors,
                         angle::EntryPoint entryPoint,
                         GLenum pname,
                         GLfixed param)
{
    return ValidateLightModelSingleComponent(state, errors, entryPoint, pname);
}

bool ValidateLightModelxv(const PrivateState &state,
                          ErrorSet *errors,
                          angle::EntryPoint entryPoint,
                          GLenum pname,
                          const GLfixed *param)
{
    return ValidateLightModelCommon(state, errors, entryPoint, pname);
}

bool ValidateLightf(const PrivateState &state,
                    ErrorSet *errors,
                    angle::EntryPoint entryPoint,
                    GLenum light,
                    LightParameter pname,
                    GLfloat param)
{
    return ValidateLightSingleComponent(state, errors, entryPoint, light, pname, param);
}

bool ValidateLightfv(const PrivateState &state,
                     ErrorSet *errors,
                     angle::EntryPoint entryPoint,
                     GLenum light,
                     LightParameter pname,
                     const GLfloat *params)
{
    return ValidateLightCommon(state, errors, entryPoint, light, pname, params);
}

bool ValidateLightx(const PrivateState &state,
                    ErrorSet *errors,
                    angle::EntryPoint entryPoint,
                    GLenum light,
                    LightParameter pname,
                    GLfixed param)
{
    return ValidateLightSingleComponent(state, errors, entryPoint, light, pname,
                                        ConvertFixedToFloat(param));
}

bool ValidateLightxv(const PrivateState &state,
                     ErrorSet *errors,
                     angle::EntryPoint entryPoint,
                     GLenum light,
                     LightParameter pname,
                     const GLfixed *params)
{
    GLfloat paramsf[4];
    for (unsigned int i = 0; i < GetLightParameterCount(pname); i++)
    {
        ANGLE_UNSAFE_TODO(paramsf[i] = ConvertFixedToFloat(params[i]));
    }

    return ValidateLightCommon(state, errors, entryPoint, light, pname, paramsf);
}

bool ValidateLineWidthx(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLfixed width)
{
    if (width <= 0)
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidWidth);
        return false;
    }

    return true;
}

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

bool ValidateMaterialf(const PrivateState &state,
                       ErrorSet *errors,
                       angle::EntryPoint entryPoint,
                       GLenum face,
                       MaterialParameter pname,
                       GLfloat param)
{
    return ValidateMaterialSingleComponent(state, errors, entryPoint, face, pname, param);
}

bool ValidateMaterialfv(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLenum face,
                        MaterialParameter pname,
                        const GLfloat *params)
{
    return ValidateMaterialSetting(state, errors, entryPoint, face, pname, params);
}

bool ValidateMaterialx(const PrivateState &state,
                       ErrorSet *errors,
                       angle::EntryPoint entryPoint,
                       GLenum face,
                       MaterialParameter pname,
                       GLfixed param)
{
    return ValidateMaterialSingleComponent(state, errors, entryPoint, face, pname,
                                           ConvertFixedToFloat(param));
}

bool ValidateMaterialxv(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLenum face,
                        MaterialParameter pname,
                        const GLfixed *params)
{
    GLfloat paramsf[4];

    for (unsigned int i = 0; i < GetMaterialParameterCount(pname); i++)
    {
        ANGLE_UNSAFE_TODO(paramsf[i] = ConvertFixedToFloat(params[i]));
    }

    return ValidateMaterialSetting(state, errors, entryPoint, face, pname, paramsf);
}

bool ValidateMatrixMode(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        MatrixType mode)
{
    switch (mode)
    {
        case MatrixType::Projection:
        case MatrixType::Modelview:
        case MatrixType::Texture:
            return true;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMatrixMode);
            return false;
    }
}

bool ValidateMultiTexCoord4f(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             GLenum target,
                             GLfloat s,
                             GLfloat t,
                             GLfloat r,
                             GLfloat q)
{
    return ValidateMultitextureUnit(state, errors, entryPoint, target);
}

bool ValidateMultiTexCoord4x(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             GLenum target,
                             GLfixed s,
                             GLfixed t,
                             GLfixed r,
                             GLfixed q)
{
    return ValidateMultitextureUnit(state, errors, entryPoint, target);
}

bool ValidateNormalPointer(const Context *context,
                           angle::EntryPoint entryPoint,
                           VertexAttribType type,
                           GLsizei stride,
                           const void *pointer)
{
    return ValidateBuiltinVertexAttributeCommon(context, entryPoint, ClientVertexArrayType::Normal,
                                                3, type, stride, pointer);
}

bool ValidateOrthof(const PrivateState &state,
                    ErrorSet *errors,
                    angle::EntryPoint entryPoint,
                    GLfloat l,
                    GLfloat r,
                    GLfloat b,
                    GLfloat t,
                    GLfloat n,
                    GLfloat f)
{
    // [OpenGL ES 1.1.12] section 2.10.2 page 31:
    // If l is equal to r, b is equal to t, or n is equal to f, the
    // error INVALID VALUE results.
    if (l == r || b == t || n == f)
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix);
        return false;
    }
    return true;
}

bool ValidateOrthox(const PrivateState &state,
                    ErrorSet *errors,
                    angle::EntryPoint entryPoint,
                    GLfixed l,
                    GLfixed r,
                    GLfixed b,
                    GLfixed t,
                    GLfixed n,
                    GLfixed f)
{
    if (l == r || b == t || n == f)
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix);
        return false;
    }
    return true;
}

bool ValidatePointParameterf(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             PointParameter pname,
                             GLfloat param)
{
    unsigned int paramCount = GetPointParameterCount(pname);
    if (paramCount != 1)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointParameter);
        return false;
    }

    return ValidatePointParameterCommon(state, errors, entryPoint, pname, &param);
}

bool ValidatePointParameterfv(const PrivateState &state,
                              ErrorSet *errors,
                              angle::EntryPoint entryPoint,
                              PointParameter pname,
                              const GLfloat *params)
{
    return ValidatePointParameterCommon(state, errors, entryPoint, pname, params);
}

bool ValidatePointParameterx(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             PointParameter pname,
                             GLfixed param)
{
    unsigned int paramCount = GetPointParameterCount(pname);
    if (paramCount != 1)
    {
        errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointParameter);
        return false;
    }

    GLfloat paramf = ConvertFixedToFloat(param);
    return ValidatePointParameterCommon(state, errors, entryPoint, pname, &paramf);
}

bool ValidatePointParameterxv(const PrivateState &state,
                              ErrorSet *errors,
                              angle::EntryPoint entryPoint,
                              PointParameter pname,
                              const GLfixed *params)
{
    GLfloat paramsf[4] = {};
    for (unsigned int i = 0; i < GetPointParameterCount(pname); i++)
    {
        ANGLE_UNSAFE_TODO(paramsf[i] = ConvertFixedToFloat(params[i]));
    }
    return ValidatePointParameterCommon(state, errors, entryPoint, pname, paramsf);
}

bool ValidatePointSize(const PrivateState &state,
                       ErrorSet *errors,
                       angle::EntryPoint entryPoint,
                       GLfloat size)
{
    return ValidatePointSizeCommon(state, errors, entryPoint, size);
}

bool ValidatePointSizex(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        GLfixed size)
{
    return ValidatePointSizeCommon(state, errors, entryPoint, ConvertFixedToFloat(size));
}

bool ValidatePopMatrix(const PrivateState &state, ErrorSet *errors, angle::EntryPoint entryPoint)
{
    const auto &stack = state.gles1().currentMatrixStack();
    if (stack.size() == 1)
    {
        errors->validationError(entryPoint, GL_STACK_UNDERFLOW, kMatrixStackUnderflow);
        return false;
    }
    return true;
}

bool ValidatePushMatrix(const PrivateState &state, ErrorSet *errors, angle::EntryPoint entryPoint)
{
    const auto &stack = state.gles1().currentMatrixStack();
    if (stack.size() == stack.max_size())
    {
        errors->validationError(entryPoint, GL_STACK_OVERFLOW, kMatrixStackOverflow);
        return false;
    }
    return true;
}

bool ValidateShadeModel(const PrivateState &state,
                        ErrorSet *errors,
                        angle::EntryPoint entryPoint,
                        ShadingModel mode)
{
    switch (mode)
    {
        case ShadingModel::Flat:
        case ShadingModel::Smooth:
            return true;
        default:
            errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingModel);
            return false;
    }
}

bool ValidateTexCoordPointer(const Context *context,
                             angle::EntryPoint entryPoint,
                             GLint size,
                             VertexAttribType type,
                             GLsizei stride,
                             const void *pointer)
{
    return ValidateBuiltinVertexAttributeCommon(
        context, entryPoint, ClientVertexArrayType::TextureCoord, size, type, stride, pointer);
}

bool ValidateTexEnvf(const PrivateState &state,
                     ErrorSet *errors,
                     angle::EntryPoint entryPoint,
                     TextureEnvTarget target,
                     TextureEnvParameter pname,
                     GLfloat param)
{
    return ValidateTexEnvCommon(state, errors, entryPoint, target, pname, &param);
}

bool ValidateTexEnvfv(const PrivateState &state,
                      ErrorSet *errors,
                      angle::EntryPoint entryPoint,
                      TextureEnvTarget target,
                      TextureEnvParameter pname,
                      const GLfloat *params)
{
    return ValidateTexEnvCommon(state, errors, entryPoint, target, pname, params);
}

bool ValidateTexEnvi(const PrivateState &state,
                     ErrorSet *errors,
                     angle::EntryPoint entryPoint,
                     TextureEnvTarget target,
                     TextureEnvParameter pname,
                     GLint param)
{
    GLfloat paramf = static_cast<GLfloat>(param);
    return ValidateTexEnvCommon(state, errors, entryPoint, target, pname, &paramf);
}

bool ValidateTexEnviv(const PrivateState &state,
                      ErrorSet *errors,
                      angle::EntryPoint entryPoint,
                      TextureEnvTarget target,
                      TextureEnvParameter pname,
                      const GLint *params)
{
    GLfloat paramsf[4];
    for (unsigned int i = 0; i < GetTextureEnvParameterCount(pname); i++)
    {
        ANGLE_UNSAFE_TODO(paramsf[i] = static_cast<GLfloat>(params[i]));
    }
    return ValidateTexEnvCommon(state, errors, entryPoint, target, pname, paramsf);
}

bool ValidateTexEnvx(const PrivateState &state,
                     ErrorSet *errors,
                     angle::EntryPoint entryPoint,
                     TextureEnvTarget target,
                     TextureEnvParameter pname,
                     GLfixed param)
{
    GLfloat paramsf[4] = {};
    ConvertTextureEnvFromFixed(pname, &param, paramsf);
    return ValidateTexEnvCommon(state, errors, entryPoint, target, pname, paramsf);
}

bool ValidateTexEnvxv(const PrivateState &state,
                      ErrorSet *errors,
                      angle::EntryPoint entryPoint,
                      TextureEnvTarget target,
                      TextureEnvParameter pname,
                      const GLfixed *params)
{
    GLfloat paramsf[4] = {};
    ConvertTextureEnvFromFixed(pname, params, paramsf);
    return ValidateTexEnvCommon(state, errors, entryPoint, target, pname, paramsf);
}

bool ValidateTexParameterBaseForGLfixed(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        TextureType targetPacked,
                                        GLenum pname,
                                        const GLfixed *params)
{
    // Convert GLfixed parameter for GL_TEXTURE_MAX_ANISOTROPY_EXT independently
    // since it compares against 1 and maxTextureAnisotropy instead of just 0
    // (other values are fine to leave unconverted since they only check positive or negative or
    // are used as enums)
    GLfloat paramValue;
    if (pname == GL_TEXTURE_MAX_ANISOTROPY_EXT)
    {
        paramValue = ConvertFixedToFloat(static_cast<GLfixed>(params[0]));
    }
    else
    {
        paramValue = static_cast<GLfloat>(params[0]);
    }
    return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, &paramValue);
}

bool ValidateTexParameterx(const Context *context,
                           angle::EntryPoint entryPoint,
                           TextureType targetPacked,
                           GLenum pname,
                           GLfixed param)
{
    return ValidateTexParameterBaseForGLfixed(context, entryPoint, targetPacked, pname, &param);
}

bool ValidateTexParameterxv(const Context *context,
                            angle::EntryPoint entryPoint,
                            TextureType targetPacked,
                            GLenum pname,
                            const GLfixed *params)
{
    return ValidateTexParameterBaseForGLfixed(context, entryPoint, targetPacked, pname, params);
}

bool ValidateVertexPointer(const Context *context,
                           angle::EntryPoint entryPoint,
                           GLint size,
                           VertexAttribType type,
                           GLsizei stride,
                           const void *pointer)
{
    return ValidateBuiltinVertexAttributeCommon(context, entryPoint, ClientVertexArrayType::Vertex,
                                                size, type, stride, pointer);
}

bool ValidateDrawTexfOES(const Context *context,
                         angle::EntryPoint entryPoint,
                         GLfloat x,
                         GLfloat y,
                         GLfloat z,
                         GLfloat width,
                         GLfloat height)
{
    return ValidateDrawTexCommon(context, entryPoint, width, height);
}

bool ValidateDrawTexfvOES(const Context *context,
                          angle::EntryPoint entryPoint,
                          const GLfloat *coords)
{
    return ValidateDrawTexCommon(context, entryPoint, ANGLE_UNSAFE_TODO(coords[3]),
                                 ANGLE_UNSAFE_TODO(coords[4]));
}

bool ValidateDrawTexiOES(const Context *context,
                         angle::EntryPoint entryPoint,
                         GLint x,
                         GLint y,
                         GLint z,
                         GLint width,
                         GLint height)
{
    return ValidateDrawTexCommon(context, entryPoint, static_cast<GLfloat>(width),
                                 static_cast<GLfloat>(height));
}

bool ValidateDrawTexivOES(const Context *context, angle::EntryPoint entryPoint, const GLint *coords)
{
    return ValidateDrawTexCommon(context, entryPoint,
                                 static_cast<GLfloat>(ANGLE_UNSAFE_TODO(coords[3])),
                                 static_cast<GLfloat>(ANGLE_UNSAFE_TODO(coords[4])));
}

bool ValidateDrawTexsOES(const Context *context,
                         angle::EntryPoint entryPoint,
                         GLshort x,
                         GLshort y,
                         GLshort z,
                         GLshort width,
                         GLshort height)
{
    return ValidateDrawTexCommon(context, entryPoint, static_cast<GLfloat>(width),
                                 static_cast<GLfloat>(height));
}

bool ValidateDrawTexsvOES(const Context *context,
                          angle::EntryPoint entryPoint,
                          const GLshort *coords)
{
    return ValidateDrawTexCommon(context, entryPoint,
                                 static_cast<GLfloat>(ANGLE_UNSAFE_TODO(coords[3])),
                                 static_cast<GLfloat>(ANGLE_UNSAFE_TODO(coords[4])));
}

bool ValidateDrawTexxOES(const Context *context,
                         angle::EntryPoint entryPoint,
                         GLfixed x,
                         GLfixed y,
                         GLfixed z,
                         GLfixed width,
                         GLfixed height)
{
    return ValidateDrawTexCommon(context, entryPoint, ConvertFixedToFloat(width),
                                 ConvertFixedToFloat(height));
}

bool ValidateDrawTexxvOES(const Context *context,
                          angle::EntryPoint entryPoint,
                          const GLfixed *coords)
{
    return ValidateDrawTexCommon(context, entryPoint,
                                 ConvertFixedToFloat(ANGLE_UNSAFE_TODO(coords[3])),
                                 ConvertFixedToFloat(ANGLE_UNSAFE_TODO(coords[4])));
}

bool ValidateCurrentPaletteMatrixOES(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     GLuint matrixpaletteindex)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateMatrixIndexPointerOES(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   GLint size,
                                   GLenum type,
                                   GLsizei stride,
                                   const void *pointer)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateWeightPointerOES(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLint size,
                              GLenum type,
                              GLsizei stride,
                              const void *pointer)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidatePointSizePointerOES(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 VertexAttribType type,
                                 GLsizei stride,
                                 const void *pointer)
{
    return ValidateBuiltinVertexAttributeCommon(
        context, entryPoint, ClientVertexArrayType::PointSize, 1, type, stride, pointer);
}

bool ValidateGenFramebuffersOES(const Context *context,
                                angle::EntryPoint entryPoint,
                                GLsizei n,
                                const FramebufferID *framebuffers)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               framebuffers);
}

bool ValidateDeleteFramebuffersOES(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   GLsizei n,
                                   const FramebufferID *framebuffers)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               framebuffers);
}

bool ValidateGenRenderbuffersOES(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 GLsizei n,
                                 const RenderbufferID *renderbuffers)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               renderbuffers);
}

bool ValidateDeleteRenderbuffersOES(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    GLsizei n,
                                    const RenderbufferID *renderbuffers)
{
    return ValidateGenOrDelete(context->getMutableErrorSetForValidation(), entryPoint, n,
                               renderbuffers);
}

bool ValidateBindFramebufferOES(const Context *context,
                                angle::EntryPoint entryPoint,
                                GLenum target,
                                FramebufferID framebuffer)
{
    return ValidateBindFramebufferBase(context, entryPoint, target, framebuffer);
}

bool ValidateBindRenderbufferOES(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 GLenum target,
                                 RenderbufferID renderbuffer)
{
    return ValidateBindRenderbufferBase(context, entryPoint, target, renderbuffer);
}

bool ValidateCheckFramebufferStatusOES(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLenum target)
{
    return ValidateCheckFramebufferStatus(context, entryPoint, target);
}

bool ValidateFramebufferRenderbufferOES(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        GLenum target,
                                        GLenum attachment,
                                        GLenum rbtarget,
                                        RenderbufferID renderbuffer)
{
    return ValidateFramebufferRenderbufferBase(context, entryPoint, target, attachment, rbtarget,
                                               renderbuffer);
}

bool ValidateFramebufferTexture2DOES(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     GLenum target,
                                     GLenum attachment,
                                     TextureTarget textarget,
                                     TextureID texture,
                                     GLint level)
{
    return ValidateFramebufferTexture2D(context, entryPoint, target, attachment, textarget, texture,
                                        level);
}

bool ValidateGenerateMipmapOES(const Context *context,
                               angle::EntryPoint entryPoint,
                               TextureType target)
{
    return ValidateGenerateMipmapBase(context, entryPoint, target);
}

bool ValidateGetFramebufferAttachmentParameterivOES(const Context *context,
                                                    angle::EntryPoint entryPoint,
                                                    GLenum target,
                                                    GLenum attachment,
                                                    GLenum pname,
                                                    const GLint *params)
{
    return ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment,
                                                           pname, nullptr);
}

bool ValidateGetRenderbufferParameterivOES(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           GLenum target,
                                           GLenum pname,
                                           const GLint *params)
{
    return ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, nullptr);
}

bool ValidateRenderbufferStorageOES(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    GLenum target,
                                    GLenum internalformat,
                                    GLsizei width,
                                    GLsizei height)
{
    return ValidateRenderbufferStorageParametersBase(context, entryPoint, target, 0, internalformat,
                                                     width, height);
}

// GL_OES_texture_cube_map

bool ValidateGetTexGenfvOES(const Context *context,
                            angle::EntryPoint entryPoint,
                            GLenum coord,
                            GLenum pname,
                            const GLfloat *params)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateGetTexGenivOES(const Context *context,
                            angle::EntryPoint entryPoint,
                            GLenum coord,
                            GLenum pname,
                            const int *params)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateGetTexGenxvOES(const Context *context,
                            angle::EntryPoint entryPoint,
                            GLenum coord,
                            GLenum pname,
                            const GLfixed *params)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateTexGenfvOES(const Context *context,
                         angle::EntryPoint entryPoint,
                         GLenum coord,
                         GLenum pname,
                         const GLfloat *params)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateTexGenivOES(const Context *context,
                         angle::EntryPoint entryPoint,
                         GLenum coord,
                         GLenum pname,
                         const GLint *param)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateTexGenxvOES(const Context *context,
                         angle::EntryPoint entryPoint,
                         GLenum coord,
                         GLenum pname,
                         const GLint *param)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateTexGenfOES(const Context *context,
                        angle::EntryPoint entryPoint,
                        GLenum coord,
                        GLenum pname,
                        GLfloat param)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateTexGeniOES(const Context *context,
                        angle::EntryPoint entryPoint,
                        GLenum coord,
                        GLenum pname,
                        GLint param)
{
    UNIMPLEMENTED();
    return true;
}

bool ValidateTexGenxOES(const Context *context,
                        angle::EntryPoint entryPoint,
                        GLenum coord,
                        GLenum pname,
                        GLfixed param)
{
    UNIMPLEMENTED();
    return true;
}

}  // namespace gl
