tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

validationESEXT.cpp (132228B)


      1 //
      2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 // validationESEXT.cpp: Validation functions for OpenGL ES extension entry points.
      7 
      8 #include "libANGLE/validationESEXT_autogen.h"
      9 
     10 #include "libANGLE/Context.h"
     11 #include "libANGLE/ErrorStrings.h"
     12 #include "libANGLE/MemoryObject.h"
     13 #include "libANGLE/PixelLocalStorage.h"
     14 #include "libANGLE/validationES.h"
     15 #include "libANGLE/validationES2.h"
     16 #include "libANGLE/validationES3.h"
     17 #include "libANGLE/validationES31.h"
     18 #include "libANGLE/validationES32.h"
     19 
     20 namespace gl
     21 {
     22 using namespace err;
     23 
     24 namespace
     25 {
     26 template <typename ObjectT>
     27 bool ValidateGetImageFormatAndType(const Context *context,
     28                                   angle::EntryPoint entryPoint,
     29                                   ObjectT *obj,
     30                                   GLenum format,
     31                                   GLenum type)
     32 {
     33    GLenum implFormat = obj->getImplementationColorReadFormat(context);
     34    if (!ValidES3Format(format) && (format != implFormat || format == GL_NONE))
     35    {
     36        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
     37        return false;
     38    }
     39 
     40    GLenum implType = obj->getImplementationColorReadType(context);
     41    if (!ValidES3Type(type) && (type != implType || type == GL_NONE))
     42    {
     43        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
     44        return false;
     45    }
     46 
     47    // Format/type combinations are not yet validated.
     48 
     49    return true;
     50 }
     51 
     52 bool IsValidImageLayout(ImageLayout layout)
     53 {
     54    switch (layout)
     55    {
     56        case ImageLayout::Undefined:
     57        case ImageLayout::General:
     58        case ImageLayout::ColorAttachment:
     59        case ImageLayout::DepthStencilAttachment:
     60        case ImageLayout::DepthStencilReadOnlyAttachment:
     61        case ImageLayout::ShaderReadOnly:
     62        case ImageLayout::TransferSrc:
     63        case ImageLayout::TransferDst:
     64        case ImageLayout::DepthReadOnlyStencilAttachment:
     65        case ImageLayout::DepthAttachmentStencilReadOnly:
     66            return true;
     67 
     68        default:
     69            return false;
     70    }
     71 }
     72 
     73 bool IsValidMemoryObjectParamater(const Context *context,
     74                                  angle::EntryPoint entryPoint,
     75                                  GLenum pname)
     76 {
     77    switch (pname)
     78    {
     79        case GL_DEDICATED_MEMORY_OBJECT_EXT:
     80            return true;
     81 
     82        case GL_PROTECTED_MEMORY_OBJECT_EXT:
     83            if (!context->getExtensions().protectedTexturesEXT)
     84            {
     85                context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
     86                return false;
     87            }
     88            return true;
     89 
     90        default:
     91            return false;
     92    }
     93 }
     94 
     95 bool ValidateObjectIdentifierAndName(const Context *context,
     96                                     angle::EntryPoint entryPoint,
     97                                     GLenum identifier,
     98                                     GLuint name)
     99 {
    100    bool isGLES11 = context->getClientVersion() == Version(1, 1);
    101    bool isGLES3  = context->getClientMajorVersion() >= 3;
    102    bool isGLES31 = context->getClientVersion() >= Version(3, 1);
    103    switch (identifier)
    104    {
    105        case GL_BUFFER_OBJECT_EXT:
    106            if (context->getBuffer({name}) == nullptr)
    107            {
    108                context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName);
    109                return false;
    110            }
    111            return true;
    112 
    113        case GL_SHADER_OBJECT_EXT:
    114            if (isGLES11)
    115            {
    116                context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
    117                return false;
    118            }
    119            if (context->getShader({name}) == nullptr)
    120            {
    121                context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShaderName);
    122                return false;
    123            }
    124            return true;
    125 
    126        case GL_PROGRAM_OBJECT_EXT:
    127            if (isGLES11)
    128            {
    129                context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
    130                return false;
    131            }
    132            if (context->getProgramNoResolveLink({name}) == nullptr)
    133            {
    134                context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidProgramName);
    135                return false;
    136            }
    137            return true;
    138 
    139        case GL_VERTEX_ARRAY_OBJECT_EXT:
    140            if (!isGLES3 && !context->getExtensions().vertexArrayObjectOES)
    141            {
    142                context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
    143                return false;
    144            }
    145            if (context->getVertexArray({name}) == nullptr)
    146            {
    147                context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidVertexArrayName);
    148                return false;
    149            }
    150            return true;
    151 
    152        case GL_QUERY_OBJECT_EXT:
    153            if (!isGLES3 && !context->getExtensions().occlusionQueryBooleanEXT)
    154            {
    155                context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
    156                return false;
    157            }
    158            if (context->getQuery({name}) == nullptr)
    159            {
    160                context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryName);
    161                return false;
    162            }
    163            return true;
    164 
    165        case GL_TRANSFORM_FEEDBACK:
    166            if (!isGLES3)
    167            {
    168                context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
    169                return false;
    170            }
    171            if (context->getTransformFeedback({name}) == nullptr)
    172            {
    173                context->validationError(entryPoint, GL_INVALID_OPERATION,
    174                                         kInvalidTransformFeedbackName);
    175                return false;
    176            }
    177            return true;
    178 
    179        case GL_SAMPLER:
    180            if (!isGLES3)
    181            {
    182                context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
    183                return false;
    184            }
    185            if (context->getSampler({name}) == nullptr)
    186            {
    187                context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSamplerName);
    188                return false;
    189            }
    190            return true;
    191 
    192        case GL_TEXTURE:
    193            if (context->getTexture({name}) == nullptr)
    194            {
    195                context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
    196                return false;
    197            }
    198            return true;
    199 
    200        case GL_RENDERBUFFER:
    201            if (!context->isRenderbuffer({name}))
    202            {
    203                context->validationError(entryPoint, GL_INVALID_OPERATION,
    204                                         kInvalidRenderbufferName);
    205                return false;
    206            }
    207            return true;
    208 
    209        case GL_FRAMEBUFFER:
    210            if (context->getFramebuffer({name}) == nullptr)
    211            {
    212                context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFramebufferName);
    213                return false;
    214            }
    215            return true;
    216 
    217        case GL_PROGRAM_PIPELINE_OBJECT_EXT:
    218            if (!isGLES31 && !context->getExtensions().separateShaderObjectsEXT)
    219            {
    220                context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
    221                return false;
    222            }
    223            if (context->getProgramPipeline({name}) == nullptr)
    224            {
    225                context->validationError(entryPoint, GL_INVALID_OPERATION,
    226                                         kInvalidProgramPipelineName);
    227                return false;
    228            }
    229            return true;
    230 
    231        default:
    232            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidIndentifier);
    233            return false;
    234    }
    235 }
    236 }  // namespace
    237 
    238 bool ValidateGetTexImage(const Context *context,
    239                         angle::EntryPoint entryPoint,
    240                         TextureTarget target,
    241                         GLint level)
    242 {
    243    if (!context->getExtensions().getImageANGLE)
    244    {
    245        context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
    246        return false;
    247    }
    248 
    249    if (!ValidTexture2DDestinationTarget(context, target) &&
    250        !ValidTexture3DDestinationTarget(context, target))
    251    {
    252        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
    253        return false;
    254    }
    255 
    256    if (level < 0)
    257    {
    258        context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel);
    259        return false;
    260    }
    261 
    262    TextureType textureType = TextureTargetToType(target);
    263    if (!ValidMipLevel(context, textureType, level))
    264    {
    265        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
    266        return false;
    267    }
    268 
    269    return true;
    270 }
    271 
    272 bool ValidateGetTexImageANGLE(const Context *context,
    273                              angle::EntryPoint entryPoint,
    274                              TextureTarget target,
    275                              GLint level,
    276                              GLenum format,
    277                              GLenum type,
    278                              const void *pixels)
    279 {
    280    if (!ValidateGetTexImage(context, entryPoint, target, level))
    281    {
    282        return false;
    283    }
    284 
    285    Texture *texture = context->getTextureByTarget(target);
    286 
    287    if (!ValidateGetImageFormatAndType(context, entryPoint, texture, format, type))
    288    {
    289        return false;
    290    }
    291 
    292    GLsizei width  = static_cast<GLsizei>(texture->getWidth(target, level));
    293    GLsizei height = static_cast<GLsizei>(texture->getHeight(target, level));
    294    if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr,
    295                           pixels))
    296    {
    297        return false;
    298    }
    299 
    300    if (texture->getFormat(target, level).info->compressed)
    301    {
    302        context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageCompressed);
    303        return false;
    304    }
    305 
    306    return true;
    307 }
    308 
    309 bool ValidateGetCompressedTexImageANGLE(const Context *context,
    310                                        angle::EntryPoint entryPoint,
    311                                        TextureTarget target,
    312                                        GLint level,
    313                                        const void *pixels)
    314 {
    315    if (!ValidateGetTexImage(context, entryPoint, target, level))
    316    {
    317        return false;
    318    }
    319 
    320    Texture *texture = context->getTextureByTarget(target);
    321    if (!texture->getFormat(target, level).info->compressed)
    322    {
    323        context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageNotCompressed);
    324        return false;
    325    }
    326 
    327    if (texture->isCompressedFormatEmulated(context, target, level))
    328    {
    329        // TODO (anglebug.com/7464): We can't currently read back from an emulated format
    330        context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidEmulatedFormat);
    331        return false;
    332    }
    333 
    334    return true;
    335 }
    336 
    337 bool ValidateGetRenderbufferImageANGLE(const Context *context,
    338                                       angle::EntryPoint entryPoint,
    339                                       GLenum target,
    340                                       GLenum format,
    341                                       GLenum type,
    342                                       const void *pixels)
    343 {
    344    if (!context->getExtensions().getImageANGLE)
    345    {
    346        context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
    347        return false;
    348    }
    349 
    350    if (target != GL_RENDERBUFFER)
    351    {
    352        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget);
    353        return false;
    354    }
    355 
    356    Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
    357 
    358    if (!ValidateGetImageFormatAndType(context, entryPoint, renderbuffer, format, type))
    359    {
    360        return false;
    361    }
    362 
    363    GLsizei width  = renderbuffer->getWidth();
    364    GLsizei height = renderbuffer->getHeight();
    365    if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr,
    366                           pixels))
    367    {
    368        return false;
    369    }
    370 
    371    return true;
    372 }
    373 
    374 bool ValidateDrawElementsBaseVertexEXT(const Context *context,
    375                                       angle::EntryPoint entryPoint,
    376                                       PrimitiveMode mode,
    377                                       GLsizei count,
    378                                       DrawElementsType type,
    379                                       const void *indices,
    380                                       GLint basevertex)
    381 {
    382    if (!context->getExtensions().drawElementsBaseVertexAny())
    383    {
    384        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    385        return false;
    386    }
    387 
    388    return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
    389 }
    390 
    391 bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context,
    392                                                angle::EntryPoint entryPoint,
    393                                                PrimitiveMode mode,
    394                                                GLsizei count,
    395                                                DrawElementsType type,
    396                                                const void *indices,
    397                                                GLsizei instancecount,
    398                                                GLint basevertex)
    399 {
    400    if (!context->getExtensions().drawElementsBaseVertexAny())
    401    {
    402        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    403        return false;
    404    }
    405 
    406    return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
    407                                             instancecount);
    408 }
    409 
    410 bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context,
    411                                            angle::EntryPoint entryPoint,
    412                                            PrimitiveMode mode,
    413                                            GLuint start,
    414                                            GLuint end,
    415                                            GLsizei count,
    416                                            DrawElementsType type,
    417                                            const void *indices,
    418                                            GLint basevertex)
    419 {
    420    if (!context->getExtensions().drawElementsBaseVertexAny())
    421    {
    422        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    423        return false;
    424    }
    425 
    426    if (end < start)
    427    {
    428        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange);
    429        return false;
    430    }
    431 
    432    if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0))
    433    {
    434        return false;
    435    }
    436 
    437    // Skip range checks for no-op calls.
    438    if (count <= 0)
    439    {
    440        return true;
    441    }
    442 
    443    // Note that resolving the index range is a bit slow. We should probably optimize this.
    444    IndexRange indexRange;
    445    ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
    446                                                                             indices, &indexRange));
    447 
    448    if (indexRange.end > end || indexRange.start < start)
    449    {
    450        // GL spec says that behavior in this case is undefined - generating an error is fine.
    451        context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsElementRange);
    452        return false;
    453    }
    454    return true;
    455 }
    456 
    457 bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context,
    458                                            angle::EntryPoint entryPoint,
    459                                            PrimitiveMode mode,
    460                                            const GLsizei *count,
    461                                            DrawElementsType type,
    462                                            const void *const *indices,
    463                                            GLsizei drawcount,
    464                                            const GLint *basevertex)
    465 {
    466    return true;
    467 }
    468 
    469 bool ValidateMultiDrawArraysIndirectEXT(const Context *context,
    470                                        angle::EntryPoint entryPoint,
    471                                        PrimitiveMode modePacked,
    472                                        const void *indirect,
    473                                        GLsizei drawcount,
    474                                        GLsizei stride)
    475 {
    476    if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride))
    477    {
    478        return false;
    479    }
    480 
    481    if (!ValidateDrawArraysIndirect(context, entryPoint, modePacked, indirect))
    482    {
    483        return false;
    484    }
    485 
    486    return true;
    487 }
    488 
    489 bool ValidateMultiDrawElementsIndirectEXT(const Context *context,
    490                                          angle::EntryPoint entryPoint,
    491                                          PrimitiveMode modePacked,
    492                                          DrawElementsType typePacked,
    493                                          const void *indirect,
    494                                          GLsizei drawcount,
    495                                          GLsizei stride)
    496 {
    497    if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride))
    498    {
    499        return false;
    500    }
    501 
    502    const State &state                      = context->getState();
    503    TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
    504    if (!ValidateDrawElementsIndirect(context, entryPoint, modePacked, typePacked, indirect))
    505    {
    506        return false;
    507    }
    508 
    509    if (curTransformFeedback && curTransformFeedback->isActive() &&
    510        !curTransformFeedback->isPaused())
    511    {
    512        // EXT_geometry_shader allows transform feedback to work with all draw commands.
    513        // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
    514        if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2)
    515        {
    516            if (!ValidateTransformFeedbackPrimitiveMode(
    517                    context, entryPoint, curTransformFeedback->getPrimitiveMode(), modePacked))
    518            {
    519                context->validationError(entryPoint, GL_INVALID_OPERATION,
    520                                         kInvalidDrawModeTransformFeedback);
    521                return false;
    522            }
    523        }
    524        else
    525        {
    526            // An INVALID_OPERATION error is generated if transform feedback is active and not
    527            // paused.
    528            context->validationError(entryPoint, GL_INVALID_OPERATION,
    529                                     kUnsupportedDrawModeForTransformFeedback);
    530            return false;
    531        }
    532    }
    533 
    534    return true;
    535 }
    536 
    537 bool ValidateDrawArraysInstancedBaseInstanceEXT(const Context *context,
    538                                                angle::EntryPoint entryPoint,
    539                                                PrimitiveMode mode,
    540                                                GLint first,
    541                                                GLsizei count,
    542                                                GLsizei instanceCount,
    543                                                GLuint baseInstance)
    544 {
    545    if (!context->getExtensions().baseInstanceEXT)
    546    {
    547        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    548        return false;
    549    }
    550 
    551    return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, instanceCount);
    552 }
    553 
    554 bool ValidateDrawElementsInstancedBaseInstanceEXT(const Context *context,
    555                                                  angle::EntryPoint entryPoint,
    556                                                  PrimitiveMode mode,
    557                                                  GLsizei count,
    558                                                  DrawElementsType type,
    559                                                  void const *indices,
    560                                                  GLsizei instancecount,
    561                                                  GLuint baseinstance)
    562 {
    563    if (!context->getExtensions().baseInstanceEXT)
    564    {
    565        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    566        return false;
    567    }
    568 
    569    return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
    570                                             instancecount);
    571 }
    572 
    573 bool ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context *context,
    574                                                            angle::EntryPoint entryPoint,
    575                                                            PrimitiveMode mode,
    576                                                            GLsizei count,
    577                                                            DrawElementsType typePacked,
    578                                                            const void *indices,
    579                                                            GLsizei instancecount,
    580                                                            GLint basevertex,
    581                                                            GLuint baseinstance)
    582 {
    583    if (!context->getExtensions().baseInstanceEXT)
    584    {
    585        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    586        return false;
    587    }
    588 
    589    return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, typePacked, indices,
    590                                             instancecount);
    591 }
    592 
    593 bool ValidateDrawElementsBaseVertexOES(const Context *context,
    594                                       angle::EntryPoint entryPoint,
    595                                       PrimitiveMode mode,
    596                                       GLsizei count,
    597                                       DrawElementsType type,
    598                                       const void *indices,
    599                                       GLint basevertex)
    600 {
    601    if (!context->getExtensions().drawElementsBaseVertexAny())
    602    {
    603        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    604        return false;
    605    }
    606 
    607    return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
    608 }
    609 
    610 bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context,
    611                                                angle::EntryPoint entryPoint,
    612                                                PrimitiveMode mode,
    613                                                GLsizei count,
    614                                                DrawElementsType type,
    615                                                const void *indices,
    616                                                GLsizei instancecount,
    617                                                GLint basevertex)
    618 {
    619    if (!context->getExtensions().drawElementsBaseVertexAny())
    620    {
    621        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    622        return false;
    623    }
    624 
    625    return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
    626                                             instancecount);
    627 }
    628 
    629 bool ValidateDrawRangeElementsBaseVertexOES(const Context *context,
    630                                            angle::EntryPoint entryPoint,
    631                                            PrimitiveMode mode,
    632                                            GLuint start,
    633                                            GLuint end,
    634                                            GLsizei count,
    635                                            DrawElementsType type,
    636                                            const void *indices,
    637                                            GLint basevertex)
    638 {
    639    if (!context->getExtensions().drawElementsBaseVertexAny())
    640    {
    641        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    642        return false;
    643    }
    644 
    645    if (end < start)
    646    {
    647        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange);
    648        return false;
    649    }
    650 
    651    if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0))
    652    {
    653        return false;
    654    }
    655 
    656    // Skip range checks for no-op calls.
    657    if (count <= 0)
    658    {
    659        return true;
    660    }
    661 
    662    // Note that resolving the index range is a bit slow. We should probably optimize this.
    663    IndexRange indexRange;
    664    ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
    665                                                                             indices, &indexRange));
    666 
    667    if (indexRange.end > end || indexRange.start < start)
    668    {
    669        // GL spec says that behavior in this case is undefined - generating an error is fine.
    670        context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsElementRange);
    671        return false;
    672    }
    673    return true;
    674 }
    675 
    676 // GL_KHR_blend_equation_advanced
    677 bool ValidateBlendBarrierKHR(const Context *context, angle::EntryPoint entryPoint)
    678 {
    679    const Extensions &extensions = context->getExtensions();
    680 
    681    if (!extensions.blendEquationAdvancedKHR)
    682    {
    683        context->validationError(entryPoint, GL_INVALID_ENUM, kAdvancedBlendExtensionNotEnabled);
    684    }
    685 
    686    return true;
    687 }
    688 
    689 bool ValidateBlendEquationSeparateiEXT(const Context *context,
    690                                       angle::EntryPoint entryPoint,
    691                                       GLuint buf,
    692                                       GLenum modeRGB,
    693                                       GLenum modeAlpha)
    694 {
    695    if (!context->getExtensions().drawBuffersIndexedEXT)
    696    {
    697        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    698        return false;
    699    }
    700 
    701    return ValidateBlendEquationSeparatei(context, entryPoint, buf, modeRGB, modeAlpha);
    702 }
    703 
    704 bool ValidateBlendEquationiEXT(const Context *context,
    705                               angle::EntryPoint entryPoint,
    706                               GLuint buf,
    707                               GLenum mode)
    708 {
    709    if (!context->getExtensions().drawBuffersIndexedEXT)
    710    {
    711        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    712        return false;
    713    }
    714 
    715    return ValidateBlendEquationi(context, entryPoint, buf, mode);
    716 }
    717 
    718 bool ValidateBlendFuncSeparateiEXT(const Context *context,
    719                                   angle::EntryPoint entryPoint,
    720                                   GLuint buf,
    721                                   GLenum srcRGB,
    722                                   GLenum dstRGB,
    723                                   GLenum srcAlpha,
    724                                   GLenum dstAlpha)
    725 {
    726    if (!context->getExtensions().drawBuffersIndexedEXT)
    727    {
    728        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    729        return false;
    730    }
    731 
    732    return ValidateBlendFuncSeparatei(context, entryPoint, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
    733 }
    734 
    735 bool ValidateBlendFunciEXT(const Context *context,
    736                           angle::EntryPoint entryPoint,
    737                           GLuint buf,
    738                           GLenum src,
    739                           GLenum dst)
    740 {
    741    if (!context->getExtensions().drawBuffersIndexedEXT)
    742    {
    743        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    744        return false;
    745    }
    746 
    747    return ValidateBlendFunci(context, entryPoint, buf, src, dst);
    748 }
    749 
    750 bool ValidateColorMaskiEXT(const Context *context,
    751                           angle::EntryPoint entryPoint,
    752                           GLuint index,
    753                           GLboolean r,
    754                           GLboolean g,
    755                           GLboolean b,
    756                           GLboolean a)
    757 {
    758    if (!context->getExtensions().drawBuffersIndexedEXT)
    759    {
    760        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    761        return false;
    762    }
    763 
    764    return ValidateColorMaski(context, entryPoint, index, r, g, b, a);
    765 }
    766 
    767 bool ValidateDisableiEXT(const Context *context,
    768                         angle::EntryPoint entryPoint,
    769                         GLenum target,
    770                         GLuint index)
    771 {
    772    if (!context->getExtensions().drawBuffersIndexedEXT)
    773    {
    774        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    775        return false;
    776    }
    777 
    778    return ValidateDisablei(context, entryPoint, target, index);
    779 }
    780 
    781 bool ValidateEnableiEXT(const Context *context,
    782                        angle::EntryPoint entryPoint,
    783                        GLenum target,
    784                        GLuint index)
    785 {
    786    if (!context->getExtensions().drawBuffersIndexedEXT)
    787    {
    788        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    789        return false;
    790    }
    791 
    792    return ValidateEnablei(context, entryPoint, target, index);
    793 }
    794 
    795 bool ValidateIsEnablediEXT(const Context *context,
    796                           angle::EntryPoint entryPoint,
    797                           GLenum target,
    798                           GLuint index)
    799 {
    800    if (!context->getExtensions().drawBuffersIndexedEXT)
    801    {
    802        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    803        return false;
    804    }
    805 
    806    return ValidateIsEnabledi(context, entryPoint, target, index);
    807 }
    808 
    809 bool ValidateBlendEquationSeparateiOES(const Context *context,
    810                                       angle::EntryPoint entryPoint,
    811                                       GLuint buf,
    812                                       GLenum modeRGB,
    813                                       GLenum modeAlpha)
    814 {
    815    if (!context->getExtensions().drawBuffersIndexedOES)
    816    {
    817        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    818        return false;
    819    }
    820 
    821    return ValidateBlendEquationSeparatei(context, entryPoint, buf, modeRGB, modeAlpha);
    822 }
    823 
    824 bool ValidateBlendEquationiOES(const Context *context,
    825                               angle::EntryPoint entryPoint,
    826                               GLuint buf,
    827                               GLenum mode)
    828 {
    829    if (!context->getExtensions().drawBuffersIndexedOES)
    830    {
    831        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    832        return false;
    833    }
    834 
    835    return ValidateBlendEquationi(context, entryPoint, buf, mode);
    836 }
    837 
    838 bool ValidateBlendFuncSeparateiOES(const Context *context,
    839                                   angle::EntryPoint entryPoint,
    840                                   GLuint buf,
    841                                   GLenum srcRGB,
    842                                   GLenum dstRGB,
    843                                   GLenum srcAlpha,
    844                                   GLenum dstAlpha)
    845 {
    846    if (!context->getExtensions().drawBuffersIndexedOES)
    847    {
    848        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    849        return false;
    850    }
    851 
    852    return ValidateBlendFuncSeparatei(context, entryPoint, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
    853 }
    854 
    855 bool ValidateBlendFunciOES(const Context *context,
    856                           angle::EntryPoint entryPoint,
    857                           GLuint buf,
    858                           GLenum src,
    859                           GLenum dst)
    860 {
    861    if (!context->getExtensions().drawBuffersIndexedOES)
    862    {
    863        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    864        return false;
    865    }
    866 
    867    return ValidateBlendFunci(context, entryPoint, buf, src, dst);
    868 }
    869 
    870 bool ValidateColorMaskiOES(const Context *context,
    871                           angle::EntryPoint entryPoint,
    872                           GLuint index,
    873                           GLboolean r,
    874                           GLboolean g,
    875                           GLboolean b,
    876                           GLboolean a)
    877 {
    878    if (!context->getExtensions().drawBuffersIndexedOES)
    879    {
    880        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    881        return false;
    882    }
    883 
    884    return ValidateColorMaski(context, entryPoint, index, r, g, b, a);
    885 }
    886 
    887 bool ValidateDisableiOES(const Context *context,
    888                         angle::EntryPoint entryPoint,
    889                         GLenum target,
    890                         GLuint index)
    891 {
    892    if (!context->getExtensions().drawBuffersIndexedOES)
    893    {
    894        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    895        return false;
    896    }
    897 
    898    return ValidateDisablei(context, entryPoint, target, index);
    899 }
    900 
    901 bool ValidateEnableiOES(const Context *context,
    902                        angle::EntryPoint entryPoint,
    903                        GLenum target,
    904                        GLuint index)
    905 {
    906    if (!context->getExtensions().drawBuffersIndexedOES)
    907    {
    908        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    909        return false;
    910    }
    911 
    912    return ValidateEnablei(context, entryPoint, target, index);
    913 }
    914 
    915 bool ValidateIsEnablediOES(const Context *context,
    916                           angle::EntryPoint entryPoint,
    917                           GLenum target,
    918                           GLuint index)
    919 {
    920    if (!context->getExtensions().drawBuffersIndexedOES)
    921    {
    922        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    923        return false;
    924    }
    925 
    926    return ValidateIsEnabledi(context, entryPoint, target, index);
    927 }
    928 
    929 bool ValidateGetInteger64vEXT(const Context *context,
    930                              angle::EntryPoint entryPoint,
    931                              GLenum pname,
    932                              const GLint64 *data)
    933 {
    934    if (!context->getExtensions().disjointTimerQueryEXT)
    935    {
    936        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    937        return false;
    938    }
    939 
    940    GLenum nativeType      = GL_NONE;
    941    unsigned int numParams = 0;
    942    if (!ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams))
    943    {
    944        return false;
    945    }
    946 
    947    return true;
    948 }
    949 
    950 bool ValidateCopyImageSubDataEXT(const Context *context,
    951                                 angle::EntryPoint entryPoint,
    952                                 GLuint srcName,
    953                                 GLenum srcTarget,
    954                                 GLint srcLevel,
    955                                 GLint srcX,
    956                                 GLint srcY,
    957                                 GLint srcZ,
    958                                 GLuint dstName,
    959                                 GLenum dstTarget,
    960                                 GLint dstLevel,
    961                                 GLint dstX,
    962                                 GLint dstY,
    963                                 GLint dstZ,
    964                                 GLsizei srcWidth,
    965                                 GLsizei srcHeight,
    966                                 GLsizei srcDepth)
    967 {
    968    if (!context->getExtensions().copyImageEXT)
    969    {
    970        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
    971        return false;
    972    }
    973 
    974    return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX,
    975                                        srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
    976                                        srcWidth, srcHeight, srcDepth);
    977 }
    978 
    979 bool ValidateCopyImageSubDataOES(const Context *context,
    980                                 angle::EntryPoint entryPoint,
    981                                 GLuint srcName,
    982                                 GLenum srcTarget,
    983                                 GLint srcLevel,
    984                                 GLint srcX,
    985                                 GLint srcY,
    986                                 GLint srcZ,
    987                                 GLuint dstName,
    988                                 GLenum dstTarget,
    989                                 GLint dstLevel,
    990                                 GLint dstX,
    991                                 GLint dstY,
    992                                 GLint dstZ,
    993                                 GLsizei srcWidth,
    994                                 GLsizei srcHeight,
    995                                 GLsizei srcDepth)
    996 {
    997    if (!context->getExtensions().copyImageEXT)
    998    {
    999        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1000        return false;
   1001    }
   1002 
   1003    return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX,
   1004                                        srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
   1005                                        srcWidth, srcHeight, srcDepth);
   1006 }
   1007 
   1008 bool ValidateBufferStorageMemEXT(const Context *context,
   1009                                 angle::EntryPoint entryPoint,
   1010                                 TextureType target,
   1011                                 GLsizeiptr size,
   1012                                 MemoryObjectID memory,
   1013                                 GLuint64 offset)
   1014 {
   1015    if (!context->getExtensions().memoryObjectEXT)
   1016    {
   1017        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1018        return false;
   1019    }
   1020 
   1021    UNIMPLEMENTED();
   1022    return false;
   1023 }
   1024 
   1025 bool ValidateCreateMemoryObjectsEXT(const Context *context,
   1026                                    angle::EntryPoint entryPoint,
   1027                                    GLsizei n,
   1028                                    const MemoryObjectID *memoryObjects)
   1029 {
   1030    if (!context->getExtensions().memoryObjectEXT)
   1031    {
   1032        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1033        return false;
   1034    }
   1035 
   1036    return ValidateGenOrDelete(context, entryPoint, n);
   1037 }
   1038 
   1039 bool ValidateDeleteMemoryObjectsEXT(const Context *context,
   1040                                    angle::EntryPoint entryPoint,
   1041                                    GLsizei n,
   1042                                    const MemoryObjectID *memoryObjects)
   1043 {
   1044    if (!context->getExtensions().memoryObjectEXT)
   1045    {
   1046        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1047        return false;
   1048    }
   1049 
   1050    return ValidateGenOrDelete(context, entryPoint, n);
   1051 }
   1052 
   1053 bool ValidateGetMemoryObjectParameterivEXT(const Context *context,
   1054                                           angle::EntryPoint entryPoint,
   1055                                           MemoryObjectID memoryObject,
   1056                                           GLenum pname,
   1057                                           const GLint *params)
   1058 {
   1059    if (!context->getExtensions().memoryObjectEXT)
   1060    {
   1061        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1062        return false;
   1063    }
   1064 
   1065    const MemoryObject *memory = context->getMemoryObject(memoryObject);
   1066    if (memory == nullptr)
   1067    {
   1068        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryObject);
   1069    }
   1070 
   1071    if (!IsValidMemoryObjectParamater(context, entryPoint, pname))
   1072    {
   1073        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
   1074        return false;
   1075    }
   1076 
   1077    return true;
   1078 }
   1079 
   1080 bool ValidateGetUnsignedBytevEXT(const Context *context,
   1081                                 angle::EntryPoint entryPoint,
   1082                                 GLenum pname,
   1083                                 const GLubyte *data)
   1084 {
   1085    if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT)
   1086    {
   1087        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1088        return false;
   1089    }
   1090 
   1091    UNIMPLEMENTED();
   1092    return false;
   1093 }
   1094 
   1095 bool ValidateGetUnsignedBytei_vEXT(const Context *context,
   1096                                   angle::EntryPoint entryPoint,
   1097                                   GLenum target,
   1098                                   GLuint index,
   1099                                   const GLubyte *data)
   1100 {
   1101    if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT)
   1102    {
   1103        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1104        return false;
   1105    }
   1106 
   1107    UNIMPLEMENTED();
   1108    return false;
   1109 }
   1110 
   1111 bool ValidateIsMemoryObjectEXT(const Context *context,
   1112                               angle::EntryPoint entryPoint,
   1113                               MemoryObjectID memoryObject)
   1114 {
   1115    if (!context->getExtensions().memoryObjectEXT)
   1116    {
   1117        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1118        return false;
   1119    }
   1120 
   1121    return true;
   1122 }
   1123 
   1124 bool ValidateMemoryObjectParameterivEXT(const Context *context,
   1125                                        angle::EntryPoint entryPoint,
   1126                                        MemoryObjectID memoryObject,
   1127                                        GLenum pname,
   1128                                        const GLint *params)
   1129 {
   1130    if (!context->getExtensions().memoryObjectEXT)
   1131    {
   1132        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1133        return false;
   1134    }
   1135 
   1136    const MemoryObject *memory = context->getMemoryObject(memoryObject);
   1137    if (memory == nullptr)
   1138    {
   1139        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryObject);
   1140        return false;
   1141    }
   1142 
   1143    if (memory->isImmutable())
   1144    {
   1145        context->validationError(entryPoint, GL_INVALID_OPERATION, kImmutableMemoryObject);
   1146        return false;
   1147    }
   1148 
   1149    if (!IsValidMemoryObjectParamater(context, entryPoint, pname))
   1150    {
   1151        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
   1152        return false;
   1153    }
   1154 
   1155    return true;
   1156 }
   1157 
   1158 bool ValidateTexStorageMem2DEXT(const Context *context,
   1159                                angle::EntryPoint entryPoint,
   1160                                TextureType target,
   1161                                GLsizei levels,
   1162                                GLenum internalFormat,
   1163                                GLsizei width,
   1164                                GLsizei height,
   1165                                MemoryObjectID memory,
   1166                                GLuint64 offset)
   1167 {
   1168    if (!context->getExtensions().memoryObjectEXT)
   1169    {
   1170        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1171        return false;
   1172    }
   1173 
   1174    if (context->getClientMajorVersion() < 3)
   1175    {
   1176        return ValidateES2TexStorageParametersBase(context, entryPoint, target, levels,
   1177                                                   internalFormat, width, height);
   1178    }
   1179 
   1180    ASSERT(context->getClientMajorVersion() >= 3);
   1181    return ValidateES3TexStorage2DParameters(context, entryPoint, target, levels, internalFormat,
   1182                                             width, height, 1);
   1183 }
   1184 
   1185 bool ValidateTexStorageMem3DEXT(const Context *context,
   1186                                angle::EntryPoint entryPoint,
   1187                                TextureType target,
   1188                                GLsizei levels,
   1189                                GLenum internalFormat,
   1190                                GLsizei width,
   1191                                GLsizei height,
   1192                                GLsizei depth,
   1193                                MemoryObjectID memory,
   1194                                GLuint64 offset)
   1195 {
   1196    if (!context->getExtensions().memoryObjectEXT)
   1197    {
   1198        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1199        return false;
   1200    }
   1201 
   1202    UNIMPLEMENTED();
   1203    return false;
   1204 }
   1205 
   1206 bool ValidateImportMemoryFdEXT(const Context *context,
   1207                               angle::EntryPoint entryPoint,
   1208                               MemoryObjectID memory,
   1209                               GLuint64 size,
   1210                               HandleType handleType,
   1211                               GLint fd)
   1212 {
   1213    if (!context->getExtensions().memoryObjectFdEXT)
   1214    {
   1215        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1216        return false;
   1217    }
   1218 
   1219    switch (handleType)
   1220    {
   1221        case HandleType::OpaqueFd:
   1222            break;
   1223        default:
   1224            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType);
   1225            return false;
   1226    }
   1227 
   1228    return true;
   1229 }
   1230 
   1231 bool ValidateImportMemoryZirconHandleANGLE(const Context *context,
   1232                                           angle::EntryPoint entryPoint,
   1233                                           MemoryObjectID memory,
   1234                                           GLuint64 size,
   1235                                           HandleType handleType,
   1236                                           GLuint handle)
   1237 {
   1238    if (!context->getExtensions().memoryObjectFuchsiaANGLE)
   1239    {
   1240        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1241        return false;
   1242    }
   1243 
   1244    switch (handleType)
   1245    {
   1246        case HandleType::ZirconVmo:
   1247            break;
   1248        default:
   1249            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType);
   1250            return false;
   1251    }
   1252 
   1253    return true;
   1254 }
   1255 
   1256 bool ValidateDeleteSemaphoresEXT(const Context *context,
   1257                                 angle::EntryPoint entryPoint,
   1258                                 GLsizei n,
   1259                                 const SemaphoreID *semaphores)
   1260 {
   1261    if (!context->getExtensions().semaphoreEXT)
   1262    {
   1263        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1264        return false;
   1265    }
   1266 
   1267    return ValidateGenOrDelete(context, entryPoint, n);
   1268 }
   1269 
   1270 bool ValidateGenSemaphoresEXT(const Context *context,
   1271                              angle::EntryPoint entryPoint,
   1272                              GLsizei n,
   1273                              const SemaphoreID *semaphores)
   1274 {
   1275    if (!context->getExtensions().semaphoreEXT)
   1276    {
   1277        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1278        return false;
   1279    }
   1280 
   1281    return ValidateGenOrDelete(context, entryPoint, n);
   1282 }
   1283 
   1284 bool ValidateGetSemaphoreParameterui64vEXT(const Context *context,
   1285                                           angle::EntryPoint entryPoint,
   1286                                           SemaphoreID semaphore,
   1287                                           GLenum pname,
   1288                                           const GLuint64 *params)
   1289 {
   1290    if (!context->getExtensions().semaphoreEXT)
   1291    {
   1292        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1293        return false;
   1294    }
   1295 
   1296    UNIMPLEMENTED();
   1297    return false;
   1298 }
   1299 
   1300 bool ValidateIsSemaphoreEXT(const Context *context,
   1301                            angle::EntryPoint entryPoint,
   1302                            SemaphoreID semaphore)
   1303 {
   1304    if (!context->getExtensions().semaphoreEXT)
   1305    {
   1306        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1307        return false;
   1308    }
   1309 
   1310    return true;
   1311 }
   1312 
   1313 bool ValidateSemaphoreParameterui64vEXT(const Context *context,
   1314                                        angle::EntryPoint entryPoint,
   1315                                        SemaphoreID semaphore,
   1316                                        GLenum pname,
   1317                                        const GLuint64 *params)
   1318 {
   1319    if (!context->getExtensions().semaphoreEXT)
   1320    {
   1321        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1322        return false;
   1323    }
   1324 
   1325    UNIMPLEMENTED();
   1326    return false;
   1327 }
   1328 
   1329 bool ValidateSignalSemaphoreEXT(const Context *context,
   1330                                angle::EntryPoint entryPoint,
   1331                                SemaphoreID semaphore,
   1332                                GLuint numBufferBarriers,
   1333                                const BufferID *buffers,
   1334                                GLuint numTextureBarriers,
   1335                                const TextureID *textures,
   1336                                const GLenum *dstLayouts)
   1337 {
   1338    if (!context->getExtensions().semaphoreEXT)
   1339    {
   1340        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1341        return false;
   1342    }
   1343 
   1344    for (GLuint i = 0; i < numBufferBarriers; ++i)
   1345    {
   1346        if (!context->getBuffer(buffers[i]))
   1347        {
   1348            context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName);
   1349            return false;
   1350        }
   1351    }
   1352 
   1353    for (GLuint i = 0; i < numTextureBarriers; ++i)
   1354    {
   1355        if (!context->getTexture(textures[i]))
   1356        {
   1357            context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
   1358            return false;
   1359        }
   1360        if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
   1361        {
   1362            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout);
   1363            return false;
   1364        }
   1365    }
   1366 
   1367    return true;
   1368 }
   1369 
   1370 bool ValidateWaitSemaphoreEXT(const Context *context,
   1371                              angle::EntryPoint entryPoint,
   1372                              SemaphoreID semaphore,
   1373                              GLuint numBufferBarriers,
   1374                              const BufferID *buffers,
   1375                              GLuint numTextureBarriers,
   1376                              const TextureID *textures,
   1377                              const GLenum *srcLayouts)
   1378 {
   1379    if (!context->getExtensions().semaphoreEXT)
   1380    {
   1381        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1382        return false;
   1383    }
   1384 
   1385    for (GLuint i = 0; i < numBufferBarriers; ++i)
   1386    {
   1387        if (!context->getBuffer(buffers[i]))
   1388        {
   1389            context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName);
   1390            return false;
   1391        }
   1392    }
   1393 
   1394    for (GLuint i = 0; i < numTextureBarriers; ++i)
   1395    {
   1396        if (!context->getTexture(textures[i]))
   1397        {
   1398            context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
   1399            return false;
   1400        }
   1401        if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
   1402        {
   1403            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout);
   1404            return false;
   1405        }
   1406    }
   1407 
   1408    return true;
   1409 }
   1410 
   1411 bool ValidateImportSemaphoreFdEXT(const Context *context,
   1412                                  angle::EntryPoint entryPoint,
   1413                                  SemaphoreID semaphore,
   1414                                  HandleType handleType,
   1415                                  GLint fd)
   1416 {
   1417    if (!context->getExtensions().semaphoreFdEXT)
   1418    {
   1419        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1420        return false;
   1421    }
   1422 
   1423    switch (handleType)
   1424    {
   1425        case HandleType::OpaqueFd:
   1426            break;
   1427        default:
   1428            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType);
   1429            return false;
   1430    }
   1431 
   1432    return true;
   1433 }
   1434 
   1435 bool ValidateGetSamplerParameterIivEXT(const Context *context,
   1436                                       angle::EntryPoint entryPoint,
   1437                                       SamplerID samplerPacked,
   1438                                       GLenum pname,
   1439                                       const GLint *params)
   1440 {
   1441    if (context->getClientMajorVersion() < 3)
   1442    {
   1443        context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
   1444        return false;
   1445    }
   1446    return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr);
   1447 }
   1448 
   1449 bool ValidateGetSamplerParameterIuivEXT(const Context *context,
   1450                                        angle::EntryPoint entryPoint,
   1451                                        SamplerID samplerPacked,
   1452                                        GLenum pname,
   1453                                        const GLuint *params)
   1454 {
   1455    if (context->getClientMajorVersion() < 3)
   1456    {
   1457        context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
   1458        return false;
   1459    }
   1460    return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr);
   1461 }
   1462 
   1463 bool ValidateGetTexParameterIivEXT(const Context *context,
   1464                                   angle::EntryPoint entryPoint,
   1465                                   TextureType targetPacked,
   1466                                   GLenum pname,
   1467                                   const GLint *params)
   1468 {
   1469    if (context->getClientMajorVersion() < 3)
   1470    {
   1471        context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
   1472        return false;
   1473    }
   1474    return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
   1475 }
   1476 
   1477 bool ValidateGetTexParameterIuivEXT(const Context *context,
   1478                                    angle::EntryPoint entryPoint,
   1479                                    TextureType targetPacked,
   1480                                    GLenum pname,
   1481                                    const GLuint *params)
   1482 {
   1483    if (context->getClientMajorVersion() < 3)
   1484    {
   1485        context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
   1486        return false;
   1487    }
   1488    return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
   1489 }
   1490 
   1491 bool ValidateSamplerParameterIivEXT(const Context *context,
   1492                                    angle::EntryPoint entryPoint,
   1493                                    SamplerID samplerPacked,
   1494                                    GLenum pname,
   1495                                    const GLint *param)
   1496 {
   1497    if (context->getClientMajorVersion() < 3)
   1498    {
   1499        context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
   1500        return false;
   1501    }
   1502    return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
   1503 }
   1504 
   1505 bool ValidateSamplerParameterIuivEXT(const Context *context,
   1506                                     angle::EntryPoint entryPoint,
   1507                                     SamplerID samplerPacked,
   1508                                     GLenum pname,
   1509                                     const GLuint *param)
   1510 {
   1511    if (context->getClientMajorVersion() < 3)
   1512    {
   1513        context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
   1514        return false;
   1515    }
   1516    return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
   1517 }
   1518 
   1519 bool ValidateTexParameterIivEXT(const Context *context,
   1520                                angle::EntryPoint entryPoint,
   1521                                TextureType targetPacked,
   1522                                GLenum pname,
   1523                                const GLint *params)
   1524 {
   1525    if (context->getClientMajorVersion() < 3)
   1526    {
   1527        context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
   1528        return false;
   1529    }
   1530    return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
   1531 }
   1532 
   1533 bool ValidateTexParameterIuivEXT(const Context *context,
   1534                                 angle::EntryPoint entryPoint,
   1535                                 TextureType targetPacked,
   1536                                 GLenum pname,
   1537                                 const GLuint *params)
   1538 {
   1539    if (context->getClientMajorVersion() < 3)
   1540    {
   1541        context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
   1542        return false;
   1543    }
   1544    return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
   1545 }
   1546 
   1547 bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
   1548                                              angle::EntryPoint entryPoint,
   1549                                              SemaphoreID semaphore,
   1550                                              HandleType handleType,
   1551                                              GLuint handle)
   1552 {
   1553    if (!context->getExtensions().semaphoreFuchsiaANGLE)
   1554    {
   1555        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   1556        return false;
   1557    }
   1558 
   1559    switch (handleType)
   1560    {
   1561        case HandleType::ZirconEvent:
   1562            break;
   1563        default:
   1564            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType);
   1565            return false;
   1566    }
   1567 
   1568    return true;
   1569 }
   1570 
   1571 namespace
   1572 {
   1573 enum class PLSExpectedStatus : bool
   1574 {
   1575    Inactive,
   1576    Active
   1577 };
   1578 
   1579 bool ValidatePLSCommon(const Context *context,
   1580                       angle::EntryPoint entryPoint,
   1581                       PLSExpectedStatus expectedStatus)
   1582 {
   1583    // Check that the pixel local storage extension is enabled at all.
   1584    if (!context->getExtensions().shaderPixelLocalStorageANGLE)
   1585    {
   1586        context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
   1587        return false;
   1588    }
   1589 
   1590    // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is
   1591    // bound to DRAW_FRAMEBUFFER.
   1592    if (context->getState().getDrawFramebuffer()->id().value == 0)
   1593    {
   1594        context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
   1595                                 kPLSDefaultFramebufferBound);
   1596        return false;
   1597    }
   1598 
   1599    if (expectedStatus == PLSExpectedStatus::Inactive)
   1600    {
   1601        // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE is TRUE.
   1602        if (context->getState().getPixelLocalStorageActive())
   1603        {
   1604            context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSActive);
   1605            return false;
   1606        }
   1607    }
   1608    else
   1609    {
   1610        ASSERT(expectedStatus == PLSExpectedStatus::Active);
   1611 
   1612        // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE is FALSE.
   1613        if (!context->getState().getPixelLocalStorageActive())
   1614        {
   1615            context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSInactive);
   1616            return false;
   1617        }
   1618    }
   1619 
   1620    return true;
   1621 }
   1622 
   1623 bool ValidatePLSCommon(const Context *context, angle::EntryPoint entryPoint, GLint plane)
   1624 {
   1625    if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive))
   1626    {
   1627        return false;
   1628    }
   1629 
   1630    // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
   1631    if (plane < 0)
   1632    {
   1633        context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlaneLessThanZero);
   1634        return false;
   1635    }
   1636    if (plane >= static_cast<GLint>(context->getCaps().maxPixelLocalStoragePlanes))
   1637    {
   1638        context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlaneOutOfRange);
   1639        return false;
   1640    }
   1641 
   1642    return true;
   1643 }
   1644 
   1645 bool ValidatePLSInternalformat(const Context *context,
   1646                               angle::EntryPoint entryPoint,
   1647                               GLenum internalformat)
   1648 {
   1649    // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
   1650    // X.2, or NONE.
   1651    switch (internalformat)
   1652    {
   1653        case GL_RGBA8:
   1654        case GL_RGBA8I:
   1655        case GL_RGBA8UI:
   1656        case GL_R32F:
   1657        case GL_R32UI:
   1658            return true;
   1659        default:
   1660            context->validationError(entryPoint, GL_INVALID_ENUM, kPLSInvalidInternalformat);
   1661            return false;
   1662    }
   1663 }
   1664 
   1665 bool ValidatePLSTextureType(const Context *context,
   1666                            angle::EntryPoint entryPoint,
   1667                            Texture *tex,
   1668                            size_t *textureDepth)
   1669 {
   1670    // INVALID_ENUM is generated if <backingtexture> is nonzero and not of type GL_TEXTURE_2D,
   1671    // GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY, or GL_TEXTURE_3D.
   1672    switch (tex->getType())
   1673    {
   1674        case TextureType::_2D:
   1675            *textureDepth = 1;
   1676            return true;
   1677        case TextureType::CubeMap:
   1678            *textureDepth = 6;
   1679            return true;
   1680        case TextureType::_2DArray:
   1681            *textureDepth = tex->getDepth(TextureTarget::_2DArray, 0);
   1682            return true;
   1683        case TextureType::_3D:
   1684            *textureDepth = tex->getDepth(TextureTarget::_3D, 0);
   1685            return true;
   1686        default:
   1687            context->validationError(entryPoint, GL_INVALID_ENUM, kPLSInvalidTextureType);
   1688            return false;
   1689    }
   1690 }
   1691 
   1692 bool ValidatePLSLoadOperation(const Context *context, angle::EntryPoint entryPoint, GLenum loadop)
   1693 {
   1694    // INVALID_ENUM is generated if <loadops>[0..<planes>-1] is not one of the Load Operations
   1695    // enumerated in Table X.1.
   1696    switch (loadop)
   1697    {
   1698        case GL_ZERO:
   1699        case GL_CLEAR_ANGLE:
   1700        case GL_KEEP:
   1701        case GL_DONT_CARE:
   1702        case GL_DISABLE_ANGLE:
   1703            return true;
   1704        default:
   1705            context->validationError(entryPoint, GL_INVALID_ENUM, kPLSInvalidLoadOperation);
   1706            return false;
   1707    }
   1708 }
   1709 }  // namespace
   1710 
   1711 bool ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context *context,
   1712                                                         angle::EntryPoint entryPoint,
   1713                                                         GLint plane,
   1714                                                         GLenum internalformat)
   1715 {
   1716    if (!ValidatePLSCommon(context, entryPoint, plane))
   1717    {
   1718        return false;
   1719    }
   1720 
   1721    // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
   1722    // X.2, or NONE.
   1723    if (internalformat != GL_NONE)
   1724    {
   1725        if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
   1726        {
   1727            return false;
   1728        }
   1729    }
   1730 
   1731    return true;
   1732 }
   1733 
   1734 bool ValidateFramebufferTexturePixelLocalStorageANGLE(const Context *context,
   1735                                                      angle::EntryPoint entryPoint,
   1736                                                      GLint plane,
   1737                                                      TextureID backingtexture,
   1738                                                      GLint level,
   1739                                                      GLint layer)
   1740 {
   1741    if (!ValidatePLSCommon(context, entryPoint, plane))
   1742    {
   1743        return false;
   1744    }
   1745 
   1746    if (backingtexture.value != 0)
   1747    {
   1748        Texture *tex = context->getTexture(backingtexture);
   1749 
   1750        // INVALID_OPERATION is generated if <backingtexture> is not the name of an existing
   1751        // immutable texture object, or zero.
   1752        if (!tex)
   1753        {
   1754            context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
   1755            return false;
   1756        }
   1757        if (!tex->getImmutableFormat())
   1758        {
   1759            context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsNotImmutable);
   1760            return false;
   1761        }
   1762 
   1763        // INVALID_ENUM is generated if <backingtexture> is nonzero and not of type GL_TEXTURE_2D,
   1764        // GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY, or GL_TEXTURE_3D.
   1765        size_t textureDepth;
   1766        if (!ValidatePLSTextureType(context, entryPoint, tex, &textureDepth))
   1767        {
   1768            return false;
   1769        }
   1770 
   1771        // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> < 0.
   1772        if (level < 0)
   1773        {
   1774            context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel);
   1775            return false;
   1776        }
   1777 
   1778        // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> >= the
   1779        // immutable number of mipmap levels in <backingtexture>.
   1780        if (static_cast<GLuint>(level) >= tex->getImmutableLevels())
   1781        {
   1782            context->validationError(entryPoint, GL_INVALID_VALUE, kTextureLevelOutOfRange);
   1783            return false;
   1784        }
   1785 
   1786        // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> < 0.
   1787        if (layer < 0)
   1788        {
   1789            context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLayer);
   1790            return false;
   1791        }
   1792 
   1793        // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> >= the immutable
   1794        // number of texture layers in <backingtexture>.
   1795        if ((size_t)layer >= textureDepth)
   1796        {
   1797            context->validationError(entryPoint, GL_INVALID_VALUE, kTextureLayerOutOfRange);
   1798            return false;
   1799        }
   1800 
   1801        // INVALID_ENUM is generated if <backingtexture> is nonzero and its internalformat is not
   1802        // one of the acceptable values in Table X.2.
   1803        ASSERT(tex->getImmutableFormat());
   1804        GLenum internalformat = tex->getState().getBaseLevelDesc().format.info->internalFormat;
   1805        if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
   1806        {
   1807            return false;
   1808        }
   1809    }
   1810 
   1811    return true;
   1812 }
   1813 
   1814 bool ValidateBeginPixelLocalStorageANGLE(const Context *context,
   1815                                         angle::EntryPoint entryPoint,
   1816                                         GLsizei planes,
   1817                                         const GLenum loadops[],
   1818                                         const void *cleardata)
   1819 {
   1820    if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive))
   1821    {
   1822        return false;
   1823    }
   1824 
   1825    const State &state             = context->getState();
   1826    const Framebuffer *framebuffer = state.getDrawFramebuffer();
   1827 
   1828    // INVALID_OPERATION is generated if the value of SAMPLE_BUFFERS is 1 (i.e., if rendering to a
   1829    // multisampled framebuffer).
   1830    if (framebuffer->getSamples(context) != 0)
   1831    {
   1832        context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSMultisamplingEnabled);
   1833        return false;
   1834    }
   1835 
   1836    // INVALID_OPERATION is generated if DITHER is enabled.
   1837    if (state.isDitherEnabled())
   1838    {
   1839        context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSDitherEnabled);
   1840        return false;
   1841    }
   1842 
   1843    // INVALID_OPERATION is generated if RASTERIZER_DISCARD is enabled.
   1844    if (state.isRasterizerDiscardEnabled())
   1845    {
   1846        context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSRasterizerDiscardEnabled);
   1847        return false;
   1848    }
   1849 
   1850    // INVALID_OPERATION is generated if SAMPLE_ALPHA_TO_COVERAGE is enabled.
   1851    if (state.isSampleAlphaToCoverageEnabled())
   1852    {
   1853        context->validationError(entryPoint, GL_INVALID_OPERATION,
   1854                                 kPLSSampleAlphaToCoverageEnabled);
   1855        return false;
   1856    }
   1857 
   1858    // INVALID_OPERATION is generated if SAMPLE_COVERAGE is enabled.
   1859    if (state.isSampleCoverageEnabled())
   1860    {
   1861        context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSSampleCoverageEnabled);
   1862        return false;
   1863    }
   1864 
   1865    // INVALID_VALUE is generated if <planes> < 1 or <planes> >
   1866    // MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
   1867    if (planes < 1)
   1868    {
   1869        context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlanesLessThanOne);
   1870        return false;
   1871    }
   1872    if (planes > static_cast<GLsizei>(context->getCaps().maxPixelLocalStoragePlanes))
   1873    {
   1874        context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlanesOutOfRange);
   1875        return false;
   1876    }
   1877 
   1878    // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
   1879    // any color attachment point on or after:
   1880    //
   1881    //   COLOR_ATTACHMENT0 +
   1882    //   MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE
   1883    //
   1884    const Caps &caps = context->getCaps();
   1885    for (int i = caps.maxColorAttachmentsWithActivePixelLocalStorage; i < caps.maxColorAttachments;
   1886         ++i)
   1887    {
   1888        if (framebuffer->getColorAttachment(i))
   1889        {
   1890            context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
   1891                                     kPLSMaxColorAttachmentsExceded);
   1892            return false;
   1893        }
   1894    }
   1895 
   1896    // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
   1897    // any color attachment point on or after:
   1898    //
   1899    //   COLOR_ATTACHMENT0 +
   1900    //   MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE -
   1901    //   <planes>
   1902    //
   1903    for (GLuint i = caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - planes;
   1904         i < caps.maxColorAttachmentsWithActivePixelLocalStorage; ++i)
   1905    {
   1906        if (framebuffer->getColorAttachment(i))
   1907        {
   1908            context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
   1909                                     kPLSMaxCombinedDrawBuffersAndPlanesExceded);
   1910            return false;
   1911        }
   1912    }
   1913 
   1914    // INVALID_VALUE is generated if <loadops> is NULL.
   1915    if (!loadops)
   1916    {
   1917        context->validationError(entryPoint, GL_INVALID_VALUE, kPLSNullLoadOps);
   1918        return false;
   1919    }
   1920 
   1921    const PixelLocalStorage *pls   = framebuffer->peekPixelLocalStorage();
   1922    bool hasTextureBackedPLSPlanes = false;
   1923    Extents textureBackedPLSExtents{};
   1924 
   1925    for (int i = 0; i < planes; ++i)
   1926    {
   1927        // INVALID_ENUM is generated if <loadops>[0..<planes>-1] is not one of the Load
   1928        // Operations enumerated in Table X.1.
   1929        if (!ValidatePLSLoadOperation(context, entryPoint, loadops[i]))
   1930        {
   1931            return false;
   1932        }
   1933 
   1934        if (loadops[i] == GL_DISABLE_ANGLE)
   1935        {
   1936            continue;
   1937        }
   1938 
   1939        // INVALID_VALUE is generated if <loadops>[0..<planes>-1] is CLEAR_ANGLE and <cleardata> is
   1940        // NULL.
   1941        if (loadops[i] == GL_CLEAR_ANGLE && !cleardata)
   1942        {
   1943            context->validationError(entryPoint, GL_INVALID_VALUE, kPLSNullClearData);
   1944            return false;
   1945        }
   1946 
   1947        // INVALID_OPERATION is generated if <loadops>[0..<planes>-1] is not DISABLE_ANGLE, and
   1948        // the pixel local storage plane at that same index is is in a deinitialized state.
   1949        if (pls == nullptr || pls->getPlane(i).isDeinitialized())
   1950        {
   1951            context->validationError(entryPoint, GL_INVALID_OPERATION,
   1952                                     kPLSEnablingDeinitializedPlane);
   1953            return false;
   1954        }
   1955 
   1956        // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage
   1957        // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to
   1958        // which it was bound is automatically converted to a memoryless plane of matching
   1959        // internalformat.
   1960        const PixelLocalStoragePlane &plane = pls->getPlane(i);
   1961 
   1962        Extents textureExtents;
   1963        if (plane.getTextureImageExtents(context, &textureExtents))
   1964        {
   1965            // INVALID_OPERATION is generated if all enabled, texture-backed pixel local storage
   1966            // planes do not have the same width and height.
   1967            if (!hasTextureBackedPLSPlanes)
   1968            {
   1969                textureBackedPLSExtents   = textureExtents;
   1970                hasTextureBackedPLSPlanes = true;
   1971            }
   1972            else if (textureExtents != textureBackedPLSExtents)
   1973            {
   1974                context->validationError(entryPoint, GL_INVALID_OPERATION,
   1975                                         kPLSMismatchedBackingTextureSizes);
   1976                return false;
   1977            }
   1978        }
   1979        else
   1980        {
   1981            // INVALID_OPERATION is generated if <loadops>[0..<planes>-1] is KEEP and the pixel
   1982            // local storage plane at that same index is memoryless.
   1983            if (loadops[i] == GL_KEEP)
   1984            {
   1985                context->validationError(entryPoint, GL_INVALID_OPERATION,
   1986                                         kPLSKeepingMemorylessPlane);
   1987                return false;
   1988            }
   1989        }
   1990    }
   1991 
   1992    const FramebufferAttachment *firstAttachment =
   1993        framebuffer->getState().getFirstNonNullAttachment();
   1994    if (firstAttachment)
   1995    {
   1996        // INVALID_OPERATION is generated if the draw framebuffer has other attachments, and its
   1997        // enabled, texture-backed pixel local storage planes do not have identical dimensions
   1998        // with the rendering area.
   1999        if (hasTextureBackedPLSPlanes &&
   2000            textureBackedPLSExtents != framebuffer->getState().getAttachmentExtentsIntersection())
   2001        {
   2002            context->validationError(entryPoint, GL_INVALID_OPERATION,
   2003                                     kPLSDimensionsDontMatchRenderingArea);
   2004            return false;
   2005        }
   2006    }
   2007    else
   2008    {
   2009        // INVALID_OPERATION is generated if the draw framebuffer has no attachments and no
   2010        // enabled, texture-backed pixel local storage planes.
   2011        if (!hasTextureBackedPLSPlanes)
   2012        {
   2013            context->validationError(entryPoint, GL_INVALID_OPERATION,
   2014                                     kPLSNoAttachmentsNoTextureBacked);
   2015            return false;
   2016        }
   2017    }
   2018 
   2019    // INVALID_OPERATION is generated if a single texture image is bound to more than one pixel
   2020    // local storage plane.
   2021    //
   2022    //   TODO(anglebug.com/7279): Block feedback loops
   2023    //
   2024 
   2025    // INVALID_OPERATION is generated if a single texture image is simultaneously bound to a pixel
   2026    // local storage plane and attached to the draw framebuffer.
   2027    //
   2028    //   TODO(anglebug.com/7279): Block feedback loops
   2029    //
   2030 
   2031    return true;
   2032 }
   2033 
   2034 bool ValidateEndPixelLocalStorageANGLE(const Context *context, angle::EntryPoint entryPoint)
   2035 {
   2036    return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active);
   2037 }
   2038 
   2039 bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint)
   2040 {
   2041    return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active);
   2042 }
   2043 
   2044 bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint)
   2045 {
   2046    if (!context->getExtensions().shaderFramebufferFetchNonCoherentEXT)
   2047    {
   2048        context->validationError(entryPoint, GL_INVALID_OPERATION,
   2049                                 kFramebufferFetchNonCoherentExtensionNotEnabled);
   2050        return false;
   2051    }
   2052    return true;
   2053 }
   2054 
   2055 bool ValidatePatchParameteriEXT(const Context *context,
   2056                                angle::EntryPoint entryPoint,
   2057                                GLenum pname,
   2058                                GLint value)
   2059 {
   2060    if (!context->getExtensions().tessellationShaderEXT)
   2061    {
   2062        context->validationError(entryPoint, GL_INVALID_OPERATION,
   2063                                 kTessellationShaderExtensionNotEnabled);
   2064        return false;
   2065    }
   2066 
   2067    if (pname != GL_PATCH_VERTICES)
   2068    {
   2069        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
   2070        return false;
   2071    }
   2072 
   2073    if (value <= 0)
   2074    {
   2075        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueNonPositive);
   2076        return false;
   2077    }
   2078 
   2079    if (value > context->getCaps().maxPatchVertices)
   2080    {
   2081        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueExceedsMaxPatchSize);
   2082        return false;
   2083    }
   2084 
   2085    return true;
   2086 }
   2087 
   2088 bool ValidateTexStorageMemFlags2DANGLE(const Context *context,
   2089                                       angle::EntryPoint entryPoint,
   2090                                       TextureType targetPacked,
   2091                                       GLsizei levels,
   2092                                       GLenum internalFormat,
   2093                                       GLsizei width,
   2094                                       GLsizei height,
   2095                                       MemoryObjectID memoryPacked,
   2096                                       GLuint64 offset,
   2097                                       GLbitfield createFlags,
   2098                                       GLbitfield usageFlags,
   2099                                       const void *imageCreateInfoPNext)
   2100 {
   2101    if (!context->getExtensions().memoryObjectFlagsANGLE)
   2102    {
   2103        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2104        return false;
   2105    }
   2106 
   2107    if (!ValidateTexStorageMem2DEXT(context, entryPoint, targetPacked, levels, internalFormat,
   2108                                    width, height, memoryPacked, offset))
   2109    {
   2110        return false;
   2111    }
   2112 
   2113    // |createFlags| and |usageFlags| must only have bits specified by the extension.
   2114    constexpr GLbitfield kAllCreateFlags =
   2115        GL_CREATE_SPARSE_BINDING_BIT_ANGLE | GL_CREATE_SPARSE_RESIDENCY_BIT_ANGLE |
   2116        GL_CREATE_SPARSE_ALIASED_BIT_ANGLE | GL_CREATE_MUTABLE_FORMAT_BIT_ANGLE |
   2117        GL_CREATE_CUBE_COMPATIBLE_BIT_ANGLE | GL_CREATE_ALIAS_BIT_ANGLE |
   2118        GL_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_ANGLE | GL_CREATE_2D_ARRAY_COMPATIBLE_BIT_ANGLE |
   2119        GL_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_ANGLE | GL_CREATE_EXTENDED_USAGE_BIT_ANGLE |
   2120        GL_CREATE_PROTECTED_BIT_ANGLE | GL_CREATE_DISJOINT_BIT_ANGLE |
   2121        GL_CREATE_CORNER_SAMPLED_BIT_ANGLE | GL_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_ANGLE |
   2122        GL_CREATE_SUBSAMPLED_BIT_ANGLE;
   2123 
   2124    if ((createFlags & ~kAllCreateFlags) != 0)
   2125    {
   2126        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidExternalCreateFlags);
   2127        return false;
   2128    }
   2129 
   2130    constexpr GLbitfield kAllUsageFlags =
   2131        GL_USAGE_TRANSFER_SRC_BIT_ANGLE | GL_USAGE_TRANSFER_DST_BIT_ANGLE |
   2132        GL_USAGE_SAMPLED_BIT_ANGLE | GL_USAGE_STORAGE_BIT_ANGLE |
   2133        GL_USAGE_COLOR_ATTACHMENT_BIT_ANGLE | GL_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT_ANGLE |
   2134        GL_USAGE_TRANSIENT_ATTACHMENT_BIT_ANGLE | GL_USAGE_INPUT_ATTACHMENT_BIT_ANGLE |
   2135        GL_USAGE_SHADING_RATE_IMAGE_BIT_ANGLE | GL_USAGE_FRAGMENT_DENSITY_MAP_BIT_ANGLE;
   2136 
   2137    if ((usageFlags & ~kAllUsageFlags) != 0)
   2138    {
   2139        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidExternalUsageFlags);
   2140        return false;
   2141    }
   2142 
   2143    return true;
   2144 }
   2145 
   2146 bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context,
   2147                                                  angle::EntryPoint entryPoint,
   2148                                                  TextureType targetPacked,
   2149                                                  GLsizei samples,
   2150                                                  GLenum internalFormat,
   2151                                                  GLsizei width,
   2152                                                  GLsizei height,
   2153                                                  GLboolean fixedSampleLocations,
   2154                                                  MemoryObjectID memoryPacked,
   2155                                                  GLuint64 offset,
   2156                                                  GLbitfield createFlags,
   2157                                                  GLbitfield usageFlags,
   2158                                                  const void *imageCreateInfoPNext)
   2159 {
   2160    UNIMPLEMENTED();
   2161    return false;
   2162 }
   2163 
   2164 bool ValidateTexStorageMemFlags3DANGLE(const Context *context,
   2165                                       angle::EntryPoint entryPoint,
   2166                                       TextureType targetPacked,
   2167                                       GLsizei levels,
   2168                                       GLenum internalFormat,
   2169                                       GLsizei width,
   2170                                       GLsizei height,
   2171                                       GLsizei depth,
   2172                                       MemoryObjectID memoryPacked,
   2173                                       GLuint64 offset,
   2174                                       GLbitfield createFlags,
   2175                                       GLbitfield usageFlags,
   2176                                       const void *imageCreateInfoPNext)
   2177 {
   2178    UNIMPLEMENTED();
   2179    return false;
   2180 }
   2181 
   2182 bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context,
   2183                                                  angle::EntryPoint entryPoint,
   2184                                                  TextureType targetPacked,
   2185                                                  GLsizei samples,
   2186                                                  GLenum internalFormat,
   2187                                                  GLsizei width,
   2188                                                  GLsizei height,
   2189                                                  GLsizei depth,
   2190                                                  GLboolean fixedSampleLocations,
   2191                                                  MemoryObjectID memoryPacked,
   2192                                                  GLuint64 offset,
   2193                                                  GLbitfield createFlags,
   2194                                                  GLbitfield usageFlags,
   2195                                                  const void *imageCreateInfoPNext)
   2196 {
   2197    UNIMPLEMENTED();
   2198    return false;
   2199 }
   2200 
   2201 // GL_EXT_buffer_storage
   2202 bool ValidateBufferStorageEXT(const Context *context,
   2203                              angle::EntryPoint entryPoint,
   2204                              BufferBinding targetPacked,
   2205                              GLsizeiptr size,
   2206                              const void *data,
   2207                              GLbitfield flags)
   2208 {
   2209    if (!context->isValidBufferBinding(targetPacked))
   2210    {
   2211        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
   2212        return false;
   2213    }
   2214 
   2215    if (size <= 0)
   2216    {
   2217        context->validationError(entryPoint, GL_INVALID_VALUE, kNonPositiveSize);
   2218        return false;
   2219    }
   2220 
   2221    constexpr GLbitfield kAllUsageFlags =
   2222        (GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
   2223         GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT | GL_CLIENT_STORAGE_BIT_EXT);
   2224    if ((flags & ~kAllUsageFlags) != 0)
   2225    {
   2226        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags);
   2227        return false;
   2228    }
   2229 
   2230    if (((flags & GL_MAP_PERSISTENT_BIT_EXT) != 0) &&
   2231        ((flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0))
   2232    {
   2233        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags);
   2234        return false;
   2235    }
   2236 
   2237    if (((flags & GL_MAP_COHERENT_BIT_EXT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT_EXT) == 0))
   2238    {
   2239        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags);
   2240        return false;
   2241    }
   2242 
   2243    Buffer *buffer = context->getState().getTargetBuffer(targetPacked);
   2244 
   2245    if (buffer == nullptr)
   2246    {
   2247        context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound);
   2248        return false;
   2249    }
   2250 
   2251    if (buffer->isImmutable())
   2252    {
   2253        context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferImmutable);
   2254        return false;
   2255    }
   2256 
   2257    return true;
   2258 }
   2259 
   2260 // GL_EXT_clip_control
   2261 bool ValidateClipControlEXT(const Context *context,
   2262                            angle::EntryPoint entryPoint,
   2263                            GLenum origin,
   2264                            GLenum depth)
   2265 {
   2266    if ((origin != GL_LOWER_LEFT_EXT) && (origin != GL_UPPER_LEFT_EXT))
   2267    {
   2268        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidOriginEnum);
   2269        return false;
   2270    }
   2271 
   2272    if ((depth != GL_NEGATIVE_ONE_TO_ONE_EXT) && (depth != GL_ZERO_TO_ONE_EXT))
   2273    {
   2274        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDepthEnum);
   2275        return false;
   2276    }
   2277 
   2278    return true;
   2279 }
   2280 
   2281 // GL_EXT_external_buffer
   2282 bool ValidateBufferStorageExternalEXT(const Context *context,
   2283                                      angle::EntryPoint entryPoint,
   2284                                      BufferBinding targetPacked,
   2285                                      GLintptr offset,
   2286                                      GLsizeiptr size,
   2287                                      GLeglClientBufferEXT clientBuffer,
   2288                                      GLbitfield flags)
   2289 {
   2290    if (!ValidateBufferStorageEXT(context, entryPoint, targetPacked, size, nullptr, flags))
   2291    {
   2292        return false;
   2293    }
   2294 
   2295    if (offset != 0)
   2296    {
   2297        context->validationError(entryPoint, GL_INVALID_VALUE, kExternalBufferInvalidOffset);
   2298        return false;
   2299    }
   2300 
   2301    if (clientBuffer == nullptr && size > 0)
   2302    {
   2303        context->validationError(entryPoint, GL_INVALID_VALUE, kClientBufferInvalid);
   2304        return false;
   2305    }
   2306 
   2307    return true;
   2308 }
   2309 
   2310 bool ValidateNamedBufferStorageExternalEXT(const Context *context,
   2311                                           angle::EntryPoint entryPoint,
   2312                                           GLuint buffer,
   2313                                           GLintptr offset,
   2314                                           GLsizeiptr size,
   2315                                           GLeglClientBufferEXT clientBuffer,
   2316                                           GLbitfield flags)
   2317 {
   2318    UNIMPLEMENTED();
   2319    return false;
   2320 }
   2321 
   2322 // GL_EXT_primitive_bounding_box
   2323 bool ValidatePrimitiveBoundingBoxEXT(const Context *context,
   2324                                     angle::EntryPoint entryPoint,
   2325                                     GLfloat minX,
   2326                                     GLfloat minY,
   2327                                     GLfloat minZ,
   2328                                     GLfloat minW,
   2329                                     GLfloat maxX,
   2330                                     GLfloat maxY,
   2331                                     GLfloat maxZ,
   2332                                     GLfloat maxW)
   2333 {
   2334    if (!context->getExtensions().primitiveBoundingBoxEXT)
   2335    {
   2336        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2337        return false;
   2338    }
   2339 
   2340    return true;
   2341 }
   2342 
   2343 // GL_OES_primitive_bounding_box
   2344 bool ValidatePrimitiveBoundingBoxOES(const Context *context,
   2345                                     angle::EntryPoint entryPoint,
   2346                                     GLfloat minX,
   2347                                     GLfloat minY,
   2348                                     GLfloat minZ,
   2349                                     GLfloat minW,
   2350                                     GLfloat maxX,
   2351                                     GLfloat maxY,
   2352                                     GLfloat maxZ,
   2353                                     GLfloat maxW)
   2354 {
   2355    if (!context->getExtensions().primitiveBoundingBoxOES)
   2356    {
   2357        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2358        return false;
   2359    }
   2360 
   2361    return true;
   2362 }
   2363 
   2364 // GL_EXT_separate_shader_objects
   2365 bool ValidateActiveShaderProgramEXT(const Context *context,
   2366                                    angle::EntryPoint entryPoint,
   2367                                    ProgramPipelineID pipelinePacked,
   2368                                    ShaderProgramID programPacked)
   2369 {
   2370    if (!context->getExtensions().separateShaderObjectsEXT)
   2371    {
   2372        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2373        return false;
   2374    }
   2375 
   2376    return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
   2377 }
   2378 
   2379 bool ValidateBindProgramPipelineEXT(const Context *context,
   2380                                    angle::EntryPoint entryPoint,
   2381                                    ProgramPipelineID pipelinePacked)
   2382 {
   2383    if (!context->getExtensions().separateShaderObjectsEXT)
   2384    {
   2385        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2386        return false;
   2387    }
   2388 
   2389    return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
   2390 }
   2391 
   2392 bool ValidateCreateShaderProgramvEXT(const Context *context,
   2393                                     angle::EntryPoint entryPoint,
   2394                                     ShaderType typePacked,
   2395                                     GLsizei count,
   2396                                     const GLchar **strings)
   2397 {
   2398    if (!context->getExtensions().separateShaderObjectsEXT)
   2399    {
   2400        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2401        return false;
   2402    }
   2403 
   2404    return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
   2405 }
   2406 
   2407 bool ValidateDeleteProgramPipelinesEXT(const Context *context,
   2408                                       angle::EntryPoint entryPoint,
   2409                                       GLsizei n,
   2410                                       const ProgramPipelineID *pipelinesPacked)
   2411 {
   2412    if (!context->getExtensions().separateShaderObjectsEXT)
   2413    {
   2414        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2415        return false;
   2416    }
   2417 
   2418    return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
   2419 }
   2420 
   2421 bool ValidateGenProgramPipelinesEXT(const Context *context,
   2422                                    angle::EntryPoint entryPoint,
   2423                                    GLsizei n,
   2424                                    const ProgramPipelineID *pipelinesPacked)
   2425 {
   2426    if (!context->getExtensions().separateShaderObjectsEXT)
   2427    {
   2428        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2429        return false;
   2430    }
   2431 
   2432    return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
   2433 }
   2434 
   2435 bool ValidateGetProgramPipelineInfoLogEXT(const Context *context,
   2436                                          angle::EntryPoint entryPoint,
   2437                                          ProgramPipelineID pipelinePacked,
   2438                                          GLsizei bufSize,
   2439                                          const GLsizei *length,
   2440                                          const GLchar *infoLog)
   2441 {
   2442    if (!context->getExtensions().separateShaderObjectsEXT)
   2443    {
   2444        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2445        return false;
   2446    }
   2447 
   2448    return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
   2449                                                 length, infoLog);
   2450 }
   2451 
   2452 bool ValidateGetProgramPipelineivEXT(const Context *context,
   2453                                     angle::EntryPoint entryPoint,
   2454                                     ProgramPipelineID pipelinePacked,
   2455                                     GLenum pname,
   2456                                     const GLint *params)
   2457 {
   2458    if (!context->getExtensions().separateShaderObjectsEXT)
   2459    {
   2460        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2461        return false;
   2462    }
   2463 
   2464    return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
   2465 }
   2466 
   2467 bool ValidateIsProgramPipelineEXT(const Context *context,
   2468                                  angle::EntryPoint entryPoint,
   2469                                  ProgramPipelineID pipelinePacked)
   2470 {
   2471    if (!context->getExtensions().separateShaderObjectsEXT)
   2472    {
   2473        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2474        return false;
   2475    }
   2476 
   2477    return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
   2478 }
   2479 
   2480 bool ValidateProgramParameteriEXT(const Context *context,
   2481                                  angle::EntryPoint entryPoint,
   2482                                  ShaderProgramID programPacked,
   2483                                  GLenum pname,
   2484                                  GLint value)
   2485 {
   2486    if (!context->getExtensions().separateShaderObjectsEXT)
   2487    {
   2488        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2489        return false;
   2490    }
   2491 
   2492    return ValidateProgramParameteriBase(context, entryPoint, programPacked, pname, value);
   2493 }
   2494 
   2495 bool ValidateProgramUniform1fEXT(const Context *context,
   2496                                 angle::EntryPoint entryPoint,
   2497                                 ShaderProgramID programPacked,
   2498                                 UniformLocation locationPacked,
   2499                                 GLfloat v0)
   2500 {
   2501    if (!context->getExtensions().separateShaderObjectsEXT)
   2502    {
   2503        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2504        return false;
   2505    }
   2506 
   2507    return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
   2508 }
   2509 
   2510 bool ValidateProgramUniform1fvEXT(const Context *context,
   2511                                  angle::EntryPoint entryPoint,
   2512                                  ShaderProgramID programPacked,
   2513                                  UniformLocation locationPacked,
   2514                                  GLsizei count,
   2515                                  const GLfloat *value)
   2516 {
   2517    if (!context->getExtensions().separateShaderObjectsEXT)
   2518    {
   2519        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2520        return false;
   2521    }
   2522 
   2523    return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
   2524                                         value);
   2525 }
   2526 
   2527 bool ValidateProgramUniform1iEXT(const Context *context,
   2528                                 angle::EntryPoint entryPoint,
   2529                                 ShaderProgramID programPacked,
   2530                                 UniformLocation locationPacked,
   2531                                 GLint v0)
   2532 {
   2533    if (!context->getExtensions().separateShaderObjectsEXT)
   2534    {
   2535        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2536        return false;
   2537    }
   2538 
   2539    return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
   2540 }
   2541 
   2542 bool ValidateProgramUniform1ivEXT(const Context *context,
   2543                                  angle::EntryPoint entryPoint,
   2544                                  ShaderProgramID programPacked,
   2545                                  UniformLocation locationPacked,
   2546                                  GLsizei count,
   2547                                  const GLint *value)
   2548 {
   2549    if (!context->getExtensions().separateShaderObjectsEXT)
   2550    {
   2551        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2552        return false;
   2553    }
   2554 
   2555    return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
   2556                                         value);
   2557 }
   2558 
   2559 bool ValidateProgramUniform1uiEXT(const Context *context,
   2560                                  angle::EntryPoint entryPoint,
   2561                                  ShaderProgramID programPacked,
   2562                                  UniformLocation locationPacked,
   2563                                  GLuint v0)
   2564 {
   2565    if (!context->getExtensions().separateShaderObjectsEXT)
   2566    {
   2567        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2568        return false;
   2569    }
   2570 
   2571    return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
   2572 }
   2573 
   2574 bool ValidateProgramUniform1uivEXT(const Context *context,
   2575                                   angle::EntryPoint entryPoint,
   2576                                   ShaderProgramID programPacked,
   2577                                   UniformLocation locationPacked,
   2578                                   GLsizei count,
   2579                                   const GLuint *value)
   2580 {
   2581    if (!context->getExtensions().separateShaderObjectsEXT)
   2582    {
   2583        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2584        return false;
   2585    }
   2586 
   2587    return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
   2588                                          value);
   2589 }
   2590 
   2591 bool ValidateProgramUniform2fEXT(const Context *context,
   2592                                 angle::EntryPoint entryPoint,
   2593                                 ShaderProgramID programPacked,
   2594                                 UniformLocation locationPacked,
   2595                                 GLfloat v0,
   2596                                 GLfloat v1)
   2597 {
   2598    if (!context->getExtensions().separateShaderObjectsEXT)
   2599    {
   2600        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2601        return false;
   2602    }
   2603 
   2604    return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1);
   2605 }
   2606 
   2607 bool ValidateProgramUniform2fvEXT(const Context *context,
   2608                                  angle::EntryPoint entryPoint,
   2609                                  ShaderProgramID programPacked,
   2610                                  UniformLocation locationPacked,
   2611                                  GLsizei count,
   2612                                  const GLfloat *value)
   2613 {
   2614    if (!context->getExtensions().separateShaderObjectsEXT)
   2615    {
   2616        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2617        return false;
   2618    }
   2619 
   2620    return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
   2621                                         value);
   2622 }
   2623 
   2624 bool ValidateProgramUniform2iEXT(const Context *context,
   2625                                 angle::EntryPoint entryPoint,
   2626                                 ShaderProgramID programPacked,
   2627                                 UniformLocation locationPacked,
   2628                                 GLint v0,
   2629                                 GLint v1)
   2630 {
   2631    if (!context->getExtensions().separateShaderObjectsEXT)
   2632    {
   2633        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2634        return false;
   2635    }
   2636 
   2637    return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1);
   2638 }
   2639 
   2640 bool ValidateProgramUniform2ivEXT(const Context *context,
   2641                                  angle::EntryPoint entryPoint,
   2642                                  ShaderProgramID programPacked,
   2643                                  UniformLocation locationPacked,
   2644                                  GLsizei count,
   2645                                  const GLint *value)
   2646 {
   2647    if (!context->getExtensions().separateShaderObjectsEXT)
   2648    {
   2649        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2650        return false;
   2651    }
   2652 
   2653    return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
   2654                                         value);
   2655 }
   2656 
   2657 bool ValidateProgramUniform2uiEXT(const Context *context,
   2658                                  angle::EntryPoint entryPoint,
   2659                                  ShaderProgramID programPacked,
   2660                                  UniformLocation locationPacked,
   2661                                  GLuint v0,
   2662                                  GLuint v1)
   2663 {
   2664    if (!context->getExtensions().separateShaderObjectsEXT)
   2665    {
   2666        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2667        return false;
   2668    }
   2669 
   2670    return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0,
   2671                                         v1);
   2672 }
   2673 
   2674 bool ValidateProgramUniform2uivEXT(const Context *context,
   2675                                   angle::EntryPoint entryPoint,
   2676                                   ShaderProgramID programPacked,
   2677                                   UniformLocation locationPacked,
   2678                                   GLsizei count,
   2679                                   const GLuint *value)
   2680 {
   2681    if (!context->getExtensions().separateShaderObjectsEXT)
   2682    {
   2683        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2684        return false;
   2685    }
   2686 
   2687    return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count,
   2688                                          value);
   2689 }
   2690 
   2691 bool ValidateProgramUniform3fEXT(const Context *context,
   2692                                 angle::EntryPoint entryPoint,
   2693                                 ShaderProgramID programPacked,
   2694                                 UniformLocation locationPacked,
   2695                                 GLfloat v0,
   2696                                 GLfloat v1,
   2697                                 GLfloat v2)
   2698 {
   2699    if (!context->getExtensions().separateShaderObjectsEXT)
   2700    {
   2701        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2702        return false;
   2703    }
   2704 
   2705    return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
   2706                                        v2);
   2707 }
   2708 
   2709 bool ValidateProgramUniform3fvEXT(const Context *context,
   2710                                  angle::EntryPoint entryPoint,
   2711                                  ShaderProgramID programPacked,
   2712                                  UniformLocation locationPacked,
   2713                                  GLsizei count,
   2714                                  const GLfloat *value)
   2715 {
   2716    if (!context->getExtensions().separateShaderObjectsEXT)
   2717    {
   2718        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2719        return false;
   2720    }
   2721 
   2722    return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
   2723                                         value);
   2724 }
   2725 
   2726 bool ValidateProgramUniform3iEXT(const Context *context,
   2727                                 angle::EntryPoint entryPoint,
   2728                                 ShaderProgramID programPacked,
   2729                                 UniformLocation locationPacked,
   2730                                 GLint v0,
   2731                                 GLint v1,
   2732                                 GLint v2)
   2733 {
   2734    if (!context->getExtensions().separateShaderObjectsEXT)
   2735    {
   2736        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2737        return false;
   2738    }
   2739 
   2740    return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
   2741                                        v2);
   2742 }
   2743 
   2744 bool ValidateProgramUniform3ivEXT(const Context *context,
   2745                                  angle::EntryPoint entryPoint,
   2746                                  ShaderProgramID programPacked,
   2747                                  UniformLocation locationPacked,
   2748                                  GLsizei count,
   2749                                  const GLint *value)
   2750 {
   2751    if (!context->getExtensions().separateShaderObjectsEXT)
   2752    {
   2753        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2754        return false;
   2755    }
   2756 
   2757    return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
   2758                                         value);
   2759 }
   2760 
   2761 bool ValidateProgramUniform3uiEXT(const Context *context,
   2762                                  angle::EntryPoint entryPoint,
   2763                                  ShaderProgramID programPacked,
   2764                                  UniformLocation locationPacked,
   2765                                  GLuint v0,
   2766                                  GLuint v1,
   2767                                  GLuint v2)
   2768 {
   2769    if (!context->getExtensions().separateShaderObjectsEXT)
   2770    {
   2771        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2772        return false;
   2773    }
   2774 
   2775    return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
   2776                                         v2);
   2777 }
   2778 
   2779 bool ValidateProgramUniform3uivEXT(const Context *context,
   2780                                   angle::EntryPoint entryPoint,
   2781                                   ShaderProgramID programPacked,
   2782                                   UniformLocation locationPacked,
   2783                                   GLsizei count,
   2784                                   const GLuint *value)
   2785 {
   2786    if (!context->getExtensions().separateShaderObjectsEXT)
   2787    {
   2788        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2789        return false;
   2790    }
   2791 
   2792    return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
   2793                                          value);
   2794 }
   2795 
   2796 bool ValidateProgramUniform4fEXT(const Context *context,
   2797                                 angle::EntryPoint entryPoint,
   2798                                 ShaderProgramID programPacked,
   2799                                 UniformLocation locationPacked,
   2800                                 GLfloat v0,
   2801                                 GLfloat v1,
   2802                                 GLfloat v2,
   2803                                 GLfloat v3)
   2804 {
   2805    if (!context->getExtensions().separateShaderObjectsEXT)
   2806    {
   2807        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2808        return false;
   2809    }
   2810 
   2811    return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
   2812                                        v2, v3);
   2813 }
   2814 
   2815 bool ValidateProgramUniform4fvEXT(const Context *context,
   2816                                  angle::EntryPoint entryPoint,
   2817                                  ShaderProgramID programPacked,
   2818                                  UniformLocation locationPacked,
   2819                                  GLsizei count,
   2820                                  const GLfloat *value)
   2821 {
   2822    if (!context->getExtensions().separateShaderObjectsEXT)
   2823    {
   2824        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2825        return false;
   2826    }
   2827 
   2828    return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
   2829                                         value);
   2830 }
   2831 
   2832 bool ValidateProgramUniform4iEXT(const Context *context,
   2833                                 angle::EntryPoint entryPoint,
   2834                                 ShaderProgramID programPacked,
   2835                                 UniformLocation locationPacked,
   2836                                 GLint v0,
   2837                                 GLint v1,
   2838                                 GLint v2,
   2839                                 GLint v3)
   2840 {
   2841    if (!context->getExtensions().separateShaderObjectsEXT)
   2842    {
   2843        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2844        return false;
   2845    }
   2846 
   2847    return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
   2848                                        v2, v3);
   2849 }
   2850 
   2851 bool ValidateProgramUniform4ivEXT(const Context *context,
   2852                                  angle::EntryPoint entryPoint,
   2853                                  ShaderProgramID programPacked,
   2854                                  UniformLocation locationPacked,
   2855                                  GLsizei count,
   2856                                  const GLint *value)
   2857 {
   2858    return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
   2859                                         value);
   2860 }
   2861 
   2862 bool ValidateProgramUniform4uiEXT(const Context *context,
   2863                                  angle::EntryPoint entryPoint,
   2864                                  ShaderProgramID programPacked,
   2865                                  UniformLocation locationPacked,
   2866                                  GLuint v0,
   2867                                  GLuint v1,
   2868                                  GLuint v2,
   2869                                  GLuint v3)
   2870 {
   2871    if (!context->getExtensions().separateShaderObjectsEXT)
   2872    {
   2873        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2874        return false;
   2875    }
   2876 
   2877    return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
   2878                                         v2, v3);
   2879 }
   2880 
   2881 bool ValidateProgramUniform4uivEXT(const Context *context,
   2882                                   angle::EntryPoint entryPoint,
   2883                                   ShaderProgramID programPacked,
   2884                                   UniformLocation locationPacked,
   2885                                   GLsizei count,
   2886                                   const GLuint *value)
   2887 {
   2888    return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
   2889                                          value);
   2890 }
   2891 
   2892 bool ValidateProgramUniformMatrix2fvEXT(const Context *context,
   2893                                        angle::EntryPoint entryPoint,
   2894                                        ShaderProgramID programPacked,
   2895                                        UniformLocation locationPacked,
   2896                                        GLsizei count,
   2897                                        GLboolean transpose,
   2898                                        const GLfloat *value)
   2899 {
   2900    if (!context->getExtensions().separateShaderObjectsEXT)
   2901    {
   2902        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2903        return false;
   2904    }
   2905 
   2906    return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked,
   2907                                               count, transpose, value);
   2908 }
   2909 
   2910 bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context,
   2911                                          angle::EntryPoint entryPoint,
   2912                                          ShaderProgramID programPacked,
   2913                                          UniformLocation locationPacked,
   2914                                          GLsizei count,
   2915                                          GLboolean transpose,
   2916                                          const GLfloat *value)
   2917 {
   2918    if (!context->getExtensions().separateShaderObjectsEXT)
   2919    {
   2920        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2921        return false;
   2922    }
   2923 
   2924    return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked,
   2925                                                 count, transpose, value);
   2926 }
   2927 
   2928 bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context,
   2929                                          angle::EntryPoint entryPoint,
   2930                                          ShaderProgramID programPacked,
   2931                                          UniformLocation locationPacked,
   2932                                          GLsizei count,
   2933                                          GLboolean transpose,
   2934                                          const GLfloat *value)
   2935 {
   2936    if (!context->getExtensions().separateShaderObjectsEXT)
   2937    {
   2938        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2939        return false;
   2940    }
   2941 
   2942    return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked,
   2943                                                 count, transpose, value);
   2944 }
   2945 
   2946 bool ValidateProgramUniformMatrix3fvEXT(const Context *context,
   2947                                        angle::EntryPoint entryPoint,
   2948                                        ShaderProgramID programPacked,
   2949                                        UniformLocation locationPacked,
   2950                                        GLsizei count,
   2951                                        GLboolean transpose,
   2952                                        const GLfloat *value)
   2953 {
   2954    if (!context->getExtensions().separateShaderObjectsEXT)
   2955    {
   2956        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2957        return false;
   2958    }
   2959 
   2960    return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked,
   2961                                               count, transpose, value);
   2962 }
   2963 
   2964 bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context,
   2965                                          angle::EntryPoint entryPoint,
   2966                                          ShaderProgramID programPacked,
   2967                                          UniformLocation locationPacked,
   2968                                          GLsizei count,
   2969                                          GLboolean transpose,
   2970                                          const GLfloat *value)
   2971 {
   2972    if (!context->getExtensions().separateShaderObjectsEXT)
   2973    {
   2974        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2975        return false;
   2976    }
   2977 
   2978    return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked,
   2979                                                 count, transpose, value);
   2980 }
   2981 
   2982 bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context,
   2983                                          angle::EntryPoint entryPoint,
   2984                                          ShaderProgramID programPacked,
   2985                                          UniformLocation locationPacked,
   2986                                          GLsizei count,
   2987                                          GLboolean transpose,
   2988                                          const GLfloat *value)
   2989 {
   2990    if (!context->getExtensions().separateShaderObjectsEXT)
   2991    {
   2992        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   2993        return false;
   2994    }
   2995 
   2996    return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked,
   2997                                                 count, transpose, value);
   2998 }
   2999 
   3000 bool ValidateProgramUniformMatrix4fvEXT(const Context *context,
   3001                                        angle::EntryPoint entryPoint,
   3002                                        ShaderProgramID programPacked,
   3003                                        UniformLocation locationPacked,
   3004                                        GLsizei count,
   3005                                        GLboolean transpose,
   3006                                        const GLfloat *value)
   3007 {
   3008    if (!context->getExtensions().separateShaderObjectsEXT)
   3009    {
   3010        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3011        return false;
   3012    }
   3013 
   3014    return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked,
   3015                                               count, transpose, value);
   3016 }
   3017 
   3018 bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context,
   3019                                          angle::EntryPoint entryPoint,
   3020                                          ShaderProgramID programPacked,
   3021                                          UniformLocation locationPacked,
   3022                                          GLsizei count,
   3023                                          GLboolean transpose,
   3024                                          const GLfloat *value)
   3025 {
   3026    if (!context->getExtensions().separateShaderObjectsEXT)
   3027    {
   3028        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3029        return false;
   3030    }
   3031 
   3032    return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked,
   3033                                                 count, transpose, value);
   3034 }
   3035 
   3036 bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context,
   3037                                          angle::EntryPoint entryPoint,
   3038                                          ShaderProgramID programPacked,
   3039                                          UniformLocation locationPacked,
   3040                                          GLsizei count,
   3041                                          GLboolean transpose,
   3042                                          const GLfloat *value)
   3043 {
   3044    if (!context->getExtensions().separateShaderObjectsEXT)
   3045    {
   3046        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3047        return false;
   3048    }
   3049 
   3050    return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
   3051                                                 count, transpose, value);
   3052 }
   3053 
   3054 bool ValidateUseProgramStagesEXT(const Context *context,
   3055                                 angle::EntryPoint entryPoint,
   3056                                 ProgramPipelineID pipelinePacked,
   3057                                 GLbitfield stages,
   3058                                 ShaderProgramID programPacked)
   3059 {
   3060    if (!context->getExtensions().separateShaderObjectsEXT)
   3061    {
   3062        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3063        return false;
   3064    }
   3065 
   3066    return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
   3067 }
   3068 
   3069 bool ValidateValidateProgramPipelineEXT(const Context *context,
   3070                                        angle::EntryPoint entryPoint,
   3071                                        ProgramPipelineID pipelinePacked)
   3072 {
   3073    if (!context->getExtensions().separateShaderObjectsEXT)
   3074    {
   3075        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3076        return false;
   3077    }
   3078 
   3079    return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked);
   3080 }
   3081 
   3082 // GL_EXT_debug_label
   3083 bool ValidateGetObjectLabelEXT(const Context *context,
   3084                               angle::EntryPoint entryPoint,
   3085                               GLenum type,
   3086                               GLuint object,
   3087                               GLsizei bufSize,
   3088                               const GLsizei *length,
   3089                               const GLchar *label)
   3090 {
   3091    if (!context->getExtensions().debugLabelEXT)
   3092    {
   3093        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3094        return false;
   3095    }
   3096 
   3097    if (bufSize < 0)
   3098    {
   3099        context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
   3100        return false;
   3101    }
   3102 
   3103    return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
   3104 }
   3105 
   3106 bool ValidateLabelObjectEXT(const Context *context,
   3107                            angle::EntryPoint entryPoint,
   3108                            GLenum type,
   3109                            GLuint object,
   3110                            GLsizei length,
   3111                            const GLchar *label)
   3112 {
   3113    if (!context->getExtensions().debugLabelEXT)
   3114    {
   3115        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3116        return false;
   3117    }
   3118 
   3119    if (length < 0)
   3120    {
   3121        context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLength);
   3122        return false;
   3123    }
   3124 
   3125    return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
   3126 }
   3127 
   3128 bool ValidateEGLImageTargetTextureStorageEXT(const Context *context,
   3129                                             angle::EntryPoint entryPoint,
   3130                                             GLuint texture,
   3131                                             GLeglImageOES image,
   3132                                             const GLint *attrib_list)
   3133 {
   3134    UNREACHABLE();
   3135    return false;
   3136 }
   3137 
   3138 bool ValidateEGLImageTargetTexStorageEXT(const Context *context,
   3139                                         angle::EntryPoint entryPoint,
   3140                                         GLenum target,
   3141                                         GLeglImageOES image,
   3142                                         const GLint *attrib_list)
   3143 {
   3144    if (!context->getExtensions().EGLImageStorageEXT)
   3145    {
   3146        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3147        return false;
   3148    }
   3149 
   3150    gl::TextureType targetType = FromGLenum<TextureType>(target);
   3151    switch (targetType)
   3152    {
   3153        case TextureType::External:
   3154            if (!context->getExtensions().EGLImageExternalOES)
   3155            {
   3156                context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
   3157                                          ToGLenum(targetType));
   3158            }
   3159            break;
   3160        case TextureType::CubeMapArray:
   3161            if (!context->getExtensions().textureCubeMapArrayAny())
   3162            {
   3163                context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
   3164                                          ToGLenum(targetType));
   3165            }
   3166            break;
   3167        case TextureType::_2D:
   3168        case TextureType::_2DArray:
   3169        case TextureType::_3D:
   3170        case TextureType::CubeMap:
   3171            break;
   3172        default:
   3173            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
   3174            return false;
   3175    }
   3176 
   3177    // Validate egl source image is valid
   3178    egl::Image *imageObject = static_cast<egl::Image *>(image);
   3179    if (!ValidateEGLImageObject(context, entryPoint, targetType, image))
   3180    {
   3181        return false;
   3182    }
   3183 
   3184    // attrib list validation
   3185    if (attrib_list != nullptr && attrib_list[0] != GL_NONE)
   3186    {
   3187        context->validationError(entryPoint, GL_INVALID_VALUE, kAttributeListNotNull);
   3188        return false;
   3189    }
   3190 
   3191    GLsizei levelCount    = imageObject->getLevelCount();
   3192    Extents size          = imageObject->getExtents();
   3193    GLsizei width         = static_cast<GLsizei>(size.width);
   3194    GLsizei height        = static_cast<GLsizei>(size.height);
   3195    GLsizei depth         = static_cast<GLsizei>(size.depth);
   3196    GLenum internalformat = imageObject->getFormat().info->sizedInternalFormat;
   3197 
   3198    if (width < 1 || height < 1 || depth < 1 || levelCount < 1)
   3199    {
   3200        context->validationError(entryPoint, GL_INVALID_VALUE, kTextureSizeTooSmall);
   3201        return false;
   3202    }
   3203 
   3204    if (!ValidateES3TexStorageParametersLevel(context, entryPoint, targetType, levelCount, width,
   3205                                              height, depth))
   3206    {
   3207        // Error already generated.
   3208        return false;
   3209    }
   3210 
   3211    if (targetType == TextureType::External)
   3212    {
   3213        const Caps &caps = context->getCaps();
   3214        if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
   3215        {
   3216            context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
   3217            return false;
   3218        }
   3219    }
   3220    else if (!ValidateES3TexStorageParametersExtent(context, entryPoint, targetType, levelCount,
   3221                                                    width, height, depth))
   3222    {
   3223        // Error already generated.
   3224        return false;
   3225    }
   3226 
   3227    if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, targetType))
   3228    {
   3229        // Error already generated.
   3230        return false;
   3231    }
   3232 
   3233    if (!ValidateES3TexStorageParametersFormat(context, entryPoint, targetType, levelCount,
   3234                                               internalformat, width, height, depth))
   3235    {
   3236        // Error already generated.
   3237        return false;
   3238    }
   3239 
   3240    return true;
   3241 }
   3242 
   3243 bool ValidateAcquireTexturesANGLE(const Context *context,
   3244                                  angle::EntryPoint entryPoint,
   3245                                  GLuint numTextures,
   3246                                  const TextureID *textures,
   3247                                  const GLenum *layouts)
   3248 {
   3249    if (!context->getExtensions().vulkanImageANGLE)
   3250    {
   3251        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3252        return false;
   3253    }
   3254 
   3255    for (GLuint i = 0; i < numTextures; ++i)
   3256    {
   3257        if (!context->getTexture(textures[i]))
   3258        {
   3259            context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
   3260            return false;
   3261        }
   3262        if (!IsValidImageLayout(FromGLenum<ImageLayout>(layouts[i])))
   3263        {
   3264            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout);
   3265            return false;
   3266        }
   3267    }
   3268 
   3269    return true;
   3270 }
   3271 
   3272 bool ValidateReleaseTexturesANGLE(const Context *context,
   3273                                  angle::EntryPoint entryPoint,
   3274                                  GLuint numTextures,
   3275                                  const TextureID *textures,
   3276                                  const GLenum *layouts)
   3277 {
   3278    if (!context->getExtensions().vulkanImageANGLE)
   3279    {
   3280        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3281        return false;
   3282    }
   3283    for (GLuint i = 0; i < numTextures; ++i)
   3284    {
   3285        if (!context->getTexture(textures[i]))
   3286        {
   3287            context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
   3288            return false;
   3289        }
   3290    }
   3291 
   3292    return true;
   3293 }
   3294 
   3295 bool ValidateFramebufferParameteriMESA(const Context *context,
   3296                                       angle::EntryPoint entryPoint,
   3297                                       GLenum target,
   3298                                       GLenum pname,
   3299                                       GLint param)
   3300 {
   3301    if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
   3302    {
   3303        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
   3304        return false;
   3305    }
   3306    return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param);
   3307 }
   3308 
   3309 bool ValidateGetFramebufferParameterivMESA(const Context *context,
   3310                                           angle::EntryPoint entryPoint,
   3311                                           GLenum target,
   3312                                           GLenum pname,
   3313                                           const GLint *params)
   3314 {
   3315    if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
   3316    {
   3317        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
   3318        return false;
   3319    }
   3320    return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params);
   3321 }
   3322 
   3323 // GL_AMD_performance_monitor
   3324 bool ValidateBeginPerfMonitorAMD(const Context *context,
   3325                                 angle::EntryPoint entryPoint,
   3326                                 GLuint monitor)
   3327 {
   3328    if (!context->getExtensions().performanceMonitorAMD)
   3329    {
   3330        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3331        return false;
   3332    }
   3333 
   3334    UNIMPLEMENTED();
   3335    return false;
   3336 }
   3337 
   3338 bool ValidateDeletePerfMonitorsAMD(const Context *context,
   3339                                   angle::EntryPoint entryPoint,
   3340                                   GLsizei n,
   3341                                   const GLuint *monitors)
   3342 {
   3343    if (!context->getExtensions().performanceMonitorAMD)
   3344    {
   3345        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3346        return false;
   3347    }
   3348 
   3349    UNIMPLEMENTED();
   3350    return false;
   3351 }
   3352 
   3353 bool ValidateEndPerfMonitorAMD(const Context *context, angle::EntryPoint entryPoint, GLuint monitor)
   3354 {
   3355    if (!context->getExtensions().performanceMonitorAMD)
   3356    {
   3357        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3358        return false;
   3359    }
   3360 
   3361    UNIMPLEMENTED();
   3362    return false;
   3363 }
   3364 
   3365 bool ValidateGenPerfMonitorsAMD(const Context *context,
   3366                                angle::EntryPoint entryPoint,
   3367                                GLsizei n,
   3368                                const GLuint *monitors)
   3369 {
   3370    if (!context->getExtensions().performanceMonitorAMD)
   3371    {
   3372        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3373        return false;
   3374    }
   3375 
   3376    UNIMPLEMENTED();
   3377    return false;
   3378 }
   3379 
   3380 bool ValidateGetPerfMonitorCounterDataAMD(const Context *context,
   3381                                          angle::EntryPoint entryPoint,
   3382                                          GLuint monitor,
   3383                                          GLenum pname,
   3384                                          GLsizei dataSize,
   3385                                          const GLuint *data,
   3386                                          const GLint *bytesWritten)
   3387 {
   3388    if (!context->getExtensions().performanceMonitorAMD)
   3389    {
   3390        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3391        return false;
   3392    }
   3393 
   3394    if (monitor != 0)
   3395    {
   3396        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitor);
   3397        return false;
   3398    }
   3399 
   3400    switch (pname)
   3401    {
   3402        case GL_PERFMON_RESULT_AVAILABLE_AMD:
   3403        case GL_PERFMON_RESULT_SIZE_AMD:
   3404        case GL_PERFMON_RESULT_AMD:
   3405            break;
   3406 
   3407        default:
   3408            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
   3409            return false;
   3410    }
   3411 
   3412    return true;
   3413 }
   3414 
   3415 bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context,
   3416                                          angle::EntryPoint entryPoint,
   3417                                          GLuint group,
   3418                                          GLuint counter,
   3419                                          GLenum pname,
   3420                                          const void *data)
   3421 {
   3422    if (!context->getExtensions().performanceMonitorAMD)
   3423    {
   3424        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3425        return false;
   3426    }
   3427 
   3428    const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
   3429 
   3430    if (group >= groups.size())
   3431    {
   3432        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
   3433        return false;
   3434    }
   3435 
   3436    if (counter >= groups[group].counters.size())
   3437    {
   3438        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
   3439        return false;
   3440    }
   3441 
   3442    switch (pname)
   3443    {
   3444        case GL_COUNTER_TYPE_AMD:
   3445        case GL_COUNTER_RANGE_AMD:
   3446            break;
   3447 
   3448        default:
   3449            context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
   3450            return false;
   3451    }
   3452 
   3453    return true;
   3454 }
   3455 
   3456 bool ValidateGetPerfMonitorCounterStringAMD(const Context *context,
   3457                                            angle::EntryPoint entryPoint,
   3458                                            GLuint group,
   3459                                            GLuint counter,
   3460                                            GLsizei bufSize,
   3461                                            const GLsizei *length,
   3462                                            const GLchar *counterString)
   3463 {
   3464    if (!context->getExtensions().performanceMonitorAMD)
   3465    {
   3466        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3467        return false;
   3468    }
   3469 
   3470    const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
   3471 
   3472    if (group >= groups.size())
   3473    {
   3474        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
   3475        return false;
   3476    }
   3477 
   3478    if (counter >= groups[group].counters.size())
   3479    {
   3480        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
   3481        return false;
   3482    }
   3483 
   3484    return true;
   3485 }
   3486 
   3487 bool ValidateGetPerfMonitorCountersAMD(const Context *context,
   3488                                       angle::EntryPoint entryPoint,
   3489                                       GLuint group,
   3490                                       const GLint *numCounters,
   3491                                       const GLint *maxActiveCounters,
   3492                                       GLsizei counterSize,
   3493                                       const GLuint *counters)
   3494 {
   3495    if (!context->getExtensions().performanceMonitorAMD)
   3496    {
   3497        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3498        return false;
   3499    }
   3500 
   3501    const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
   3502 
   3503    if (group >= groups.size())
   3504    {
   3505        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
   3506        return false;
   3507    }
   3508 
   3509    return true;
   3510 }
   3511 
   3512 bool ValidateGetPerfMonitorGroupStringAMD(const Context *context,
   3513                                          angle::EntryPoint entryPoint,
   3514                                          GLuint group,
   3515                                          GLsizei bufSize,
   3516                                          const GLsizei *length,
   3517                                          const GLchar *groupString)
   3518 {
   3519    if (!context->getExtensions().performanceMonitorAMD)
   3520    {
   3521        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3522        return false;
   3523    }
   3524 
   3525    const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
   3526 
   3527    if (group >= groups.size())
   3528    {
   3529        context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
   3530        return false;
   3531    }
   3532 
   3533    return true;
   3534 }
   3535 
   3536 bool ValidateGetPerfMonitorGroupsAMD(const Context *context,
   3537                                     angle::EntryPoint entryPoint,
   3538                                     const GLint *numGroups,
   3539                                     GLsizei groupsSize,
   3540                                     const GLuint *groups)
   3541 {
   3542    if (!context->getExtensions().performanceMonitorAMD)
   3543    {
   3544        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3545        return false;
   3546    }
   3547 
   3548    return true;
   3549 }
   3550 
   3551 bool ValidateSelectPerfMonitorCountersAMD(const Context *context,
   3552                                          angle::EntryPoint entryPoint,
   3553                                          GLuint monitor,
   3554                                          GLboolean enable,
   3555                                          GLuint group,
   3556                                          GLint numCounters,
   3557                                          const GLuint *counterList)
   3558 {
   3559    if (!context->getExtensions().performanceMonitorAMD)
   3560    {
   3561        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3562        return false;
   3563    }
   3564 
   3565    UNIMPLEMENTED();
   3566    return false;
   3567 }
   3568 
   3569 bool ValidateShadingRateQCOM(const Context *context, angle::EntryPoint entryPoint, GLenum rate)
   3570 {
   3571    if (!context->getExtensions().shadingRateQCOM)
   3572    {
   3573        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3574        return false;
   3575    }
   3576 
   3577    gl::ShadingRate shadingRate = gl::FromGLenum<gl::ShadingRate>(rate);
   3578    if (shadingRate == gl::ShadingRate::Undefined || shadingRate == gl::ShadingRate::InvalidEnum)
   3579    {
   3580        context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingRate);
   3581        return false;
   3582    }
   3583 
   3584    return true;
   3585 }
   3586 
   3587 bool ValidateLogicOpANGLE(const Context *context,
   3588                          angle::EntryPoint entryPoint,
   3589                          LogicalOperation opcodePacked)
   3590 {
   3591    if (!context->getExtensions().logicOpANGLE)
   3592    {
   3593        context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
   3594        return false;
   3595    }
   3596 
   3597    return ValidateLogicOpCommon(context, entryPoint, opcodePacked);
   3598 }
   3599 }  // namespace gl