Home | History | Annotate | Download | only in libGLESv2
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 //
      7 
      8 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
      9 
     10 #include "common/version.h"
     11 
     12 #include "libGLESv2/main.h"
     13 #include "common/utilities.h"
     14 #include "libGLESv2/formatutils.h"
     15 #include "libGLESv2/Buffer.h"
     16 #include "libGLESv2/Fence.h"
     17 #include "libGLESv2/Framebuffer.h"
     18 #include "libGLESv2/Renderbuffer.h"
     19 #include "libGLESv2/Program.h"
     20 #include "libGLESv2/ProgramBinary.h"
     21 #include "libGLESv2/Texture.h"
     22 #include "libGLESv2/Query.h"
     23 #include "libGLESv2/Context.h"
     24 #include "libGLESv2/VertexArray.h"
     25 #include "libGLESv2/TransformFeedback.h"
     26 
     27 #include "libGLESv2/validationES.h"
     28 #include "libGLESv2/validationES2.h"
     29 #include "libGLESv2/validationES3.h"
     30 #include "libGLESv2/queryconversions.h"
     31 
     32 extern "C"
     33 {
     34 
     35 // OpenGL ES 2.0 functions
     36 
     37 void __stdcall glActiveTexture(GLenum texture)
     38 {
     39     EVENT("(GLenum texture = 0x%X)", texture);
     40 
     41     try
     42     {
     43         gl::Context *context = gl::getNonLostContext();
     44 
     45         if (context)
     46         {
     47             if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
     48             {
     49                 return gl::error(GL_INVALID_ENUM);
     50             }
     51 
     52             context->setActiveSampler(texture - GL_TEXTURE0);
     53         }
     54     }
     55     catch (...)
     56     {
     57         return gl::error(GL_OUT_OF_MEMORY);
     58     }
     59 }
     60 
     61 void __stdcall glAttachShader(GLuint program, GLuint shader)
     62 {
     63     EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
     64 
     65     try
     66     {
     67         gl::Context *context = gl::getNonLostContext();
     68 
     69         if (context)
     70         {
     71             gl::Program *programObject = context->getProgram(program);
     72             gl::Shader *shaderObject = context->getShader(shader);
     73 
     74             if (!programObject)
     75             {
     76                 if (context->getShader(program))
     77                 {
     78                     return gl::error(GL_INVALID_OPERATION);
     79                 }
     80                 else
     81                 {
     82                     return gl::error(GL_INVALID_VALUE);
     83                 }
     84             }
     85 
     86             if (!shaderObject)
     87             {
     88                 if (context->getProgram(shader))
     89                 {
     90                     return gl::error(GL_INVALID_OPERATION);
     91                 }
     92                 else
     93                 {
     94                     return gl::error(GL_INVALID_VALUE);
     95                 }
     96             }
     97 
     98             if (!programObject->attachShader(shaderObject))
     99             {
    100                 return gl::error(GL_INVALID_OPERATION);
    101             }
    102         }
    103     }
    104     catch (...)
    105     {
    106         return gl::error(GL_OUT_OF_MEMORY);
    107     }
    108 }
    109 
    110 void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
    111 {
    112     EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
    113 
    114     try
    115     {
    116         gl::Context *context = gl::getNonLostContext();
    117 
    118         if (context)
    119         {
    120             if (!ValidateBeginQuery(context, target, id))
    121             {
    122                 return;
    123             }
    124 
    125             context->beginQuery(target, id);
    126         }
    127     }
    128     catch (...)
    129     {
    130         return gl::error(GL_OUT_OF_MEMORY);
    131     }
    132 }
    133 
    134 void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
    135 {
    136     EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
    137 
    138     try
    139     {
    140         if (index >= gl::MAX_VERTEX_ATTRIBS)
    141         {
    142             return gl::error(GL_INVALID_VALUE);
    143         }
    144 
    145         gl::Context *context = gl::getNonLostContext();
    146 
    147         if (context)
    148         {
    149             gl::Program *programObject = context->getProgram(program);
    150 
    151             if (!programObject)
    152             {
    153                 if (context->getShader(program))
    154                 {
    155                     return gl::error(GL_INVALID_OPERATION);
    156                 }
    157                 else
    158                 {
    159                     return gl::error(GL_INVALID_VALUE);
    160                 }
    161             }
    162 
    163             if (strncmp(name, "gl_", 3) == 0)
    164             {
    165                 return gl::error(GL_INVALID_OPERATION);
    166             }
    167 
    168             programObject->bindAttributeLocation(index, name);
    169         }
    170     }
    171     catch (...)
    172     {
    173         return gl::error(GL_OUT_OF_MEMORY);
    174     }
    175 }
    176 
    177 void __stdcall glBindBuffer(GLenum target, GLuint buffer)
    178 {
    179     EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
    180 
    181     try
    182     {
    183         gl::Context *context = gl::getNonLostContext();
    184 
    185         if (context)
    186         {
    187             if (!gl::ValidBufferTarget(context, target))
    188             {
    189                 return gl::error(GL_INVALID_ENUM);
    190             }
    191 
    192             switch (target)
    193             {
    194               case GL_ARRAY_BUFFER:
    195                 context->bindArrayBuffer(buffer);
    196                 return;
    197               case GL_ELEMENT_ARRAY_BUFFER:
    198                 context->bindElementArrayBuffer(buffer);
    199                 return;
    200               case GL_COPY_READ_BUFFER:
    201                 context->bindCopyReadBuffer(buffer);
    202                 return;
    203               case GL_COPY_WRITE_BUFFER:
    204                 context->bindCopyWriteBuffer(buffer);
    205                 return;
    206               case GL_PIXEL_PACK_BUFFER:
    207                 context->bindPixelPackBuffer(buffer);
    208                 return;
    209               case GL_PIXEL_UNPACK_BUFFER:
    210                 context->bindPixelUnpackBuffer(buffer);
    211                 return;
    212               case GL_UNIFORM_BUFFER:
    213                 context->bindGenericUniformBuffer(buffer);
    214                 return;
    215               case GL_TRANSFORM_FEEDBACK_BUFFER:
    216                 context->bindGenericTransformFeedbackBuffer(buffer);
    217                 return;
    218               default:
    219                 return gl::error(GL_INVALID_ENUM);
    220             }
    221         }
    222     }
    223     catch (...)
    224     {
    225         return gl::error(GL_OUT_OF_MEMORY);
    226     }
    227 }
    228 
    229 void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
    230 {
    231     EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
    232 
    233     try
    234     {
    235         if (!gl::ValidFramebufferTarget(target))
    236         {
    237             return gl::error(GL_INVALID_ENUM);
    238         }
    239 
    240         gl::Context *context = gl::getNonLostContext();
    241 
    242         if (context)
    243         {
    244             if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
    245             {
    246                 context->bindReadFramebuffer(framebuffer);
    247             }
    248 
    249             if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
    250             {
    251                 context->bindDrawFramebuffer(framebuffer);
    252             }
    253         }
    254     }
    255     catch (...)
    256     {
    257         return gl::error(GL_OUT_OF_MEMORY);
    258     }
    259 }
    260 
    261 void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
    262 {
    263     EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
    264 
    265     try
    266     {
    267         if (target != GL_RENDERBUFFER)
    268         {
    269             return gl::error(GL_INVALID_ENUM);
    270         }
    271 
    272         gl::Context *context = gl::getNonLostContext();
    273 
    274         if (context)
    275         {
    276             context->bindRenderbuffer(renderbuffer);
    277         }
    278     }
    279     catch (...)
    280     {
    281         return gl::error(GL_OUT_OF_MEMORY);
    282     }
    283 }
    284 
    285 void __stdcall glBindTexture(GLenum target, GLuint texture)
    286 {
    287     EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
    288 
    289     try
    290     {
    291         gl::Context *context = gl::getNonLostContext();
    292 
    293         if (context)
    294         {
    295             gl::Texture *textureObject = context->getTexture(texture);
    296 
    297             if (textureObject && textureObject->getTarget() != target && texture != 0)
    298             {
    299                 return gl::error(GL_INVALID_OPERATION);
    300             }
    301 
    302             switch (target)
    303             {
    304               case GL_TEXTURE_2D:
    305                 context->bindTexture2D(texture);
    306                 return;
    307               case GL_TEXTURE_CUBE_MAP:
    308                 context->bindTextureCubeMap(texture);
    309                 return;
    310               case GL_TEXTURE_3D:
    311                 if (context->getClientVersion() < 3)
    312                 {
    313                     return gl::error(GL_INVALID_ENUM);
    314                 }
    315                 context->bindTexture3D(texture);
    316                 return;
    317               case GL_TEXTURE_2D_ARRAY:
    318                 if (context->getClientVersion() < 3)
    319                 {
    320                     return gl::error(GL_INVALID_ENUM);
    321                 }
    322                 context->bindTexture2DArray(texture);
    323                 return;
    324               default:
    325                 return gl::error(GL_INVALID_ENUM);
    326             }
    327         }
    328     }
    329     catch (...)
    330     {
    331         return gl::error(GL_OUT_OF_MEMORY);
    332     }
    333 }
    334 
    335 void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
    336 {
    337     EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
    338           red, green, blue, alpha);
    339 
    340     try
    341     {
    342         gl::Context* context = gl::getNonLostContext();
    343 
    344         if (context)
    345         {
    346             context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
    347         }
    348     }
    349     catch (...)
    350     {
    351         return gl::error(GL_OUT_OF_MEMORY);
    352     }
    353 }
    354 
    355 void __stdcall glBlendEquation(GLenum mode)
    356 {
    357     glBlendEquationSeparate(mode, mode);
    358 }
    359 
    360 void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
    361 {
    362     EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
    363 
    364     try
    365     {
    366         gl::Context *context = gl::getNonLostContext();
    367 
    368         switch (modeRGB)
    369         {
    370           case GL_FUNC_ADD:
    371           case GL_FUNC_SUBTRACT:
    372           case GL_FUNC_REVERSE_SUBTRACT:
    373           case GL_MIN:
    374           case GL_MAX:
    375             break;
    376 
    377           default:
    378             return gl::error(GL_INVALID_ENUM);
    379         }
    380 
    381         switch (modeAlpha)
    382         {
    383           case GL_FUNC_ADD:
    384           case GL_FUNC_SUBTRACT:
    385           case GL_FUNC_REVERSE_SUBTRACT:
    386           case GL_MIN:
    387           case GL_MAX:
    388             break;
    389 
    390           default:
    391             return gl::error(GL_INVALID_ENUM);
    392         }
    393 
    394         if (context)
    395         {
    396             context->setBlendEquation(modeRGB, modeAlpha);
    397         }
    398     }
    399     catch (...)
    400     {
    401         return gl::error(GL_OUT_OF_MEMORY);
    402     }
    403 }
    404 
    405 void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
    406 {
    407     glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
    408 }
    409 
    410 void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
    411 {
    412     EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
    413           srcRGB, dstRGB, srcAlpha, dstAlpha);
    414 
    415     try
    416     {
    417         gl::Context *context = gl::getNonLostContext();
    418 
    419         switch (srcRGB)
    420         {
    421           case GL_ZERO:
    422           case GL_ONE:
    423           case GL_SRC_COLOR:
    424           case GL_ONE_MINUS_SRC_COLOR:
    425           case GL_DST_COLOR:
    426           case GL_ONE_MINUS_DST_COLOR:
    427           case GL_SRC_ALPHA:
    428           case GL_ONE_MINUS_SRC_ALPHA:
    429           case GL_DST_ALPHA:
    430           case GL_ONE_MINUS_DST_ALPHA:
    431           case GL_CONSTANT_COLOR:
    432           case GL_ONE_MINUS_CONSTANT_COLOR:
    433           case GL_CONSTANT_ALPHA:
    434           case GL_ONE_MINUS_CONSTANT_ALPHA:
    435           case GL_SRC_ALPHA_SATURATE:
    436             break;
    437           default:
    438             return gl::error(GL_INVALID_ENUM);
    439         }
    440 
    441         switch (dstRGB)
    442         {
    443           case GL_ZERO:
    444           case GL_ONE:
    445           case GL_SRC_COLOR:
    446           case GL_ONE_MINUS_SRC_COLOR:
    447           case GL_DST_COLOR:
    448           case GL_ONE_MINUS_DST_COLOR:
    449           case GL_SRC_ALPHA:
    450           case GL_ONE_MINUS_SRC_ALPHA:
    451           case GL_DST_ALPHA:
    452           case GL_ONE_MINUS_DST_ALPHA:
    453           case GL_CONSTANT_COLOR:
    454           case GL_ONE_MINUS_CONSTANT_COLOR:
    455           case GL_CONSTANT_ALPHA:
    456           case GL_ONE_MINUS_CONSTANT_ALPHA:
    457             break;
    458 
    459           case GL_SRC_ALPHA_SATURATE:
    460             if (!context || context->getClientVersion() < 3)
    461             {
    462                 return gl::error(GL_INVALID_ENUM);
    463             }
    464             break;
    465 
    466           default:
    467             return gl::error(GL_INVALID_ENUM);
    468         }
    469 
    470         switch (srcAlpha)
    471         {
    472           case GL_ZERO:
    473           case GL_ONE:
    474           case GL_SRC_COLOR:
    475           case GL_ONE_MINUS_SRC_COLOR:
    476           case GL_DST_COLOR:
    477           case GL_ONE_MINUS_DST_COLOR:
    478           case GL_SRC_ALPHA:
    479           case GL_ONE_MINUS_SRC_ALPHA:
    480           case GL_DST_ALPHA:
    481           case GL_ONE_MINUS_DST_ALPHA:
    482           case GL_CONSTANT_COLOR:
    483           case GL_ONE_MINUS_CONSTANT_COLOR:
    484           case GL_CONSTANT_ALPHA:
    485           case GL_ONE_MINUS_CONSTANT_ALPHA:
    486           case GL_SRC_ALPHA_SATURATE:
    487             break;
    488           default:
    489             return gl::error(GL_INVALID_ENUM);
    490         }
    491 
    492         switch (dstAlpha)
    493         {
    494           case GL_ZERO:
    495           case GL_ONE:
    496           case GL_SRC_COLOR:
    497           case GL_ONE_MINUS_SRC_COLOR:
    498           case GL_DST_COLOR:
    499           case GL_ONE_MINUS_DST_COLOR:
    500           case GL_SRC_ALPHA:
    501           case GL_ONE_MINUS_SRC_ALPHA:
    502           case GL_DST_ALPHA:
    503           case GL_ONE_MINUS_DST_ALPHA:
    504           case GL_CONSTANT_COLOR:
    505           case GL_ONE_MINUS_CONSTANT_COLOR:
    506           case GL_CONSTANT_ALPHA:
    507           case GL_ONE_MINUS_CONSTANT_ALPHA:
    508             break;
    509 
    510           case GL_SRC_ALPHA_SATURATE:
    511             if (!context || context->getClientVersion() < 3)
    512             {
    513                 return gl::error(GL_INVALID_ENUM);
    514             }
    515             break;
    516 
    517           default:
    518             return gl::error(GL_INVALID_ENUM);
    519         }
    520 
    521         bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
    522                                   dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
    523 
    524         bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
    525                                   dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
    526 
    527         if (constantColorUsed && constantAlphaUsed)
    528         {
    529             ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
    530             return gl::error(GL_INVALID_OPERATION);
    531         }
    532 
    533         if (context)
    534         {
    535             context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
    536         }
    537     }
    538     catch (...)
    539     {
    540         return gl::error(GL_OUT_OF_MEMORY);
    541     }
    542 }
    543 
    544 void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
    545 {
    546     EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
    547           target, size, data, usage);
    548 
    549     try
    550     {
    551         if (size < 0)
    552         {
    553             return gl::error(GL_INVALID_VALUE);
    554         }
    555 
    556         gl::Context *context = gl::getNonLostContext();
    557 
    558         switch (usage)
    559         {
    560           case GL_STREAM_DRAW:
    561           case GL_STATIC_DRAW:
    562           case GL_DYNAMIC_DRAW:
    563             break;
    564 
    565           case GL_STREAM_READ:
    566           case GL_STREAM_COPY:
    567           case GL_STATIC_READ:
    568           case GL_STATIC_COPY:
    569           case GL_DYNAMIC_READ:
    570           case GL_DYNAMIC_COPY:
    571             if (context && context->getClientVersion() < 3)
    572             {
    573               return gl::error(GL_INVALID_ENUM);
    574             }
    575             break;
    576 
    577           default:
    578             return gl::error(GL_INVALID_ENUM);
    579         }
    580 
    581         if (context)
    582         {
    583             if (!gl::ValidBufferTarget(context, target))
    584             {
    585                 return gl::error(GL_INVALID_ENUM);
    586             }
    587 
    588             gl::Buffer *buffer = context->getTargetBuffer(target);
    589 
    590             if (!buffer)
    591             {
    592                 return gl::error(GL_INVALID_OPERATION);
    593             }
    594 
    595             buffer->bufferData(data, size, usage);
    596         }
    597     }
    598     catch (...)
    599     {
    600         return gl::error(GL_OUT_OF_MEMORY);
    601     }
    602 }
    603 
    604 void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
    605 {
    606     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
    607           target, offset, size, data);
    608 
    609     try
    610     {
    611         if (size < 0 || offset < 0)
    612         {
    613             return gl::error(GL_INVALID_VALUE);
    614         }
    615 
    616         if (data == NULL)
    617         {
    618             return;
    619         }
    620 
    621         gl::Context *context = gl::getNonLostContext();
    622 
    623         if (context)
    624         {
    625             if (!gl::ValidBufferTarget(context, target))
    626             {
    627                 return gl::error(GL_INVALID_ENUM);
    628             }
    629 
    630             gl::Buffer *buffer = context->getTargetBuffer(target);
    631 
    632             if (!buffer)
    633             {
    634                 return gl::error(GL_INVALID_OPERATION);
    635             }
    636 
    637             if (buffer->mapped())
    638             {
    639                 return gl::error(GL_INVALID_OPERATION);
    640             }
    641 
    642             // Check for possible overflow of size + offset
    643             if (!rx::IsUnsignedAdditionSafe<size_t>(size, offset))
    644             {
    645                 return gl::error(GL_OUT_OF_MEMORY);
    646             }
    647 
    648             if (size + offset > buffer->size())
    649             {
    650                 return gl::error(GL_INVALID_VALUE);
    651             }
    652 
    653             buffer->bufferSubData(data, size, offset);
    654         }
    655     }
    656     catch (...)
    657     {
    658         return gl::error(GL_OUT_OF_MEMORY);
    659     }
    660 }
    661 
    662 GLenum __stdcall glCheckFramebufferStatus(GLenum target)
    663 {
    664     EVENT("(GLenum target = 0x%X)", target);
    665 
    666     try
    667     {
    668         if (!gl::ValidFramebufferTarget(target))
    669         {
    670             return gl::error(GL_INVALID_ENUM, 0);
    671         }
    672 
    673         gl::Context *context = gl::getNonLostContext();
    674 
    675         if (context)
    676         {
    677             gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
    678             ASSERT(framebuffer);
    679             return framebuffer->completeness();
    680         }
    681     }
    682     catch (...)
    683     {
    684         return gl::error(GL_OUT_OF_MEMORY, 0);
    685     }
    686 
    687     return 0;
    688 }
    689 
    690 void __stdcall glClear(GLbitfield mask)
    691 {
    692     EVENT("(GLbitfield mask = 0x%X)", mask);
    693 
    694     try
    695     {
    696         gl::Context *context = gl::getNonLostContext();
    697 
    698         if (context)
    699         {
    700             gl::Framebuffer *framebufferObject = context->getDrawFramebuffer();
    701 
    702             if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
    703             {
    704                 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
    705             }
    706 
    707             if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
    708             {
    709                 return gl::error(GL_INVALID_VALUE);
    710             }
    711 
    712             context->clear(mask);
    713         }
    714     }
    715     catch (...)
    716     {
    717         return gl::error(GL_OUT_OF_MEMORY);
    718     }
    719 }
    720 
    721 void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
    722 {
    723     EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
    724           red, green, blue, alpha);
    725 
    726     try
    727     {
    728         gl::Context *context = gl::getNonLostContext();
    729 
    730         if (context)
    731         {
    732             context->setClearColor(red, green, blue, alpha);
    733         }
    734     }
    735     catch (...)
    736     {
    737         return gl::error(GL_OUT_OF_MEMORY);
    738     }
    739 }
    740 
    741 void __stdcall glClearDepthf(GLclampf depth)
    742 {
    743     EVENT("(GLclampf depth = %f)", depth);
    744 
    745     try
    746     {
    747         gl::Context *context = gl::getNonLostContext();
    748 
    749         if (context)
    750         {
    751             context->setClearDepth(depth);
    752         }
    753     }
    754     catch (...)
    755     {
    756         return gl::error(GL_OUT_OF_MEMORY);
    757     }
    758 }
    759 
    760 void __stdcall glClearStencil(GLint s)
    761 {
    762     EVENT("(GLint s = %d)", s);
    763 
    764     try
    765     {
    766         gl::Context *context = gl::getNonLostContext();
    767 
    768         if (context)
    769         {
    770             context->setClearStencil(s);
    771         }
    772     }
    773     catch (...)
    774     {
    775         return gl::error(GL_OUT_OF_MEMORY);
    776     }
    777 }
    778 
    779 void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
    780 {
    781     EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)",
    782           red, green, blue, alpha);
    783 
    784     try
    785     {
    786         gl::Context *context = gl::getNonLostContext();
    787 
    788         if (context)
    789         {
    790             context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
    791         }
    792     }
    793     catch (...)
    794     {
    795         return gl::error(GL_OUT_OF_MEMORY);
    796     }
    797 }
    798 
    799 void __stdcall glCompileShader(GLuint shader)
    800 {
    801     EVENT("(GLuint shader = %d)", shader);
    802 
    803     try
    804     {
    805         gl::Context *context = gl::getNonLostContext();
    806 
    807         if (context)
    808         {
    809             gl::Shader *shaderObject = context->getShader(shader);
    810 
    811             if (!shaderObject)
    812             {
    813                 if (context->getProgram(shader))
    814                 {
    815                     return gl::error(GL_INVALID_OPERATION);
    816                 }
    817                 else
    818                 {
    819                     return gl::error(GL_INVALID_VALUE);
    820                 }
    821             }
    822 
    823             shaderObject->compile();
    824         }
    825     }
    826     catch (...)
    827     {
    828         return gl::error(GL_OUT_OF_MEMORY);
    829     }
    830 }
    831 
    832 void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
    833                                       GLint border, GLsizei imageSize, const GLvoid* data)
    834 {
    835     EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
    836           "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
    837           target, level, internalformat, width, height, border, imageSize, data);
    838 
    839     try
    840     {
    841         gl::Context *context = gl::getNonLostContext();
    842 
    843         if (context)
    844         {
    845             if (context->getClientVersion() < 3 &&
    846                 !ValidateES2TexImageParameters(context, target, level, internalformat, true, false,
    847                                                0, 0, width, height, border, GL_NONE, GL_NONE, data))
    848             {
    849                 return;
    850             }
    851 
    852             if (context->getClientVersion() >= 3 &&
    853                 !ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
    854                                                0, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, data))
    855             {
    856                 return;
    857             }
    858 
    859             if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height))
    860             {
    861                 return gl::error(GL_INVALID_VALUE);
    862             }
    863 
    864             switch (target)
    865             {
    866               case GL_TEXTURE_2D:
    867                 {
    868                     gl::Texture2D *texture = context->getTexture2D();
    869                     texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
    870                 }
    871                 break;
    872 
    873               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
    874               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
    875               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
    876               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
    877               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
    878               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
    879                 {
    880                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
    881                     texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
    882                 }
    883                 break;
    884 
    885               default:
    886                 return gl::error(GL_INVALID_ENUM);
    887             }
    888         }
    889     }
    890     catch (...)
    891     {
    892         return gl::error(GL_OUT_OF_MEMORY);
    893     }
    894 }
    895 
    896 void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
    897                                          GLenum format, GLsizei imageSize, const GLvoid* data)
    898 {
    899     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
    900           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
    901           "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
    902           target, level, xoffset, yoffset, width, height, format, imageSize, data);
    903 
    904     try
    905     {
    906         gl::Context *context = gl::getNonLostContext();
    907 
    908         if (context)
    909         {
    910             if (context->getClientVersion() < 3 &&
    911                 !ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true,
    912                                                xoffset, yoffset, width, height, 0, GL_NONE, GL_NONE, data))
    913             {
    914                 return;
    915             }
    916 
    917             if (context->getClientVersion() >= 3 &&
    918                 !ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
    919                                                xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, data))
    920             {
    921                 return;
    922             }
    923 
    924             if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height))
    925             {
    926                 return gl::error(GL_INVALID_VALUE);
    927             }
    928 
    929             switch (target)
    930             {
    931               case GL_TEXTURE_2D:
    932                 {
    933                     gl::Texture2D *texture = context->getTexture2D();
    934                     texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
    935                 }
    936                 break;
    937 
    938               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
    939               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
    940               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
    941               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
    942               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
    943               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
    944                 {
    945                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
    946                     texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
    947                 }
    948                 break;
    949 
    950               default:
    951                 return gl::error(GL_INVALID_ENUM);
    952             }
    953         }
    954     }
    955     catch (...)
    956     {
    957         return gl::error(GL_OUT_OF_MEMORY);
    958     }
    959 }
    960 
    961 void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
    962 {
    963     EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
    964           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
    965           target, level, internalformat, x, y, width, height, border);
    966 
    967     try
    968     {
    969         gl::Context *context = gl::getNonLostContext();
    970 
    971         if (context)
    972         {
    973             if (context->getClientVersion() < 3 &&
    974                 !ValidateES2CopyTexImageParameters(context, target, level, internalformat, false,
    975                                                    0, 0, x, y, width, height, border))
    976             {
    977                 return;
    978             }
    979 
    980             if (context->getClientVersion() >= 3 &&
    981                 !ValidateES3CopyTexImageParameters(context, target, level, internalformat, false,
    982                                                    0, 0, 0, x, y, width, height, border))
    983             {
    984                 return;
    985             }
    986 
    987             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
    988 
    989             switch (target)
    990             {
    991               case GL_TEXTURE_2D:
    992                 {
    993                     gl::Texture2D *texture = context->getTexture2D();
    994                     texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
    995                 }
    996                 break;
    997 
    998               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
    999               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   1000               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   1001               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   1002               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   1003               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   1004                 {
   1005                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
   1006                     texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
   1007                 }
   1008                 break;
   1009 
   1010              default:
   1011                 return gl::error(GL_INVALID_ENUM);
   1012             }
   1013         }
   1014     }
   1015     catch (...)
   1016     {
   1017         return gl::error(GL_OUT_OF_MEMORY);
   1018     }
   1019 }
   1020 
   1021 void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
   1022 {
   1023     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
   1024           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
   1025           target, level, xoffset, yoffset, x, y, width, height);
   1026 
   1027     try
   1028     {
   1029         gl::Context *context = gl::getNonLostContext();
   1030 
   1031         if (context)
   1032         {
   1033             if (context->getClientVersion() < 3 &&
   1034                 !ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true,
   1035                                                    xoffset, yoffset, x, y, width, height, 0))
   1036             {
   1037                 return;
   1038             }
   1039 
   1040             if (context->getClientVersion() >= 3 &&
   1041                 !ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true,
   1042                                                    xoffset, yoffset, 0, x, y, width, height, 0))
   1043             {
   1044                 return;
   1045             }
   1046 
   1047             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
   1048 
   1049             switch (target)
   1050             {
   1051               case GL_TEXTURE_2D:
   1052                 {
   1053                     gl::Texture2D *texture = context->getTexture2D();
   1054                     texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
   1055                 }
   1056                 break;
   1057 
   1058               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   1059               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   1060               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   1061               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   1062               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   1063               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   1064                 {
   1065                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
   1066                     texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
   1067                 }
   1068                 break;
   1069 
   1070               default:
   1071                 return gl::error(GL_INVALID_ENUM);
   1072             }
   1073         }
   1074     }
   1075 
   1076     catch (...)
   1077     {
   1078         return gl::error(GL_OUT_OF_MEMORY);
   1079     }
   1080 }
   1081 
   1082 GLuint __stdcall glCreateProgram(void)
   1083 {
   1084     EVENT("()");
   1085 
   1086     try
   1087     {
   1088         gl::Context *context = gl::getNonLostContext();
   1089 
   1090         if (context)
   1091         {
   1092             return context->createProgram();
   1093         }
   1094     }
   1095     catch (...)
   1096     {
   1097         return gl::error(GL_OUT_OF_MEMORY, 0);
   1098     }
   1099 
   1100     return 0;
   1101 }
   1102 
   1103 GLuint __stdcall glCreateShader(GLenum type)
   1104 {
   1105     EVENT("(GLenum type = 0x%X)", type);
   1106 
   1107     try
   1108     {
   1109         gl::Context *context = gl::getNonLostContext();
   1110 
   1111         if (context)
   1112         {
   1113             switch (type)
   1114             {
   1115               case GL_FRAGMENT_SHADER:
   1116               case GL_VERTEX_SHADER:
   1117                 return context->createShader(type);
   1118               default:
   1119                 return gl::error(GL_INVALID_ENUM, 0);
   1120             }
   1121         }
   1122     }
   1123     catch (...)
   1124     {
   1125         return gl::error(GL_OUT_OF_MEMORY, 0);
   1126     }
   1127 
   1128     return 0;
   1129 }
   1130 
   1131 void __stdcall glCullFace(GLenum mode)
   1132 {
   1133     EVENT("(GLenum mode = 0x%X)", mode);
   1134 
   1135     try
   1136     {
   1137         switch (mode)
   1138         {
   1139           case GL_FRONT:
   1140           case GL_BACK:
   1141           case GL_FRONT_AND_BACK:
   1142             {
   1143                 gl::Context *context = gl::getNonLostContext();
   1144 
   1145                 if (context)
   1146                 {
   1147                     context->setCullMode(mode);
   1148                 }
   1149             }
   1150             break;
   1151           default:
   1152             return gl::error(GL_INVALID_ENUM);
   1153         }
   1154     }
   1155     catch (...)
   1156     {
   1157         return gl::error(GL_OUT_OF_MEMORY);
   1158     }
   1159 }
   1160 
   1161 void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
   1162 {
   1163     EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
   1164 
   1165     try
   1166     {
   1167         if (n < 0)
   1168         {
   1169             return gl::error(GL_INVALID_VALUE);
   1170         }
   1171 
   1172         gl::Context *context = gl::getNonLostContext();
   1173 
   1174         if (context)
   1175         {
   1176             for (int i = 0; i < n; i++)
   1177             {
   1178                 context->deleteBuffer(buffers[i]);
   1179             }
   1180         }
   1181     }
   1182     catch (...)
   1183     {
   1184         return gl::error(GL_OUT_OF_MEMORY);
   1185     }
   1186 }
   1187 
   1188 void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
   1189 {
   1190     EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
   1191 
   1192     try
   1193     {
   1194         if (n < 0)
   1195         {
   1196             return gl::error(GL_INVALID_VALUE);
   1197         }
   1198 
   1199         gl::Context *context = gl::getNonLostContext();
   1200 
   1201         if (context)
   1202         {
   1203             for (int i = 0; i < n; i++)
   1204             {
   1205                 context->deleteFenceNV(fences[i]);
   1206             }
   1207         }
   1208     }
   1209     catch (...)
   1210     {
   1211         return gl::error(GL_OUT_OF_MEMORY);
   1212     }
   1213 }
   1214 
   1215 void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
   1216 {
   1217     EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
   1218 
   1219     try
   1220     {
   1221         if (n < 0)
   1222         {
   1223             return gl::error(GL_INVALID_VALUE);
   1224         }
   1225 
   1226         gl::Context *context = gl::getNonLostContext();
   1227 
   1228         if (context)
   1229         {
   1230             for (int i = 0; i < n; i++)
   1231             {
   1232                 if (framebuffers[i] != 0)
   1233                 {
   1234                     context->deleteFramebuffer(framebuffers[i]);
   1235                 }
   1236             }
   1237         }
   1238     }
   1239     catch (...)
   1240     {
   1241         return gl::error(GL_OUT_OF_MEMORY);
   1242     }
   1243 }
   1244 
   1245 void __stdcall glDeleteProgram(GLuint program)
   1246 {
   1247     EVENT("(GLuint program = %d)", program);
   1248 
   1249     try
   1250     {
   1251         if (program == 0)
   1252         {
   1253             return;
   1254         }
   1255 
   1256         gl::Context *context = gl::getNonLostContext();
   1257 
   1258         if (context)
   1259         {
   1260             if (!context->getProgram(program))
   1261             {
   1262                 if(context->getShader(program))
   1263                 {
   1264                     return gl::error(GL_INVALID_OPERATION);
   1265                 }
   1266                 else
   1267                 {
   1268                     return gl::error(GL_INVALID_VALUE);
   1269                 }
   1270             }
   1271 
   1272             context->deleteProgram(program);
   1273         }
   1274     }
   1275     catch (...)
   1276     {
   1277         return gl::error(GL_OUT_OF_MEMORY);
   1278     }
   1279 }
   1280 
   1281 void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
   1282 {
   1283     EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
   1284 
   1285     try
   1286     {
   1287         if (n < 0)
   1288         {
   1289             return gl::error(GL_INVALID_VALUE);
   1290         }
   1291 
   1292         gl::Context *context = gl::getNonLostContext();
   1293 
   1294         if (context)
   1295         {
   1296             for (int i = 0; i < n; i++)
   1297             {
   1298                 context->deleteQuery(ids[i]);
   1299             }
   1300         }
   1301     }
   1302     catch (...)
   1303     {
   1304         return gl::error(GL_OUT_OF_MEMORY);
   1305     }
   1306 }
   1307 
   1308 void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
   1309 {
   1310     EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
   1311 
   1312     try
   1313     {
   1314         if (n < 0)
   1315         {
   1316             return gl::error(GL_INVALID_VALUE);
   1317         }
   1318 
   1319         gl::Context *context = gl::getNonLostContext();
   1320 
   1321         if (context)
   1322         {
   1323             for (int i = 0; i < n; i++)
   1324             {
   1325                 context->deleteRenderbuffer(renderbuffers[i]);
   1326             }
   1327         }
   1328     }
   1329     catch (...)
   1330     {
   1331         return gl::error(GL_OUT_OF_MEMORY);
   1332     }
   1333 }
   1334 
   1335 void __stdcall glDeleteShader(GLuint shader)
   1336 {
   1337     EVENT("(GLuint shader = %d)", shader);
   1338 
   1339     try
   1340     {
   1341         if (shader == 0)
   1342         {
   1343             return;
   1344         }
   1345 
   1346         gl::Context *context = gl::getNonLostContext();
   1347 
   1348         if (context)
   1349         {
   1350             if (!context->getShader(shader))
   1351             {
   1352                 if(context->getProgram(shader))
   1353                 {
   1354                     return gl::error(GL_INVALID_OPERATION);
   1355                 }
   1356                 else
   1357                 {
   1358                     return gl::error(GL_INVALID_VALUE);
   1359                 }
   1360             }
   1361 
   1362             context->deleteShader(shader);
   1363         }
   1364     }
   1365     catch (...)
   1366     {
   1367         return gl::error(GL_OUT_OF_MEMORY);
   1368     }
   1369 }
   1370 
   1371 void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
   1372 {
   1373     EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
   1374 
   1375     try
   1376     {
   1377         if (n < 0)
   1378         {
   1379             return gl::error(GL_INVALID_VALUE);
   1380         }
   1381 
   1382         gl::Context *context = gl::getNonLostContext();
   1383 
   1384         if (context)
   1385         {
   1386             for (int i = 0; i < n; i++)
   1387             {
   1388                 if (textures[i] != 0)
   1389                 {
   1390                     context->deleteTexture(textures[i]);
   1391                 }
   1392             }
   1393         }
   1394     }
   1395     catch (...)
   1396     {
   1397         return gl::error(GL_OUT_OF_MEMORY);
   1398     }
   1399 }
   1400 
   1401 void __stdcall glDepthFunc(GLenum func)
   1402 {
   1403     EVENT("(GLenum func = 0x%X)", func);
   1404 
   1405     try
   1406     {
   1407         switch (func)
   1408         {
   1409           case GL_NEVER:
   1410           case GL_ALWAYS:
   1411           case GL_LESS:
   1412           case GL_LEQUAL:
   1413           case GL_EQUAL:
   1414           case GL_GREATER:
   1415           case GL_GEQUAL:
   1416           case GL_NOTEQUAL:
   1417             break;
   1418           default:
   1419             return gl::error(GL_INVALID_ENUM);
   1420         }
   1421 
   1422         gl::Context *context = gl::getNonLostContext();
   1423 
   1424         if (context)
   1425         {
   1426             context->setDepthFunc(func);
   1427         }
   1428     }
   1429     catch (...)
   1430     {
   1431         return gl::error(GL_OUT_OF_MEMORY);
   1432     }
   1433 }
   1434 
   1435 void __stdcall glDepthMask(GLboolean flag)
   1436 {
   1437     EVENT("(GLboolean flag = %u)", flag);
   1438 
   1439     try
   1440     {
   1441         gl::Context *context = gl::getNonLostContext();
   1442 
   1443         if (context)
   1444         {
   1445             context->setDepthMask(flag != GL_FALSE);
   1446         }
   1447     }
   1448     catch (...)
   1449     {
   1450         return gl::error(GL_OUT_OF_MEMORY);
   1451     }
   1452 }
   1453 
   1454 void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
   1455 {
   1456     EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
   1457 
   1458     try
   1459     {
   1460         gl::Context *context = gl::getNonLostContext();
   1461 
   1462         if (context)
   1463         {
   1464             context->setDepthRange(zNear, zFar);
   1465         }
   1466     }
   1467     catch (...)
   1468     {
   1469         return gl::error(GL_OUT_OF_MEMORY);
   1470     }
   1471 }
   1472 
   1473 void __stdcall glDetachShader(GLuint program, GLuint shader)
   1474 {
   1475     EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
   1476 
   1477     try
   1478     {
   1479         gl::Context *context = gl::getNonLostContext();
   1480 
   1481         if (context)
   1482         {
   1483 
   1484             gl::Program *programObject = context->getProgram(program);
   1485             gl::Shader *shaderObject = context->getShader(shader);
   1486 
   1487             if (!programObject)
   1488             {
   1489                 gl::Shader *shaderByProgramHandle;
   1490                 shaderByProgramHandle = context->getShader(program);
   1491                 if (!shaderByProgramHandle)
   1492                 {
   1493                     return gl::error(GL_INVALID_VALUE);
   1494                 }
   1495                 else
   1496                 {
   1497                     return gl::error(GL_INVALID_OPERATION);
   1498                 }
   1499             }
   1500 
   1501             if (!shaderObject)
   1502             {
   1503                 gl::Program *programByShaderHandle = context->getProgram(shader);
   1504                 if (!programByShaderHandle)
   1505                 {
   1506                     return gl::error(GL_INVALID_VALUE);
   1507                 }
   1508                 else
   1509                 {
   1510                     return gl::error(GL_INVALID_OPERATION);
   1511                 }
   1512             }
   1513 
   1514             if (!programObject->detachShader(shaderObject))
   1515             {
   1516                 return gl::error(GL_INVALID_OPERATION);
   1517             }
   1518         }
   1519     }
   1520     catch (...)
   1521     {
   1522         return gl::error(GL_OUT_OF_MEMORY);
   1523     }
   1524 }
   1525 
   1526 void __stdcall glDisable(GLenum cap)
   1527 {
   1528     EVENT("(GLenum cap = 0x%X)", cap);
   1529 
   1530     try
   1531     {
   1532         gl::Context *context = gl::getNonLostContext();
   1533 
   1534         if (context)
   1535         {
   1536             if (!ValidCap(context, cap))
   1537             {
   1538                 return gl::error(GL_INVALID_ENUM);
   1539             }
   1540 
   1541             context->setCap(cap, false);
   1542         }
   1543     }
   1544     catch (...)
   1545     {
   1546         return gl::error(GL_OUT_OF_MEMORY);
   1547     }
   1548 }
   1549 
   1550 void __stdcall glDisableVertexAttribArray(GLuint index)
   1551 {
   1552     EVENT("(GLuint index = %d)", index);
   1553 
   1554     try
   1555     {
   1556         if (index >= gl::MAX_VERTEX_ATTRIBS)
   1557         {
   1558             return gl::error(GL_INVALID_VALUE);
   1559         }
   1560 
   1561         gl::Context *context = gl::getNonLostContext();
   1562 
   1563         if (context)
   1564         {
   1565             context->setEnableVertexAttribArray(index, false);
   1566         }
   1567     }
   1568     catch (...)
   1569     {
   1570         return gl::error(GL_OUT_OF_MEMORY);
   1571     }
   1572 }
   1573 
   1574 void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
   1575 {
   1576     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
   1577 
   1578     try
   1579     {
   1580         if (count < 0 || first < 0)
   1581         {
   1582             return gl::error(GL_INVALID_VALUE);
   1583         }
   1584 
   1585         gl::Context *context = gl::getNonLostContext();
   1586 
   1587         // Check for mapped buffers
   1588         if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
   1589         {
   1590             return gl::error(GL_INVALID_OPERATION);
   1591         }
   1592 
   1593         if (context)
   1594         {
   1595             gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
   1596             if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
   1597                 curTransformFeedback->getDrawMode() != mode)
   1598             {
   1599                 // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
   1600                 // that does not match the current transform feedback object's draw mode (if transform feedback
   1601                 // is active), (3.0.2, section 2.14, pg 86)
   1602                 return gl::error(GL_INVALID_OPERATION);
   1603             }
   1604 
   1605             context->drawArrays(mode, first, count, 0);
   1606         }
   1607     }
   1608     catch (...)
   1609     {
   1610         return gl::error(GL_OUT_OF_MEMORY);
   1611     }
   1612 }
   1613 
   1614 void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
   1615 {
   1616     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
   1617 
   1618     try
   1619     {
   1620         if (count < 0 || first < 0 || primcount < 0)
   1621         {
   1622             return gl::error(GL_INVALID_VALUE);
   1623         }
   1624 
   1625         if (primcount > 0)
   1626         {
   1627             gl::Context *context = gl::getNonLostContext();
   1628 
   1629             // Check for mapped buffers
   1630             if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
   1631             {
   1632                 return gl::error(GL_INVALID_OPERATION);
   1633             }
   1634 
   1635             if (context)
   1636             {
   1637                 gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
   1638                 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
   1639                     curTransformFeedback->getDrawMode() != mode)
   1640                 {
   1641                     // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
   1642                     // that does not match the current transform feedback object's draw mode (if transform feedback
   1643                     // is active), (3.0.2, section 2.14, pg 86)
   1644                     return gl::error(GL_INVALID_OPERATION);
   1645                 }
   1646 
   1647                 context->drawArrays(mode, first, count, primcount);
   1648             }
   1649         }
   1650     }
   1651     catch (...)
   1652     {
   1653         return gl::error(GL_OUT_OF_MEMORY);
   1654     }
   1655 }
   1656 
   1657 void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
   1658 {
   1659     EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
   1660           mode, count, type, indices);
   1661 
   1662     try
   1663     {
   1664         if (count < 0)
   1665         {
   1666             return gl::error(GL_INVALID_VALUE);
   1667         }
   1668 
   1669         gl::Context *context = gl::getNonLostContext();
   1670 
   1671         if (context)
   1672         {
   1673             switch (type)
   1674             {
   1675               case GL_UNSIGNED_BYTE:
   1676               case GL_UNSIGNED_SHORT:
   1677                 break;
   1678               case GL_UNSIGNED_INT:
   1679                 if (!context->supports32bitIndices())
   1680                 {
   1681                     return gl::error(GL_INVALID_ENUM);
   1682                 }
   1683                 break;
   1684               default:
   1685                 return gl::error(GL_INVALID_ENUM);
   1686             }
   1687 
   1688             gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
   1689             if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
   1690             {
   1691                 // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
   1692                 // while transform feedback is active, (3.0.2, section 2.14, pg 86)
   1693                 return gl::error(GL_INVALID_OPERATION);
   1694             }
   1695 
   1696             // Check for mapped buffers
   1697             if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
   1698             {
   1699                 return gl::error(GL_INVALID_OPERATION);
   1700             }
   1701 
   1702             context->drawElements(mode, count, type, indices, 0);
   1703         }
   1704     }
   1705     catch (...)
   1706     {
   1707         return gl::error(GL_OUT_OF_MEMORY);
   1708     }
   1709 }
   1710 
   1711 void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
   1712 {
   1713     EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
   1714           mode, count, type, indices, primcount);
   1715 
   1716     try
   1717     {
   1718         if (count < 0 || primcount < 0)
   1719         {
   1720             return gl::error(GL_INVALID_VALUE);
   1721         }
   1722 
   1723         if (primcount > 0)
   1724         {
   1725             gl::Context *context = gl::getNonLostContext();
   1726 
   1727             if (context)
   1728             {
   1729                 switch (type)
   1730                 {
   1731                   case GL_UNSIGNED_BYTE:
   1732                   case GL_UNSIGNED_SHORT:
   1733                     break;
   1734                   case GL_UNSIGNED_INT:
   1735                     if (!context->supports32bitIndices())
   1736                     {
   1737                         return gl::error(GL_INVALID_ENUM);
   1738                     }
   1739                     break;
   1740                   default:
   1741                     return gl::error(GL_INVALID_ENUM);
   1742                 }
   1743 
   1744                 gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
   1745                 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
   1746                 {
   1747                     // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
   1748                     // while transform feedback is active, (3.0.2, section 2.14, pg 86)
   1749                     return gl::error(GL_INVALID_OPERATION);
   1750                 }
   1751 
   1752                 // Check for mapped buffers
   1753                 if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
   1754                 {
   1755                     return gl::error(GL_INVALID_OPERATION);
   1756                 }
   1757 
   1758                 context->drawElements(mode, count, type, indices, primcount);
   1759             }
   1760         }
   1761     }
   1762     catch (...)
   1763     {
   1764         return gl::error(GL_OUT_OF_MEMORY);
   1765     }
   1766 }
   1767 
   1768 void __stdcall glEnable(GLenum cap)
   1769 {
   1770     EVENT("(GLenum cap = 0x%X)", cap);
   1771 
   1772     try
   1773     {
   1774         gl::Context *context = gl::getNonLostContext();
   1775 
   1776         if (context)
   1777         {
   1778             if (!ValidCap(context, cap))
   1779             {
   1780                 return gl::error(GL_INVALID_ENUM);
   1781             }
   1782 
   1783             context->setCap(cap, true);
   1784         }
   1785     }
   1786     catch (...)
   1787     {
   1788         return gl::error(GL_OUT_OF_MEMORY);
   1789     }
   1790 }
   1791 
   1792 void __stdcall glEnableVertexAttribArray(GLuint index)
   1793 {
   1794     EVENT("(GLuint index = %d)", index);
   1795 
   1796     try
   1797     {
   1798         if (index >= gl::MAX_VERTEX_ATTRIBS)
   1799         {
   1800             return gl::error(GL_INVALID_VALUE);
   1801         }
   1802 
   1803         gl::Context *context = gl::getNonLostContext();
   1804 
   1805         if (context)
   1806         {
   1807             context->setEnableVertexAttribArray(index, true);
   1808         }
   1809     }
   1810     catch (...)
   1811     {
   1812         return gl::error(GL_OUT_OF_MEMORY);
   1813     }
   1814 }
   1815 
   1816 void __stdcall glEndQueryEXT(GLenum target)
   1817 {
   1818     EVENT("GLenum target = 0x%X)", target);
   1819 
   1820     try
   1821     {
   1822         gl::Context *context = gl::getNonLostContext();
   1823 
   1824         if (context)
   1825         {
   1826             if (!ValidateEndQuery(context, target))
   1827             {
   1828                 return;
   1829             }
   1830 
   1831             context->endQuery(target);
   1832         }
   1833     }
   1834     catch (...)
   1835     {
   1836         return gl::error(GL_OUT_OF_MEMORY);
   1837     }
   1838 }
   1839 
   1840 void __stdcall glFinishFenceNV(GLuint fence)
   1841 {
   1842     EVENT("(GLuint fence = %d)", fence);
   1843 
   1844     try
   1845     {
   1846         gl::Context *context = gl::getNonLostContext();
   1847 
   1848         if (context)
   1849         {
   1850             gl::FenceNV *fenceObject = context->getFenceNV(fence);
   1851 
   1852             if (fenceObject == NULL)
   1853             {
   1854                 return gl::error(GL_INVALID_OPERATION);
   1855             }
   1856 
   1857             if (fenceObject->isFence() != GL_TRUE)
   1858             {
   1859                 return gl::error(GL_INVALID_OPERATION);
   1860             }
   1861 
   1862             fenceObject->finishFence();
   1863         }
   1864     }
   1865     catch (...)
   1866     {
   1867         return gl::error(GL_OUT_OF_MEMORY);
   1868     }
   1869 }
   1870 
   1871 void __stdcall glFinish(void)
   1872 {
   1873     EVENT("()");
   1874 
   1875     try
   1876     {
   1877         gl::Context *context = gl::getNonLostContext();
   1878 
   1879         if (context)
   1880         {
   1881             context->sync(true);
   1882         }
   1883     }
   1884     catch (...)
   1885     {
   1886         return gl::error(GL_OUT_OF_MEMORY);
   1887     }
   1888 }
   1889 
   1890 void __stdcall glFlush(void)
   1891 {
   1892     EVENT("()");
   1893 
   1894     try
   1895     {
   1896         gl::Context *context = gl::getNonLostContext();
   1897 
   1898         if (context)
   1899         {
   1900             context->sync(false);
   1901         }
   1902     }
   1903     catch (...)
   1904     {
   1905         return gl::error(GL_OUT_OF_MEMORY);
   1906     }
   1907 }
   1908 
   1909 void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
   1910 {
   1911     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
   1912           "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
   1913 
   1914     try
   1915     {
   1916         if (!gl::ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
   1917         {
   1918             return gl::error(GL_INVALID_ENUM);
   1919         }
   1920 
   1921         gl::Context *context = gl::getNonLostContext();
   1922 
   1923         if (context)
   1924         {
   1925             if (!gl::ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer))
   1926             {
   1927                 return;
   1928             }
   1929 
   1930             gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
   1931             ASSERT(framebuffer);
   1932 
   1933             if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
   1934             {
   1935                 unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
   1936                 framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer, 0, 0);
   1937             }
   1938             else
   1939             {
   1940                 switch (attachment)
   1941                 {
   1942                   case GL_DEPTH_ATTACHMENT:
   1943                     framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
   1944                     break;
   1945                   case GL_STENCIL_ATTACHMENT:
   1946                     framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
   1947                     break;
   1948                   case GL_DEPTH_STENCIL_ATTACHMENT:
   1949                     framebuffer->setDepthStencilBuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
   1950                     break;
   1951                   default:
   1952                     UNREACHABLE();
   1953                     break;
   1954                 }
   1955             }
   1956         }
   1957     }
   1958     catch (...)
   1959     {
   1960         return gl::error(GL_OUT_OF_MEMORY);
   1961     }
   1962 }
   1963 
   1964 void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
   1965 {
   1966     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
   1967           "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
   1968 
   1969     try
   1970     {
   1971         gl::Context *context = gl::getNonLostContext();
   1972         if (context)
   1973         {
   1974             if (context->getClientVersion() < 3 &&
   1975                 !ValidateES2FramebufferTextureParameters(context, target, attachment, textarget, texture, level))
   1976             {
   1977                 return;
   1978             }
   1979 
   1980             if (context->getClientVersion() >= 3 &&
   1981                 !ValidateES3FramebufferTextureParameters(context, target, attachment, textarget, texture, level, 0, false))
   1982             {
   1983                 return;
   1984             }
   1985 
   1986             if (texture == 0)
   1987             {
   1988                 textarget = GL_NONE;
   1989             }
   1990 
   1991             gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
   1992 
   1993             if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
   1994             {
   1995                 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
   1996                 framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, 0);
   1997             }
   1998             else
   1999             {
   2000                 switch (attachment)
   2001                 {
   2002                   case GL_DEPTH_ATTACHMENT:         framebuffer->setDepthbuffer(textarget, texture, level, 0);        break;
   2003                   case GL_STENCIL_ATTACHMENT:       framebuffer->setStencilbuffer(textarget, texture, level, 0);      break;
   2004                   case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, 0); break;
   2005                 }
   2006             }
   2007         }
   2008     }
   2009     catch (...)
   2010     {
   2011         return gl::error(GL_OUT_OF_MEMORY);
   2012     }
   2013 }
   2014 
   2015 void __stdcall glFrontFace(GLenum mode)
   2016 {
   2017     EVENT("(GLenum mode = 0x%X)", mode);
   2018 
   2019     try
   2020     {
   2021         switch (mode)
   2022         {
   2023           case GL_CW:
   2024           case GL_CCW:
   2025             {
   2026                 gl::Context *context = gl::getNonLostContext();
   2027 
   2028                 if (context)
   2029                 {
   2030                     context->setFrontFace(mode);
   2031                 }
   2032             }
   2033             break;
   2034           default:
   2035             return gl::error(GL_INVALID_ENUM);
   2036         }
   2037     }
   2038     catch (...)
   2039     {
   2040         return gl::error(GL_OUT_OF_MEMORY);
   2041     }
   2042 }
   2043 
   2044 void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
   2045 {
   2046     EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
   2047 
   2048     try
   2049     {
   2050         if (n < 0)
   2051         {
   2052             return gl::error(GL_INVALID_VALUE);
   2053         }
   2054 
   2055         gl::Context *context = gl::getNonLostContext();
   2056 
   2057         if (context)
   2058         {
   2059             for (int i = 0; i < n; i++)
   2060             {
   2061                 buffers[i] = context->createBuffer();
   2062             }
   2063         }
   2064     }
   2065     catch (...)
   2066     {
   2067         return gl::error(GL_OUT_OF_MEMORY);
   2068     }
   2069 }
   2070 
   2071 void __stdcall glGenerateMipmap(GLenum target)
   2072 {
   2073     EVENT("(GLenum target = 0x%X)", target);
   2074 
   2075     try
   2076     {
   2077         gl::Context *context = gl::getNonLostContext();
   2078 
   2079         if (context)
   2080         {
   2081             if (!ValidTextureTarget(context, target))
   2082             {
   2083                 return gl::error(GL_INVALID_ENUM);
   2084             }
   2085 
   2086             gl::Texture *texture = context->getTargetTexture(target);
   2087 
   2088             if (texture == NULL)
   2089             {
   2090                 return gl::error(GL_INVALID_OPERATION);
   2091             }
   2092 
   2093             GLenum internalFormat = texture->getBaseLevelInternalFormat();
   2094 
   2095             // Internally, all texture formats are sized so checking if the format
   2096             // is color renderable and filterable will not fail.
   2097 
   2098             bool validRenderable = (gl::IsColorRenderingSupported(internalFormat, context) ||
   2099                                     gl::IsSizedInternalFormat(internalFormat, context->getClientVersion()));
   2100 
   2101             if (gl::IsDepthRenderingSupported(internalFormat, context) ||
   2102                 gl::IsFormatCompressed(internalFormat, context->getClientVersion()) ||
   2103                 !gl::IsTextureFilteringSupported(internalFormat, context) ||
   2104                 !validRenderable)
   2105             {
   2106                 return gl::error(GL_INVALID_OPERATION);
   2107             }
   2108 
   2109             // Non-power of 2 ES2 check
   2110             if (!context->supportsNonPower2Texture() && (!gl::isPow2(texture->getBaseLevelWidth()) || !gl::isPow2(texture->getBaseLevelHeight())))
   2111             {
   2112                 ASSERT(context->getClientVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP));
   2113                 return gl::error(GL_INVALID_OPERATION);
   2114             }
   2115 
   2116             // Cube completeness check
   2117             if (target == GL_TEXTURE_CUBE_MAP)
   2118             {
   2119                 gl::TextureCubeMap *textureCube = static_cast<gl::TextureCubeMap *>(texture);
   2120                 if (!textureCube->isCubeComplete())
   2121                 {
   2122                     return gl::error(GL_INVALID_OPERATION);
   2123                 }
   2124             }
   2125 
   2126             texture->generateMipmaps();
   2127         }
   2128     }
   2129     catch (...)
   2130     {
   2131         return gl::error(GL_OUT_OF_MEMORY);
   2132     }
   2133 }
   2134 
   2135 void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
   2136 {
   2137     EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
   2138 
   2139     try
   2140     {
   2141         if (n < 0)
   2142         {
   2143             return gl::error(GL_INVALID_VALUE);
   2144         }
   2145 
   2146         gl::Context *context = gl::getNonLostContext();
   2147 
   2148         if (context)
   2149         {
   2150             for (int i = 0; i < n; i++)
   2151             {
   2152                 fences[i] = context->createFenceNV();
   2153             }
   2154         }
   2155     }
   2156     catch (...)
   2157     {
   2158         return gl::error(GL_OUT_OF_MEMORY);
   2159     }
   2160 }
   2161 
   2162 void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
   2163 {
   2164     EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
   2165 
   2166     try
   2167     {
   2168         if (n < 0)
   2169         {
   2170             return gl::error(GL_INVALID_VALUE);
   2171         }
   2172 
   2173         gl::Context *context = gl::getNonLostContext();
   2174 
   2175         if (context)
   2176         {
   2177             for (int i = 0; i < n; i++)
   2178             {
   2179                 framebuffers[i] = context->createFramebuffer();
   2180             }
   2181         }
   2182     }
   2183     catch (...)
   2184     {
   2185         return gl::error(GL_OUT_OF_MEMORY);
   2186     }
   2187 }
   2188 
   2189 void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
   2190 {
   2191     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
   2192 
   2193     try
   2194     {
   2195         gl::Context *context = gl::getNonLostContext();
   2196 
   2197         if (context)
   2198         {
   2199             if (n < 0)
   2200             {
   2201                 return gl::error(GL_INVALID_VALUE);
   2202             }
   2203 
   2204             for (GLsizei i = 0; i < n; i++)
   2205             {
   2206                 ids[i] = context->createQuery();
   2207             }
   2208         }
   2209     }
   2210     catch (...)
   2211     {
   2212         return gl::error(GL_OUT_OF_MEMORY);
   2213     }
   2214 }
   2215 
   2216 void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
   2217 {
   2218     EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
   2219 
   2220     try
   2221     {
   2222         if (n < 0)
   2223         {
   2224             return gl::error(GL_INVALID_VALUE);
   2225         }
   2226 
   2227         gl::Context *context = gl::getNonLostContext();
   2228 
   2229         if (context)
   2230         {
   2231             for (int i = 0; i < n; i++)
   2232             {
   2233                 renderbuffers[i] = context->createRenderbuffer();
   2234             }
   2235         }
   2236     }
   2237     catch (...)
   2238     {
   2239         return gl::error(GL_OUT_OF_MEMORY);
   2240     }
   2241 }
   2242 
   2243 void __stdcall glGenTextures(GLsizei n, GLuint* textures)
   2244 {
   2245     EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
   2246 
   2247     try
   2248     {
   2249         if (n < 0)
   2250         {
   2251             return gl::error(GL_INVALID_VALUE);
   2252         }
   2253 
   2254         gl::Context *context = gl::getNonLostContext();
   2255 
   2256         if (context)
   2257         {
   2258             for (int i = 0; i < n; i++)
   2259             {
   2260                 textures[i] = context->createTexture();
   2261             }
   2262         }
   2263     }
   2264     catch (...)
   2265     {
   2266         return gl::error(GL_OUT_OF_MEMORY);
   2267     }
   2268 }
   2269 
   2270 void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
   2271 {
   2272     EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
   2273           "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
   2274           program, index, bufsize, length, size, type, name);
   2275 
   2276     try
   2277     {
   2278         if (bufsize < 0)
   2279         {
   2280             return gl::error(GL_INVALID_VALUE);
   2281         }
   2282 
   2283         gl::Context *context = gl::getNonLostContext();
   2284 
   2285         if (context)
   2286         {
   2287             gl::Program *programObject = context->getProgram(program);
   2288 
   2289             if (!programObject)
   2290             {
   2291                 if (context->getShader(program))
   2292                 {
   2293                     return gl::error(GL_INVALID_OPERATION);
   2294                 }
   2295                 else
   2296                 {
   2297                     return gl::error(GL_INVALID_VALUE);
   2298                 }
   2299             }
   2300 
   2301             if (index >= (GLuint)programObject->getActiveAttributeCount())
   2302             {
   2303                 return gl::error(GL_INVALID_VALUE);
   2304             }
   2305 
   2306             programObject->getActiveAttribute(index, bufsize, length, size, type, name);
   2307         }
   2308     }
   2309     catch (...)
   2310     {
   2311         return gl::error(GL_OUT_OF_MEMORY);
   2312     }
   2313 }
   2314 
   2315 void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
   2316 {
   2317     EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
   2318           "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
   2319           program, index, bufsize, length, size, type, name);
   2320 
   2321     try
   2322     {
   2323         if (bufsize < 0)
   2324         {
   2325             return gl::error(GL_INVALID_VALUE);
   2326         }
   2327 
   2328         gl::Context *context = gl::getNonLostContext();
   2329 
   2330         if (context)
   2331         {
   2332             gl::Program *programObject = context->getProgram(program);
   2333 
   2334             if (!programObject)
   2335             {
   2336                 if (context->getShader(program))
   2337                 {
   2338                     return gl::error(GL_INVALID_OPERATION);
   2339                 }
   2340                 else
   2341                 {
   2342                     return gl::error(GL_INVALID_VALUE);
   2343                 }
   2344             }
   2345 
   2346             if (index >= (GLuint)programObject->getActiveUniformCount())
   2347             {
   2348                 return gl::error(GL_INVALID_VALUE);
   2349             }
   2350 
   2351             programObject->getActiveUniform(index, bufsize, length, size, type, name);
   2352         }
   2353     }
   2354     catch (...)
   2355     {
   2356         return gl::error(GL_OUT_OF_MEMORY);
   2357     }
   2358 }
   2359 
   2360 void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
   2361 {
   2362     EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
   2363           program, maxcount, count, shaders);
   2364 
   2365     try
   2366     {
   2367         if (maxcount < 0)
   2368         {
   2369             return gl::error(GL_INVALID_VALUE);
   2370         }
   2371 
   2372         gl::Context *context = gl::getNonLostContext();
   2373 
   2374         if (context)
   2375         {
   2376             gl::Program *programObject = context->getProgram(program);
   2377 
   2378             if (!programObject)
   2379             {
   2380                 if (context->getShader(program))
   2381                 {
   2382                     return gl::error(GL_INVALID_OPERATION);
   2383                 }
   2384                 else
   2385                 {
   2386                     return gl::error(GL_INVALID_VALUE);
   2387                 }
   2388             }
   2389 
   2390             return programObject->getAttachedShaders(maxcount, count, shaders);
   2391         }
   2392     }
   2393     catch (...)
   2394     {
   2395         return gl::error(GL_OUT_OF_MEMORY);
   2396     }
   2397 }
   2398 
   2399 int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
   2400 {
   2401     EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
   2402 
   2403     try
   2404     {
   2405         gl::Context *context = gl::getNonLostContext();
   2406 
   2407         if (context)
   2408         {
   2409 
   2410             gl::Program *programObject = context->getProgram(program);
   2411 
   2412             if (!programObject)
   2413             {
   2414                 if (context->getShader(program))
   2415                 {
   2416                     return gl::error(GL_INVALID_OPERATION, -1);
   2417                 }
   2418                 else
   2419                 {
   2420                     return gl::error(GL_INVALID_VALUE, -1);
   2421                 }
   2422             }
   2423 
   2424             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   2425             if (!programObject->isLinked() || !programBinary)
   2426             {
   2427                 return gl::error(GL_INVALID_OPERATION, -1);
   2428             }
   2429 
   2430             return programBinary->getAttributeLocation(name);
   2431         }
   2432     }
   2433     catch (...)
   2434     {
   2435         return gl::error(GL_OUT_OF_MEMORY, -1);
   2436     }
   2437 
   2438     return -1;
   2439 }
   2440 
   2441 void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
   2442 {
   2443     EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)",  pname, params);
   2444 
   2445     try
   2446     {
   2447         gl::Context *context = gl::getNonLostContext();
   2448 
   2449         if (context)
   2450         {
   2451             GLenum nativeType;
   2452             unsigned int numParams = 0;
   2453             if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
   2454             {
   2455                 return;
   2456             }
   2457 
   2458             if (nativeType == GL_BOOL)
   2459             {
   2460                 context->getBooleanv(pname, params);
   2461             }
   2462             else
   2463             {
   2464                 CastStateValues(context, nativeType, pname, numParams, params);
   2465             }
   2466         }
   2467     }
   2468     catch (...)
   2469     {
   2470         return gl::error(GL_OUT_OF_MEMORY);
   2471     }
   2472 }
   2473 
   2474 void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
   2475 {
   2476     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
   2477 
   2478     try
   2479     {
   2480         gl::Context *context = gl::getNonLostContext();
   2481 
   2482         if (context)
   2483         {
   2484             if (!gl::ValidBufferTarget(context, target))
   2485             {
   2486                 return gl::error(GL_INVALID_ENUM);
   2487             }
   2488 
   2489             if (!gl::ValidBufferParameter(context, pname))
   2490             {
   2491                 return gl::error(GL_INVALID_ENUM);
   2492             }
   2493 
   2494             gl::Buffer *buffer = context->getTargetBuffer(target);
   2495 
   2496             if (!buffer)
   2497             {
   2498                 // A null buffer means that "0" is bound to the requested buffer target
   2499                 return gl::error(GL_INVALID_OPERATION);
   2500             }
   2501 
   2502             switch (pname)
   2503             {
   2504               case GL_BUFFER_USAGE:
   2505                 *params = static_cast<GLint>(buffer->usage());
   2506                 break;
   2507               case GL_BUFFER_SIZE:
   2508                 *params = gl::clampCast<GLint>(buffer->size());
   2509                 break;
   2510               case GL_BUFFER_ACCESS_FLAGS:
   2511                 *params = buffer->accessFlags();
   2512                 break;
   2513               case GL_BUFFER_MAPPED:
   2514                 *params = static_cast<GLint>(buffer->mapped());
   2515                 break;
   2516               case GL_BUFFER_MAP_OFFSET:
   2517                 *params = gl::clampCast<GLint>(buffer->mapOffset());
   2518                 break;
   2519               case GL_BUFFER_MAP_LENGTH:
   2520                 *params = gl::clampCast<GLint>(buffer->mapLength());
   2521                 break;
   2522               default: UNREACHABLE(); break;
   2523             }
   2524         }
   2525     }
   2526     catch (...)
   2527     {
   2528         return gl::error(GL_OUT_OF_MEMORY);
   2529     }
   2530 }
   2531 
   2532 GLenum __stdcall glGetError(void)
   2533 {
   2534     EVENT("()");
   2535 
   2536     gl::Context *context = gl::getContext();
   2537 
   2538     if (context)
   2539     {
   2540         return context->getError();
   2541     }
   2542 
   2543     return GL_NO_ERROR;
   2544 }
   2545 
   2546 void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
   2547 {
   2548     EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
   2549 
   2550     try
   2551     {
   2552 
   2553         gl::Context *context = gl::getNonLostContext();
   2554 
   2555         if (context)
   2556         {
   2557             gl::FenceNV *fenceObject = context->getFenceNV(fence);
   2558 
   2559             if (fenceObject == NULL)
   2560             {
   2561                 return gl::error(GL_INVALID_OPERATION);
   2562             }
   2563 
   2564             if (fenceObject->isFence() != GL_TRUE)
   2565             {
   2566                 return gl::error(GL_INVALID_OPERATION);
   2567             }
   2568 
   2569             switch (pname)
   2570             {
   2571               case GL_FENCE_STATUS_NV:
   2572               case GL_FENCE_CONDITION_NV:
   2573                 break;
   2574 
   2575               default: return gl::error(GL_INVALID_ENUM);
   2576             }
   2577 
   2578             params[0] = fenceObject->getFencei(pname);
   2579         }
   2580     }
   2581     catch (...)
   2582     {
   2583         return gl::error(GL_OUT_OF_MEMORY);
   2584     }
   2585 }
   2586 
   2587 void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
   2588 {
   2589     EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
   2590 
   2591     try
   2592     {
   2593         gl::Context *context = gl::getNonLostContext();
   2594 
   2595         if (context)
   2596         {
   2597             GLenum nativeType;
   2598             unsigned int numParams = 0;
   2599             if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
   2600             {
   2601                 return;
   2602             }
   2603 
   2604             if (nativeType == GL_FLOAT)
   2605             {
   2606                 context->getFloatv(pname, params);
   2607             }
   2608             else
   2609             {
   2610                 CastStateValues(context, nativeType, pname, numParams, params);
   2611             }
   2612         }
   2613     }
   2614     catch (...)
   2615     {
   2616         return gl::error(GL_OUT_OF_MEMORY);
   2617     }
   2618 }
   2619 
   2620 void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
   2621 {
   2622     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
   2623           target, attachment, pname, params);
   2624 
   2625     try
   2626     {
   2627         gl::Context *context = gl::getNonLostContext();
   2628 
   2629         if (context)
   2630         {
   2631             if (!gl::ValidFramebufferTarget(target))
   2632             {
   2633                 return gl::error(GL_INVALID_ENUM);
   2634             }
   2635 
   2636             switch (pname)
   2637             {
   2638               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
   2639               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
   2640               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
   2641               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
   2642                 break;
   2643               case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
   2644               case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
   2645               case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
   2646               case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
   2647               case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
   2648               case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
   2649               case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
   2650               case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
   2651               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
   2652                 if (context->getClientVersion() >= 3)
   2653                 {
   2654                     break;
   2655                 }
   2656               default:
   2657                 return gl::error(GL_INVALID_ENUM);
   2658             }
   2659 
   2660             // Determine if the attachment is a valid enum
   2661             switch (attachment)
   2662             {
   2663               case GL_BACK:
   2664               case GL_FRONT:
   2665               case GL_DEPTH:
   2666               case GL_STENCIL:
   2667               case GL_DEPTH_STENCIL_ATTACHMENT:
   2668                 if (context->getClientVersion() < 3)
   2669                 {
   2670                     return gl::error(GL_INVALID_ENUM);
   2671                 }
   2672                 break;
   2673 
   2674               case GL_DEPTH_ATTACHMENT:
   2675               case GL_STENCIL_ATTACHMENT:
   2676                 break;
   2677 
   2678               default:
   2679                 if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
   2680                     (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getMaximumRenderTargets())
   2681                 {
   2682                     return gl::error(GL_INVALID_ENUM);
   2683                 }
   2684                 break;
   2685             }
   2686 
   2687             GLuint framebufferHandle = context->getTargetFramebufferHandle(target);
   2688             ASSERT(framebufferHandle != GL_INVALID_INDEX);
   2689             gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle);
   2690 
   2691             GLenum attachmentType;
   2692             GLuint attachmentHandle;
   2693             GLuint attachmentLevel;
   2694             GLuint attachmentLayer;
   2695             gl::FramebufferAttachment *attachmentObject;
   2696 
   2697             if (framebufferHandle == 0)
   2698             {
   2699                 if (context->getClientVersion() < 3)
   2700                 {
   2701                     return gl::error(GL_INVALID_OPERATION);
   2702                 }
   2703 
   2704                 switch (attachment)
   2705                 {
   2706                   case GL_BACK:
   2707                     attachmentType = framebuffer->getColorbufferType(0);
   2708                     attachmentHandle = framebuffer->getColorbufferHandle(0);
   2709                     attachmentLevel = framebuffer->getColorbufferMipLevel(0);
   2710                     attachmentLayer = framebuffer->getColorbufferLayer(0);
   2711                     attachmentObject = framebuffer->getColorbuffer(0);
   2712                     break;
   2713                   case GL_DEPTH:
   2714                     attachmentType = framebuffer->getDepthbufferType();
   2715                     attachmentHandle = framebuffer->getDepthbufferHandle();
   2716                     attachmentLevel = framebuffer->getDepthbufferMipLevel();
   2717                     attachmentLayer = framebuffer->getDepthbufferLayer();
   2718                     attachmentObject = framebuffer->getDepthbuffer();
   2719                     break;
   2720                   case GL_STENCIL:
   2721                     attachmentType = framebuffer->getStencilbufferType();
   2722                     attachmentHandle = framebuffer->getStencilbufferHandle();
   2723                     attachmentLevel = framebuffer->getStencilbufferMipLevel();
   2724                     attachmentLayer = framebuffer->getStencilbufferLayer();
   2725                     attachmentObject = framebuffer->getStencilbuffer();
   2726                     break;
   2727                   default:
   2728                     return gl::error(GL_INVALID_OPERATION);
   2729                 }
   2730             }
   2731             else
   2732             {
   2733                 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
   2734                 {
   2735                     const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
   2736                     attachmentType = framebuffer->getColorbufferType(colorAttachment);
   2737                     attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment);
   2738                     attachmentLevel = framebuffer->getColorbufferMipLevel(colorAttachment);
   2739                     attachmentLayer = framebuffer->getColorbufferLayer(colorAttachment);
   2740                     attachmentObject = framebuffer->getColorbuffer(colorAttachment);
   2741                 }
   2742                 else
   2743                 {
   2744                     switch (attachment)
   2745                     {
   2746                       case GL_DEPTH_ATTACHMENT:
   2747                         attachmentType = framebuffer->getDepthbufferType();
   2748                         attachmentHandle = framebuffer->getDepthbufferHandle();
   2749                         attachmentLevel = framebuffer->getDepthbufferMipLevel();
   2750                         attachmentLayer = framebuffer->getDepthbufferLayer();
   2751                         attachmentObject = framebuffer->getDepthbuffer();
   2752                         break;
   2753                       case GL_STENCIL_ATTACHMENT:
   2754                         attachmentType = framebuffer->getStencilbufferType();
   2755                         attachmentHandle = framebuffer->getStencilbufferHandle();
   2756                         attachmentLevel = framebuffer->getStencilbufferMipLevel();
   2757                         attachmentLayer = framebuffer->getStencilbufferLayer();
   2758                         attachmentObject = framebuffer->getStencilbuffer();
   2759                         break;
   2760                       case GL_DEPTH_STENCIL_ATTACHMENT:
   2761                         if (framebuffer->getDepthbufferHandle() != framebuffer->getStencilbufferHandle())
   2762                         {
   2763                             return gl::error(GL_INVALID_OPERATION);
   2764                         }
   2765                         attachmentType = framebuffer->getDepthStencilbufferType();
   2766                         attachmentHandle = framebuffer->getDepthStencilbufferHandle();
   2767                         attachmentLevel = framebuffer->getDepthStencilbufferMipLevel();
   2768                         attachmentLayer = framebuffer->getDepthStencilbufferLayer();
   2769                         attachmentObject = framebuffer->getDepthStencilBuffer();
   2770                         break;
   2771                       default:
   2772                         return gl::error(GL_INVALID_OPERATION);
   2773                     }
   2774                 }
   2775             }
   2776 
   2777             GLenum attachmentObjectType;   // Type category
   2778             if (framebufferHandle == 0)
   2779             {
   2780                 attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
   2781             }
   2782             else if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
   2783             {
   2784                 attachmentObjectType = attachmentType;
   2785             }
   2786             else if (gl::IsInternalTextureTarget(attachmentType, context->getClientVersion()))
   2787             {
   2788                 attachmentObjectType = GL_TEXTURE;
   2789             }
   2790             else
   2791             {
   2792                 UNREACHABLE();
   2793                 return;
   2794             }
   2795 
   2796             if (attachmentObjectType == GL_NONE)
   2797             {
   2798                 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
   2799                 // is NONE, then querying any other pname will generate INVALID_ENUM.
   2800 
   2801                 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
   2802                 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
   2803                 // INVALID_OPERATION for all other pnames
   2804 
   2805                 switch (pname)
   2806                 {
   2807                   case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
   2808                     *params = attachmentObjectType;
   2809                     break;
   2810 
   2811                   case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
   2812                     if (context->getClientVersion() < 3)
   2813                     {
   2814                         return gl::error(GL_INVALID_ENUM);
   2815                     }
   2816                     *params = 0;
   2817                     break;
   2818 
   2819                   default:
   2820                     if (context->getClientVersion() < 3)
   2821                     {
   2822                         return gl::error(GL_INVALID_ENUM);
   2823                     }
   2824                     else
   2825                     {
   2826                         gl::error(GL_INVALID_OPERATION);
   2827                     }
   2828                 }
   2829             }
   2830             else
   2831             {
   2832                 ASSERT(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE ||
   2833                        attachmentObjectType == GL_FRAMEBUFFER_DEFAULT);
   2834                 ASSERT(attachmentObject != NULL);
   2835 
   2836                 switch (pname)
   2837                 {
   2838                   case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
   2839                     *params = attachmentObjectType;
   2840                     break;
   2841 
   2842                   case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
   2843                     if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE)
   2844                     {
   2845                         return gl::error(GL_INVALID_ENUM);
   2846                     }
   2847                     *params = attachmentHandle;
   2848                     break;
   2849 
   2850                   case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
   2851                     if (attachmentObjectType != GL_TEXTURE)
   2852                     {
   2853                         return gl::error(GL_INVALID_ENUM);
   2854                     }
   2855                     *params = attachmentLevel;
   2856                     break;
   2857 
   2858                   case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
   2859                     if (attachmentObjectType != GL_TEXTURE)
   2860                     {
   2861                         return gl::error(GL_INVALID_ENUM);
   2862                     }
   2863                     *params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0;
   2864                     break;
   2865 
   2866                   case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
   2867                     *params = attachmentObject->getRedSize();
   2868                     break;
   2869 
   2870                   case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
   2871                     *params = attachmentObject->getGreenSize();
   2872                     break;
   2873 
   2874                   case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
   2875                     *params = attachmentObject->getBlueSize();
   2876                     break;
   2877 
   2878                   case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
   2879                     *params = attachmentObject->getAlphaSize();
   2880                     break;
   2881 
   2882                   case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
   2883                     *params = attachmentObject->getDepthSize();
   2884                     break;
   2885 
   2886                   case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
   2887                     *params = attachmentObject->getStencilSize();
   2888                     break;
   2889 
   2890                   case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
   2891                     if (attachment == GL_DEPTH_STENCIL)
   2892                     {
   2893                         gl::error(GL_INVALID_OPERATION);
   2894                     }
   2895                     *params = attachmentObject->getComponentType();
   2896                     break;
   2897 
   2898                   case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
   2899                     *params = attachmentObject->getColorEncoding();
   2900                     break;
   2901 
   2902                   case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
   2903                     if (attachmentObjectType != GL_TEXTURE)
   2904                     {
   2905                         return gl::error(GL_INVALID_ENUM);
   2906                     }
   2907                     *params = attachmentLayer;
   2908                     break;
   2909 
   2910                   default:
   2911                     UNREACHABLE();
   2912                     break;
   2913                 }
   2914             }
   2915         }
   2916     }
   2917     catch (...)
   2918     {
   2919         return gl::error(GL_OUT_OF_MEMORY);
   2920     }
   2921 }
   2922 
   2923 GLenum __stdcall glGetGraphicsResetStatusEXT(void)
   2924 {
   2925     EVENT("()");
   2926 
   2927     try
   2928     {
   2929         gl::Context *context = gl::getContext();
   2930 
   2931         if (context)
   2932         {
   2933             return context->getResetStatus();
   2934         }
   2935 
   2936         return GL_NO_ERROR;
   2937     }
   2938     catch (...)
   2939     {
   2940         return GL_OUT_OF_MEMORY;
   2941     }
   2942 }
   2943 
   2944 void __stdcall glGetIntegerv(GLenum pname, GLint* params)
   2945 {
   2946     EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
   2947 
   2948     try
   2949     {
   2950         gl::Context *context = gl::getNonLostContext();
   2951 
   2952         if (context)
   2953         {
   2954             GLenum nativeType;
   2955             unsigned int numParams = 0;
   2956 
   2957             if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
   2958             {
   2959                 return;
   2960             }
   2961 
   2962             if (nativeType == GL_INT)
   2963             {
   2964                 context->getIntegerv(pname, params);
   2965             }
   2966             else
   2967             {
   2968                 CastStateValues(context, nativeType, pname, numParams, params);
   2969             }
   2970         }
   2971     }
   2972     catch (...)
   2973     {
   2974         return gl::error(GL_OUT_OF_MEMORY);
   2975     }
   2976 }
   2977 
   2978 void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
   2979 {
   2980     EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
   2981 
   2982     try
   2983     {
   2984         gl::Context *context = gl::getNonLostContext();
   2985 
   2986         if (context)
   2987         {
   2988             gl::Program *programObject = context->getProgram(program);
   2989 
   2990             if (!programObject)
   2991             {
   2992                 return gl::error(GL_INVALID_VALUE);
   2993             }
   2994 
   2995             if (context->getClientVersion() < 3)
   2996             {
   2997                 switch (pname)
   2998                 {
   2999                   case GL_ACTIVE_UNIFORM_BLOCKS:
   3000                   case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
   3001                   case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
   3002                   case GL_TRANSFORM_FEEDBACK_VARYINGS:
   3003                   case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
   3004                     return gl::error(GL_INVALID_ENUM);
   3005                 }
   3006             }
   3007 
   3008             switch (pname)
   3009             {
   3010               case GL_DELETE_STATUS:
   3011                 *params = programObject->isFlaggedForDeletion();
   3012                 return;
   3013               case GL_LINK_STATUS:
   3014                 *params = programObject->isLinked();
   3015                 return;
   3016               case GL_VALIDATE_STATUS:
   3017                 *params = programObject->isValidated();
   3018                 return;
   3019               case GL_INFO_LOG_LENGTH:
   3020                 *params = programObject->getInfoLogLength();
   3021                 return;
   3022               case GL_ATTACHED_SHADERS:
   3023                 *params = programObject->getAttachedShadersCount();
   3024                 return;
   3025               case GL_ACTIVE_ATTRIBUTES:
   3026                 *params = programObject->getActiveAttributeCount();
   3027                 return;
   3028               case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
   3029                 *params = programObject->getActiveAttributeMaxLength();
   3030                 return;
   3031               case GL_ACTIVE_UNIFORMS:
   3032                 *params = programObject->getActiveUniformCount();
   3033                 return;
   3034               case GL_ACTIVE_UNIFORM_MAX_LENGTH:
   3035                 *params = programObject->getActiveUniformMaxLength();
   3036                 return;
   3037               case GL_PROGRAM_BINARY_LENGTH_OES:
   3038                 *params = programObject->getProgramBinaryLength();
   3039                 return;
   3040               case GL_ACTIVE_UNIFORM_BLOCKS:
   3041                 *params = programObject->getActiveUniformBlockCount();
   3042                 return;
   3043               case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
   3044                 *params = programObject->getActiveUniformBlockMaxLength();
   3045                 break;
   3046               case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
   3047                 *params = programObject->getTransformFeedbackBufferMode();
   3048                 break;
   3049               case GL_TRANSFORM_FEEDBACK_VARYINGS:
   3050                 *params = programObject->getTransformFeedbackVaryingCount();
   3051                 break;
   3052               case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
   3053                 *params = programObject->getTransformFeedbackVaryingMaxLength();
   3054                 break;
   3055               default:
   3056                 return gl::error(GL_INVALID_ENUM);
   3057             }
   3058         }
   3059     }
   3060     catch (...)
   3061     {
   3062         return gl::error(GL_OUT_OF_MEMORY);
   3063     }
   3064 }
   3065 
   3066 void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
   3067 {
   3068     EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
   3069           program, bufsize, length, infolog);
   3070 
   3071     try
   3072     {
   3073         if (bufsize < 0)
   3074         {
   3075             return gl::error(GL_INVALID_VALUE);
   3076         }
   3077 
   3078         gl::Context *context = gl::getNonLostContext();
   3079 
   3080         if (context)
   3081         {
   3082             gl::Program *programObject = context->getProgram(program);
   3083 
   3084             if (!programObject)
   3085             {
   3086                 return gl::error(GL_INVALID_VALUE);
   3087             }
   3088 
   3089             programObject->getInfoLog(bufsize, length, infolog);
   3090         }
   3091     }
   3092     catch (...)
   3093     {
   3094         return gl::error(GL_OUT_OF_MEMORY);
   3095     }
   3096 }
   3097 
   3098 void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
   3099 {
   3100     EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
   3101 
   3102     try
   3103     {
   3104         gl::Context *context = gl::getNonLostContext();
   3105 
   3106         if (context)
   3107         {
   3108             if (!ValidQueryType(context, target))
   3109             {
   3110                 return gl::error(GL_INVALID_ENUM);
   3111             }
   3112 
   3113             switch (pname)
   3114             {
   3115               case GL_CURRENT_QUERY_EXT:
   3116                 params[0] = context->getActiveQueryId(target);
   3117                 break;
   3118 
   3119               default:
   3120                 return gl::error(GL_INVALID_ENUM);
   3121             }
   3122         }
   3123     }
   3124     catch (...)
   3125     {
   3126         return gl::error(GL_OUT_OF_MEMORY);
   3127     }
   3128 }
   3129 
   3130 void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
   3131 {
   3132     EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
   3133 
   3134     try
   3135     {
   3136         gl::Context *context = gl::getNonLostContext();
   3137 
   3138         if (context)
   3139         {
   3140             gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
   3141 
   3142             if (!queryObject)
   3143             {
   3144                 return gl::error(GL_INVALID_OPERATION);
   3145             }
   3146 
   3147             if (context->getActiveQueryId(queryObject->getType()) == id)
   3148             {
   3149                 return gl::error(GL_INVALID_OPERATION);
   3150             }
   3151 
   3152             switch(pname)
   3153             {
   3154               case GL_QUERY_RESULT_EXT:
   3155                 params[0] = queryObject->getResult();
   3156                 break;
   3157               case GL_QUERY_RESULT_AVAILABLE_EXT:
   3158                 params[0] = queryObject->isResultAvailable();
   3159                 break;
   3160               default:
   3161                 return gl::error(GL_INVALID_ENUM);
   3162             }
   3163         }
   3164     }
   3165     catch (...)
   3166     {
   3167         return gl::error(GL_OUT_OF_MEMORY);
   3168     }
   3169 }
   3170 
   3171 void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
   3172 {
   3173     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
   3174 
   3175     try
   3176     {
   3177         gl::Context *context = gl::getNonLostContext();
   3178 
   3179         if (context)
   3180         {
   3181             if (target != GL_RENDERBUFFER)
   3182             {
   3183                 return gl::error(GL_INVALID_ENUM);
   3184             }
   3185 
   3186             if (context->getRenderbufferHandle() == 0)
   3187             {
   3188                 return gl::error(GL_INVALID_OPERATION);
   3189             }
   3190 
   3191             gl::FramebufferAttachment *attachment = context->getRenderbuffer(context->getRenderbufferHandle());
   3192 
   3193             switch (pname)
   3194             {
   3195               case GL_RENDERBUFFER_WIDTH:           *params = attachment->getWidth();          break;
   3196               case GL_RENDERBUFFER_HEIGHT:          *params = attachment->getHeight();         break;
   3197               case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = attachment->getInternalFormat(); break;
   3198               case GL_RENDERBUFFER_RED_SIZE:        *params = attachment->getRedSize();        break;
   3199               case GL_RENDERBUFFER_GREEN_SIZE:      *params = attachment->getGreenSize();      break;
   3200               case GL_RENDERBUFFER_BLUE_SIZE:       *params = attachment->getBlueSize();       break;
   3201               case GL_RENDERBUFFER_ALPHA_SIZE:      *params = attachment->getAlphaSize();      break;
   3202               case GL_RENDERBUFFER_DEPTH_SIZE:      *params = attachment->getDepthSize();      break;
   3203               case GL_RENDERBUFFER_STENCIL_SIZE:    *params = attachment->getStencilSize();    break;
   3204               case GL_RENDERBUFFER_SAMPLES_ANGLE:
   3205                 if (context->getMaxSupportedSamples() != 0)
   3206                 {
   3207                     *params = attachment->getSamples();
   3208                 }
   3209                 else
   3210                 {
   3211                     return gl::error(GL_INVALID_ENUM);
   3212                 }
   3213                 break;
   3214               default:
   3215                 return gl::error(GL_INVALID_ENUM);
   3216             }
   3217         }
   3218     }
   3219     catch (...)
   3220     {
   3221         return gl::error(GL_OUT_OF_MEMORY);
   3222     }
   3223 }
   3224 
   3225 void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
   3226 {
   3227     EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
   3228 
   3229     try
   3230     {
   3231         gl::Context *context = gl::getNonLostContext();
   3232 
   3233         if (context)
   3234         {
   3235             gl::Shader *shaderObject = context->getShader(shader);
   3236 
   3237             if (!shaderObject)
   3238             {
   3239                 return gl::error(GL_INVALID_VALUE);
   3240             }
   3241 
   3242             switch (pname)
   3243             {
   3244               case GL_SHADER_TYPE:
   3245                 *params = shaderObject->getType();
   3246                 return;
   3247               case GL_DELETE_STATUS:
   3248                 *params = shaderObject->isFlaggedForDeletion();
   3249                 return;
   3250               case GL_COMPILE_STATUS:
   3251                 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
   3252                 return;
   3253               case GL_INFO_LOG_LENGTH:
   3254                 *params = shaderObject->getInfoLogLength();
   3255                 return;
   3256               case GL_SHADER_SOURCE_LENGTH:
   3257                 *params = shaderObject->getSourceLength();
   3258                 return;
   3259               case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
   3260                 *params = shaderObject->getTranslatedSourceLength();
   3261                 return;
   3262               default:
   3263                 return gl::error(GL_INVALID_ENUM);
   3264             }
   3265         }
   3266     }
   3267     catch (...)
   3268     {
   3269         return gl::error(GL_OUT_OF_MEMORY);
   3270     }
   3271 }
   3272 
   3273 void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
   3274 {
   3275     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
   3276           shader, bufsize, length, infolog);
   3277 
   3278     try
   3279     {
   3280         if (bufsize < 0)
   3281         {
   3282             return gl::error(GL_INVALID_VALUE);
   3283         }
   3284 
   3285         gl::Context *context = gl::getNonLostContext();
   3286 
   3287         if (context)
   3288         {
   3289             gl::Shader *shaderObject = context->getShader(shader);
   3290 
   3291             if (!shaderObject)
   3292             {
   3293                 return gl::error(GL_INVALID_VALUE);
   3294             }
   3295 
   3296             shaderObject->getInfoLog(bufsize, length, infolog);
   3297         }
   3298     }
   3299     catch (...)
   3300     {
   3301         return gl::error(GL_OUT_OF_MEMORY);
   3302     }
   3303 }
   3304 
   3305 void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
   3306 {
   3307     EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
   3308           shadertype, precisiontype, range, precision);
   3309 
   3310     try
   3311     {
   3312         switch (shadertype)
   3313         {
   3314           case GL_VERTEX_SHADER:
   3315           case GL_FRAGMENT_SHADER:
   3316             break;
   3317           default:
   3318             return gl::error(GL_INVALID_ENUM);
   3319         }
   3320 
   3321         switch (precisiontype)
   3322         {
   3323           case GL_LOW_FLOAT:
   3324           case GL_MEDIUM_FLOAT:
   3325           case GL_HIGH_FLOAT:
   3326             // Assume IEEE 754 precision
   3327             range[0] = 127;
   3328             range[1] = 127;
   3329             *precision = 23;
   3330             break;
   3331           case GL_LOW_INT:
   3332           case GL_MEDIUM_INT:
   3333           case GL_HIGH_INT:
   3334             // Some (most) hardware only supports single-precision floating-point numbers,
   3335             // which can accurately represent integers up to +/-16777216
   3336             range[0] = 24;
   3337             range[1] = 24;
   3338             *precision = 0;
   3339             break;
   3340           default:
   3341             return gl::error(GL_INVALID_ENUM);
   3342         }
   3343     }
   3344     catch (...)
   3345     {
   3346         return gl::error(GL_OUT_OF_MEMORY);
   3347     }
   3348 }
   3349 
   3350 void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
   3351 {
   3352     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
   3353           shader, bufsize, length, source);
   3354 
   3355     try
   3356     {
   3357         if (bufsize < 0)
   3358         {
   3359             return gl::error(GL_INVALID_VALUE);
   3360         }
   3361 
   3362         gl::Context *context = gl::getNonLostContext();
   3363 
   3364         if (context)
   3365         {
   3366             gl::Shader *shaderObject = context->getShader(shader);
   3367 
   3368             if (!shaderObject)
   3369             {
   3370                 return gl::error(GL_INVALID_OPERATION);
   3371             }
   3372 
   3373             shaderObject->getSource(bufsize, length, source);
   3374         }
   3375     }
   3376     catch (...)
   3377     {
   3378         return gl::error(GL_OUT_OF_MEMORY);
   3379     }
   3380 }
   3381 
   3382 void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
   3383 {
   3384     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
   3385           shader, bufsize, length, source);
   3386 
   3387     try
   3388     {
   3389         if (bufsize < 0)
   3390         {
   3391             return gl::error(GL_INVALID_VALUE);
   3392         }
   3393 
   3394         gl::Context *context = gl::getNonLostContext();
   3395 
   3396         if (context)
   3397         {
   3398             gl::Shader *shaderObject = context->getShader(shader);
   3399 
   3400             if (!shaderObject)
   3401             {
   3402                 return gl::error(GL_INVALID_OPERATION);
   3403             }
   3404 
   3405             shaderObject->getTranslatedSource(bufsize, length, source);
   3406         }
   3407     }
   3408     catch (...)
   3409     {
   3410         return gl::error(GL_OUT_OF_MEMORY);
   3411     }
   3412 }
   3413 
   3414 const GLubyte* __stdcall glGetString(GLenum name)
   3415 {
   3416     EVENT("(GLenum name = 0x%X)", name);
   3417 
   3418     try
   3419     {
   3420         gl::Context *context = gl::getNonLostContext();
   3421 
   3422         switch (name)
   3423         {
   3424           case GL_VENDOR:
   3425             return (GLubyte*)"Google Inc.";
   3426           case GL_RENDERER:
   3427             return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
   3428           case GL_VERSION:
   3429             if (context->getClientVersion() == 2)
   3430             {
   3431                 return (GLubyte*)"OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")";
   3432             }
   3433             else
   3434             {
   3435                 return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")";
   3436             }
   3437           case GL_SHADING_LANGUAGE_VERSION:
   3438             if (context->getClientVersion() == 2)
   3439             {
   3440                 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")";
   3441             }
   3442             else
   3443             {
   3444                 return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")";
   3445             }
   3446           case GL_EXTENSIONS:
   3447             return (GLubyte*)((context != NULL) ? context->getCombinedExtensionsString() : "");
   3448           default:
   3449             return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL);
   3450         }
   3451     }
   3452     catch (...)
   3453     {
   3454         return gl::error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
   3455     }
   3456 }
   3457 
   3458 void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
   3459 {
   3460     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
   3461 
   3462     try
   3463     {
   3464         gl::Context *context = gl::getNonLostContext();
   3465 
   3466         if (context)
   3467         {
   3468             gl::Texture *texture = context->getTargetTexture(target);
   3469 
   3470             if (!texture)
   3471             {
   3472                 return gl::error(GL_INVALID_ENUM);
   3473             }
   3474 
   3475             switch (pname)
   3476             {
   3477               case GL_TEXTURE_MAG_FILTER:
   3478                 *params = (GLfloat)texture->getMagFilter();
   3479                 break;
   3480               case GL_TEXTURE_MIN_FILTER:
   3481                 *params = (GLfloat)texture->getMinFilter();
   3482                 break;
   3483               case GL_TEXTURE_WRAP_S:
   3484                 *params = (GLfloat)texture->getWrapS();
   3485                 break;
   3486               case GL_TEXTURE_WRAP_T:
   3487                 *params = (GLfloat)texture->getWrapT();
   3488                 break;
   3489               case GL_TEXTURE_WRAP_R:
   3490                 if (context->getClientVersion() < 3)
   3491                 {
   3492                     return gl::error(GL_INVALID_ENUM);
   3493                 }
   3494                 *params = (GLfloat)texture->getWrapR();
   3495                 break;
   3496               case GL_TEXTURE_IMMUTABLE_FORMAT:
   3497                 // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
   3498                 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
   3499                 break;
   3500               case GL_TEXTURE_IMMUTABLE_LEVELS:
   3501                 if (context->getClientVersion() < 3)
   3502                 {
   3503                     return gl::error(GL_INVALID_ENUM);
   3504                 }
   3505                 *params = (GLfloat)texture->immutableLevelCount();
   3506                 break;
   3507               case GL_TEXTURE_USAGE_ANGLE:
   3508                 *params = (GLfloat)texture->getUsage();
   3509                 break;
   3510               case GL_TEXTURE_MAX_ANISOTROPY_EXT:
   3511                 if (!context->supportsTextureFilterAnisotropy())
   3512                 {
   3513                     return gl::error(GL_INVALID_ENUM);
   3514                 }
   3515                 *params = (GLfloat)texture->getMaxAnisotropy();
   3516                 break;
   3517               case GL_TEXTURE_SWIZZLE_R:
   3518                 if (context->getClientVersion() < 3)
   3519                 {
   3520                     return gl::error(GL_INVALID_ENUM);
   3521                 }
   3522                 *params = (GLfloat)texture->getSwizzleRed();
   3523                 break;
   3524               case GL_TEXTURE_SWIZZLE_G:
   3525                 if (context->getClientVersion() < 3)
   3526                 {
   3527                     return gl::error(GL_INVALID_ENUM);
   3528                 }
   3529                 *params = (GLfloat)texture->getSwizzleGreen();
   3530                 break;
   3531               case GL_TEXTURE_SWIZZLE_B:
   3532                 if (context->getClientVersion() < 3)
   3533                 {
   3534                     return gl::error(GL_INVALID_ENUM);
   3535                 }
   3536                 *params = (GLfloat)texture->getSwizzleBlue();
   3537                 break;
   3538               case GL_TEXTURE_SWIZZLE_A:
   3539                 if (context->getClientVersion() < 3)
   3540                 {
   3541                     return gl::error(GL_INVALID_ENUM);
   3542                 }
   3543                 *params = (GLfloat)texture->getSwizzleAlpha();
   3544                 break;
   3545               case GL_TEXTURE_BASE_LEVEL:
   3546                 if (context->getClientVersion() < 3)
   3547                 {
   3548                     return gl::error(GL_INVALID_ENUM);
   3549                 }
   3550                 *params = (GLfloat)texture->getBaseLevel();
   3551                 break;
   3552               case GL_TEXTURE_MAX_LEVEL:
   3553                 if (context->getClientVersion() < 3)
   3554                 {
   3555                     return gl::error(GL_INVALID_ENUM);
   3556                 }
   3557                 *params = (GLfloat)texture->getMaxLevel();
   3558                 break;
   3559               case GL_TEXTURE_MIN_LOD:
   3560                 if (context->getClientVersion() < 3)
   3561                 {
   3562                     return gl::error(GL_INVALID_ENUM);
   3563                 }
   3564                 *params = texture->getMinLod();
   3565                 break;
   3566               case GL_TEXTURE_MAX_LOD:
   3567                 if (context->getClientVersion() < 3)
   3568                 {
   3569                     return gl::error(GL_INVALID_ENUM);
   3570                 }
   3571                 *params = texture->getMaxLod();
   3572                 break;
   3573               default:
   3574                 return gl::error(GL_INVALID_ENUM);
   3575             }
   3576         }
   3577     }
   3578     catch (...)
   3579     {
   3580         return gl::error(GL_OUT_OF_MEMORY);
   3581     }
   3582 }
   3583 
   3584 void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
   3585 {
   3586     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
   3587 
   3588     try
   3589     {
   3590         gl::Context *context = gl::getNonLostContext();
   3591 
   3592         if (context)
   3593         {
   3594             gl::Texture *texture = context->getTargetTexture(target);
   3595 
   3596             if (!texture)
   3597             {
   3598                 return gl::error(GL_INVALID_ENUM);
   3599             }
   3600 
   3601             switch (pname)
   3602             {
   3603               case GL_TEXTURE_MAG_FILTER:
   3604                 *params = texture->getMagFilter();
   3605                 break;
   3606               case GL_TEXTURE_MIN_FILTER:
   3607                 *params = texture->getMinFilter();
   3608                 break;
   3609               case GL_TEXTURE_WRAP_S:
   3610                 *params = texture->getWrapS();
   3611                 break;
   3612               case GL_TEXTURE_WRAP_T:
   3613                 *params = texture->getWrapT();
   3614                 break;
   3615               case GL_TEXTURE_WRAP_R:
   3616                 if (context->getClientVersion() < 3)
   3617                 {
   3618                     return gl::error(GL_INVALID_ENUM);
   3619                 }
   3620                 *params = texture->getWrapR();
   3621                 break;
   3622               case GL_TEXTURE_IMMUTABLE_FORMAT:
   3623                 // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
   3624                 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
   3625                 break;
   3626               case GL_TEXTURE_IMMUTABLE_LEVELS:
   3627                 if (context->getClientVersion() < 3)
   3628                 {
   3629                     return gl::error(GL_INVALID_ENUM);
   3630                 }
   3631                 *params = texture->immutableLevelCount();
   3632                 break;
   3633               case GL_TEXTURE_USAGE_ANGLE:
   3634                 *params = texture->getUsage();
   3635                 break;
   3636               case GL_TEXTURE_MAX_ANISOTROPY_EXT:
   3637                 if (!context->supportsTextureFilterAnisotropy())
   3638                 {
   3639                     return gl::error(GL_INVALID_ENUM);
   3640                 }
   3641                 *params = (GLint)texture->getMaxAnisotropy();
   3642                 break;
   3643               case GL_TEXTURE_SWIZZLE_R:
   3644                 if (context->getClientVersion() < 3)
   3645                 {
   3646                     return gl::error(GL_INVALID_ENUM);
   3647                 }
   3648                 *params = texture->getSwizzleRed();
   3649                 break;
   3650               case GL_TEXTURE_SWIZZLE_G:
   3651                 if (context->getClientVersion() < 3)
   3652                 {
   3653                     return gl::error(GL_INVALID_ENUM);
   3654                 }
   3655                 *params = texture->getSwizzleGreen();
   3656                 break;
   3657               case GL_TEXTURE_SWIZZLE_B:
   3658                 if (context->getClientVersion() < 3)
   3659                 {
   3660                     return gl::error(GL_INVALID_ENUM);
   3661                 }
   3662                 *params = texture->getSwizzleBlue();
   3663                 break;
   3664               case GL_TEXTURE_SWIZZLE_A:
   3665                 if (context->getClientVersion() < 3)
   3666                 {
   3667                     return gl::error(GL_INVALID_ENUM);
   3668                 }
   3669                 *params = texture->getSwizzleAlpha();
   3670                 break;
   3671               case GL_TEXTURE_BASE_LEVEL:
   3672                 if (context->getClientVersion() < 3)
   3673                 {
   3674                     return gl::error(GL_INVALID_ENUM);
   3675                 }
   3676                 *params = texture->getBaseLevel();
   3677                 break;
   3678               case GL_TEXTURE_MAX_LEVEL:
   3679                 if (context->getClientVersion() < 3)
   3680                 {
   3681                     return gl::error(GL_INVALID_ENUM);
   3682                 }
   3683                 *params = texture->getMaxLevel();
   3684                 break;
   3685               case GL_TEXTURE_MIN_LOD:
   3686                 if (context->getClientVersion() < 3)
   3687                 {
   3688                     return gl::error(GL_INVALID_ENUM);
   3689                 }
   3690                 *params = (GLint)texture->getMinLod();
   3691                 break;
   3692               case GL_TEXTURE_MAX_LOD:
   3693                 if (context->getClientVersion() < 3)
   3694                 {
   3695                     return gl::error(GL_INVALID_ENUM);
   3696                 }
   3697                 *params = (GLint)texture->getMaxLod();
   3698                 break;
   3699               default:
   3700                 return gl::error(GL_INVALID_ENUM);
   3701             }
   3702         }
   3703     }
   3704     catch (...)
   3705     {
   3706         return gl::error(GL_OUT_OF_MEMORY);
   3707     }
   3708 }
   3709 
   3710 void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
   3711 {
   3712     EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
   3713           program, location, bufSize, params);
   3714 
   3715     try
   3716     {
   3717         if (bufSize < 0)
   3718         {
   3719             return gl::error(GL_INVALID_VALUE);
   3720         }
   3721 
   3722         gl::Context *context = gl::getNonLostContext();
   3723 
   3724         if (context)
   3725         {
   3726             if (program == 0)
   3727             {
   3728                 return gl::error(GL_INVALID_VALUE);
   3729             }
   3730 
   3731             gl::Program *programObject = context->getProgram(program);
   3732 
   3733             if (!programObject || !programObject->isLinked())
   3734             {
   3735                 return gl::error(GL_INVALID_OPERATION);
   3736             }
   3737 
   3738             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   3739             if (!programBinary)
   3740             {
   3741                 return gl::error(GL_INVALID_OPERATION);
   3742             }
   3743 
   3744             if (!programBinary->getUniformfv(location, &bufSize, params))
   3745             {
   3746                 return gl::error(GL_INVALID_OPERATION);
   3747             }
   3748         }
   3749     }
   3750     catch (...)
   3751     {
   3752         return gl::error(GL_OUT_OF_MEMORY);
   3753     }
   3754 }
   3755 
   3756 void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
   3757 {
   3758     EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
   3759 
   3760     try
   3761     {
   3762         gl::Context *context = gl::getNonLostContext();
   3763 
   3764         if (context)
   3765         {
   3766             if (program == 0)
   3767             {
   3768                 return gl::error(GL_INVALID_VALUE);
   3769             }
   3770 
   3771             gl::Program *programObject = context->getProgram(program);
   3772 
   3773             if (!programObject || !programObject->isLinked())
   3774             {
   3775                 return gl::error(GL_INVALID_OPERATION);
   3776             }
   3777 
   3778             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   3779             if (!programBinary)
   3780             {
   3781                 return gl::error(GL_INVALID_OPERATION);
   3782             }
   3783 
   3784             if (!programBinary->getUniformfv(location, NULL, params))
   3785             {
   3786                 return gl::error(GL_INVALID_OPERATION);
   3787             }
   3788         }
   3789     }
   3790     catch (...)
   3791     {
   3792         return gl::error(GL_OUT_OF_MEMORY);
   3793     }
   3794 }
   3795 
   3796 void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
   3797 {
   3798     EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
   3799           program, location, bufSize, params);
   3800 
   3801     try
   3802     {
   3803         if (bufSize < 0)
   3804         {
   3805             return gl::error(GL_INVALID_VALUE);
   3806         }
   3807 
   3808         gl::Context *context = gl::getNonLostContext();
   3809 
   3810         if (context)
   3811         {
   3812             if (program == 0)
   3813             {
   3814                 return gl::error(GL_INVALID_VALUE);
   3815             }
   3816 
   3817             gl::Program *programObject = context->getProgram(program);
   3818 
   3819             if (!programObject || !programObject->isLinked())
   3820             {
   3821                 return gl::error(GL_INVALID_OPERATION);
   3822             }
   3823 
   3824             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   3825             if (!programBinary)
   3826             {
   3827                 return gl::error(GL_INVALID_OPERATION);
   3828             }
   3829 
   3830             if (!programBinary->getUniformiv(location, &bufSize, params))
   3831             {
   3832                 return gl::error(GL_INVALID_OPERATION);
   3833             }
   3834         }
   3835     }
   3836     catch (...)
   3837     {
   3838         return gl::error(GL_OUT_OF_MEMORY);
   3839     }
   3840 }
   3841 
   3842 void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
   3843 {
   3844     EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
   3845 
   3846     try
   3847     {
   3848         gl::Context *context = gl::getNonLostContext();
   3849 
   3850         if (context)
   3851         {
   3852             if (program == 0)
   3853             {
   3854                 return gl::error(GL_INVALID_VALUE);
   3855             }
   3856 
   3857             gl::Program *programObject = context->getProgram(program);
   3858 
   3859             if (!programObject || !programObject->isLinked())
   3860             {
   3861                 return gl::error(GL_INVALID_OPERATION);
   3862             }
   3863 
   3864             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   3865             if (!programBinary)
   3866             {
   3867                 return gl::error(GL_INVALID_OPERATION);
   3868             }
   3869 
   3870             if (!programBinary->getUniformiv(location, NULL, params))
   3871             {
   3872                 return gl::error(GL_INVALID_OPERATION);
   3873             }
   3874         }
   3875     }
   3876     catch (...)
   3877     {
   3878         return gl::error(GL_OUT_OF_MEMORY);
   3879     }
   3880 }
   3881 
   3882 int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
   3883 {
   3884     EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
   3885 
   3886     try
   3887     {
   3888         gl::Context *context = gl::getNonLostContext();
   3889 
   3890         if (strstr(name, "gl_") == name)
   3891         {
   3892             return -1;
   3893         }
   3894 
   3895         if (context)
   3896         {
   3897             gl::Program *programObject = context->getProgram(program);
   3898 
   3899             if (!programObject)
   3900             {
   3901                 if (context->getShader(program))
   3902                 {
   3903                     return gl::error(GL_INVALID_OPERATION, -1);
   3904                 }
   3905                 else
   3906                 {
   3907                     return gl::error(GL_INVALID_VALUE, -1);
   3908                 }
   3909             }
   3910 
   3911             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   3912             if (!programObject->isLinked() || !programBinary)
   3913             {
   3914                 return gl::error(GL_INVALID_OPERATION, -1);
   3915             }
   3916 
   3917             return programBinary->getUniformLocation(name);
   3918         }
   3919     }
   3920     catch (...)
   3921     {
   3922         return gl::error(GL_OUT_OF_MEMORY, -1);
   3923     }
   3924 
   3925     return -1;
   3926 }
   3927 
   3928 void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
   3929 {
   3930     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
   3931 
   3932     try
   3933     {
   3934         gl::Context *context = gl::getNonLostContext();
   3935 
   3936         if (context)
   3937         {
   3938             if (index >= gl::MAX_VERTEX_ATTRIBS)
   3939             {
   3940                 return gl::error(GL_INVALID_VALUE);
   3941             }
   3942 
   3943             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
   3944 
   3945             if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
   3946             {
   3947                 return;
   3948             }
   3949 
   3950             if (pname == GL_CURRENT_VERTEX_ATTRIB)
   3951             {
   3952                 const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
   3953                 for (int i = 0; i < 4; ++i)
   3954                 {
   3955                     params[i] = currentValueData.FloatValues[i];
   3956                 }
   3957             }
   3958             else
   3959             {
   3960                 *params = attribState.querySingleParameter<GLfloat>(pname);
   3961             }
   3962         }
   3963     }
   3964     catch (...)
   3965     {
   3966         return gl::error(GL_OUT_OF_MEMORY);
   3967     }
   3968 }
   3969 
   3970 void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
   3971 {
   3972     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
   3973 
   3974     try
   3975     {
   3976         gl::Context *context = gl::getNonLostContext();
   3977 
   3978         if (context)
   3979         {
   3980             if (index >= gl::MAX_VERTEX_ATTRIBS)
   3981             {
   3982                 return gl::error(GL_INVALID_VALUE);
   3983             }
   3984 
   3985             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
   3986 
   3987             if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
   3988             {
   3989                 return;
   3990             }
   3991 
   3992             if (pname == GL_CURRENT_VERTEX_ATTRIB)
   3993             {
   3994                 const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
   3995                 for (int i = 0; i < 4; ++i)
   3996                 {
   3997                     float currentValue = currentValueData.FloatValues[i];
   3998                     params[i] = gl::iround<GLint>(currentValue);
   3999                 }
   4000             }
   4001             else
   4002             {
   4003                 *params = attribState.querySingleParameter<GLint>(pname);
   4004             }
   4005         }
   4006     }
   4007     catch (...)
   4008     {
   4009         return gl::error(GL_OUT_OF_MEMORY);
   4010     }
   4011 }
   4012 
   4013 void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
   4014 {
   4015     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
   4016 
   4017     try
   4018     {
   4019         gl::Context *context = gl::getNonLostContext();
   4020 
   4021         if (context)
   4022         {
   4023             if (index >= gl::MAX_VERTEX_ATTRIBS)
   4024             {
   4025                 return gl::error(GL_INVALID_VALUE);
   4026             }
   4027 
   4028             if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
   4029             {
   4030                 return gl::error(GL_INVALID_ENUM);
   4031             }
   4032 
   4033             *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
   4034         }
   4035     }
   4036     catch (...)
   4037     {
   4038         return gl::error(GL_OUT_OF_MEMORY);
   4039     }
   4040 }
   4041 
   4042 void __stdcall glHint(GLenum target, GLenum mode)
   4043 {
   4044     EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
   4045 
   4046     try
   4047     {
   4048         switch (mode)
   4049         {
   4050           case GL_FASTEST:
   4051           case GL_NICEST:
   4052           case GL_DONT_CARE:
   4053             break;
   4054           default:
   4055             return gl::error(GL_INVALID_ENUM);
   4056         }
   4057 
   4058         gl::Context *context = gl::getNonLostContext();
   4059         switch (target)
   4060         {
   4061           case GL_GENERATE_MIPMAP_HINT:
   4062             if (context) context->setGenerateMipmapHint(mode);
   4063             break;
   4064           case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
   4065             if (context) context->setFragmentShaderDerivativeHint(mode);
   4066             break;
   4067           default:
   4068             return gl::error(GL_INVALID_ENUM);
   4069         }
   4070     }
   4071     catch (...)
   4072     {
   4073         return gl::error(GL_OUT_OF_MEMORY);
   4074     }
   4075 }
   4076 
   4077 GLboolean __stdcall glIsBuffer(GLuint buffer)
   4078 {
   4079     EVENT("(GLuint buffer = %d)", buffer);
   4080 
   4081     try
   4082     {
   4083         gl::Context *context = gl::getNonLostContext();
   4084 
   4085         if (context && buffer)
   4086         {
   4087             gl::Buffer *bufferObject = context->getBuffer(buffer);
   4088 
   4089             if (bufferObject)
   4090             {
   4091                 return GL_TRUE;
   4092             }
   4093         }
   4094     }
   4095     catch (...)
   4096     {
   4097         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   4098     }
   4099 
   4100     return GL_FALSE;
   4101 }
   4102 
   4103 GLboolean __stdcall glIsEnabled(GLenum cap)
   4104 {
   4105     EVENT("(GLenum cap = 0x%X)", cap);
   4106 
   4107     try
   4108     {
   4109         gl::Context *context = gl::getNonLostContext();
   4110 
   4111         if (context)
   4112         {
   4113             if (!ValidCap(context, cap))
   4114             {
   4115                 return gl::error(GL_INVALID_ENUM, false);
   4116             }
   4117 
   4118             return context->getCap(cap);
   4119         }
   4120     }
   4121     catch (...)
   4122     {
   4123         return gl::error(GL_OUT_OF_MEMORY, false);
   4124     }
   4125 
   4126     return false;
   4127 }
   4128 
   4129 GLboolean __stdcall glIsFenceNV(GLuint fence)
   4130 {
   4131     EVENT("(GLuint fence = %d)", fence);
   4132 
   4133     try
   4134     {
   4135         gl::Context *context = gl::getNonLostContext();
   4136 
   4137         if (context)
   4138         {
   4139             gl::FenceNV *fenceObject = context->getFenceNV(fence);
   4140 
   4141             if (fenceObject == NULL)
   4142             {
   4143                 return GL_FALSE;
   4144             }
   4145 
   4146             return fenceObject->isFence();
   4147         }
   4148     }
   4149     catch (...)
   4150     {
   4151         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   4152     }
   4153 
   4154     return GL_FALSE;
   4155 }
   4156 
   4157 GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
   4158 {
   4159     EVENT("(GLuint framebuffer = %d)", framebuffer);
   4160 
   4161     try
   4162     {
   4163         gl::Context *context = gl::getNonLostContext();
   4164 
   4165         if (context && framebuffer)
   4166         {
   4167             gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
   4168 
   4169             if (framebufferObject)
   4170             {
   4171                 return GL_TRUE;
   4172             }
   4173         }
   4174     }
   4175     catch (...)
   4176     {
   4177         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   4178     }
   4179 
   4180     return GL_FALSE;
   4181 }
   4182 
   4183 GLboolean __stdcall glIsProgram(GLuint program)
   4184 {
   4185     EVENT("(GLuint program = %d)", program);
   4186 
   4187     try
   4188     {
   4189         gl::Context *context = gl::getNonLostContext();
   4190 
   4191         if (context && program)
   4192         {
   4193             gl::Program *programObject = context->getProgram(program);
   4194 
   4195             if (programObject)
   4196             {
   4197                 return GL_TRUE;
   4198             }
   4199         }
   4200     }
   4201     catch (...)
   4202     {
   4203         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   4204     }
   4205 
   4206     return GL_FALSE;
   4207 }
   4208 
   4209 GLboolean __stdcall glIsQueryEXT(GLuint id)
   4210 {
   4211     EVENT("(GLuint id = %d)", id);
   4212 
   4213     try
   4214     {
   4215         gl::Context *context = gl::getNonLostContext();
   4216 
   4217         if (context)
   4218         {
   4219             return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
   4220         }
   4221     }
   4222     catch (...)
   4223     {
   4224         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   4225     }
   4226 
   4227     return GL_FALSE;
   4228 }
   4229 
   4230 GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
   4231 {
   4232     EVENT("(GLuint renderbuffer = %d)", renderbuffer);
   4233 
   4234     try
   4235     {
   4236         gl::Context *context = gl::getNonLostContext();
   4237 
   4238         if (context && renderbuffer)
   4239         {
   4240             gl::FramebufferAttachment *renderbufferObject = context->getRenderbuffer(renderbuffer);
   4241 
   4242             if (renderbufferObject)
   4243             {
   4244                 return GL_TRUE;
   4245             }
   4246         }
   4247     }
   4248     catch (...)
   4249     {
   4250         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   4251     }
   4252 
   4253     return GL_FALSE;
   4254 }
   4255 
   4256 GLboolean __stdcall glIsShader(GLuint shader)
   4257 {
   4258     EVENT("(GLuint shader = %d)", shader);
   4259 
   4260     try
   4261     {
   4262         gl::Context *context = gl::getNonLostContext();
   4263 
   4264         if (context && shader)
   4265         {
   4266             gl::Shader *shaderObject = context->getShader(shader);
   4267 
   4268             if (shaderObject)
   4269             {
   4270                 return GL_TRUE;
   4271             }
   4272         }
   4273     }
   4274     catch (...)
   4275     {
   4276         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   4277     }
   4278 
   4279     return GL_FALSE;
   4280 }
   4281 
   4282 GLboolean __stdcall glIsTexture(GLuint texture)
   4283 {
   4284     EVENT("(GLuint texture = %d)", texture);
   4285 
   4286     try
   4287     {
   4288         gl::Context *context = gl::getNonLostContext();
   4289 
   4290         if (context && texture)
   4291         {
   4292             gl::Texture *textureObject = context->getTexture(texture);
   4293 
   4294             if (textureObject)
   4295             {
   4296                 return GL_TRUE;
   4297             }
   4298         }
   4299     }
   4300     catch (...)
   4301     {
   4302         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   4303     }
   4304 
   4305     return GL_FALSE;
   4306 }
   4307 
   4308 void __stdcall glLineWidth(GLfloat width)
   4309 {
   4310     EVENT("(GLfloat width = %f)", width);
   4311 
   4312     try
   4313     {
   4314         if (width <= 0.0f)
   4315         {
   4316             return gl::error(GL_INVALID_VALUE);
   4317         }
   4318 
   4319         gl::Context *context = gl::getNonLostContext();
   4320 
   4321         if (context)
   4322         {
   4323             context->setLineWidth(width);
   4324         }
   4325     }
   4326     catch (...)
   4327     {
   4328         return gl::error(GL_OUT_OF_MEMORY);
   4329     }
   4330 }
   4331 
   4332 void __stdcall glLinkProgram(GLuint program)
   4333 {
   4334     EVENT("(GLuint program = %d)", program);
   4335 
   4336     try
   4337     {
   4338         gl::Context *context = gl::getNonLostContext();
   4339 
   4340         if (context)
   4341         {
   4342             gl::Program *programObject = context->getProgram(program);
   4343 
   4344             if (!programObject)
   4345             {
   4346                 if (context->getShader(program))
   4347                 {
   4348                     return gl::error(GL_INVALID_OPERATION);
   4349                 }
   4350                 else
   4351                 {
   4352                     return gl::error(GL_INVALID_VALUE);
   4353                 }
   4354             }
   4355 
   4356             context->linkProgram(program);
   4357         }
   4358     }
   4359     catch (...)
   4360     {
   4361         return gl::error(GL_OUT_OF_MEMORY);
   4362     }
   4363 }
   4364 
   4365 void __stdcall glPixelStorei(GLenum pname, GLint param)
   4366 {
   4367     EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
   4368 
   4369     try
   4370     {
   4371         gl::Context *context = gl::getNonLostContext();
   4372 
   4373         if (context)
   4374         {
   4375             switch (pname)
   4376             {
   4377               case GL_UNPACK_ALIGNMENT:
   4378                 if (param != 1 && param != 2 && param != 4 && param != 8)
   4379                 {
   4380                     return gl::error(GL_INVALID_VALUE);
   4381                 }
   4382 
   4383                 context->setUnpackAlignment(param);
   4384                 break;
   4385 
   4386               case GL_PACK_ALIGNMENT:
   4387                 if (param != 1 && param != 2 && param != 4 && param != 8)
   4388                 {
   4389                     return gl::error(GL_INVALID_VALUE);
   4390                 }
   4391 
   4392                 context->setPackAlignment(param);
   4393                 break;
   4394 
   4395               case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
   4396                 context->setPackReverseRowOrder(param != 0);
   4397                 break;
   4398 
   4399               case GL_UNPACK_IMAGE_HEIGHT:
   4400               case GL_UNPACK_SKIP_IMAGES:
   4401               case GL_UNPACK_ROW_LENGTH:
   4402               case GL_UNPACK_SKIP_ROWS:
   4403               case GL_UNPACK_SKIP_PIXELS:
   4404               case GL_PACK_ROW_LENGTH:
   4405               case GL_PACK_SKIP_ROWS:
   4406               case GL_PACK_SKIP_PIXELS:
   4407                 if (context->getClientVersion() < 3)
   4408                 {
   4409                     return gl::error(GL_INVALID_ENUM);
   4410                 }
   4411                 UNIMPLEMENTED();
   4412                 break;
   4413 
   4414               default:
   4415                 return gl::error(GL_INVALID_ENUM);
   4416             }
   4417         }
   4418     }
   4419     catch (...)
   4420     {
   4421         return gl::error(GL_OUT_OF_MEMORY);
   4422     }
   4423 }
   4424 
   4425 void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
   4426 {
   4427     EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
   4428 
   4429     try
   4430     {
   4431         gl::Context *context = gl::getNonLostContext();
   4432 
   4433         if (context)
   4434         {
   4435             context->setPolygonOffsetParams(factor, units);
   4436         }
   4437     }
   4438     catch (...)
   4439     {
   4440         return gl::error(GL_OUT_OF_MEMORY);
   4441     }
   4442 }
   4443 
   4444 void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
   4445                                 GLenum format, GLenum type, GLsizei bufSize,
   4446                                 GLvoid *data)
   4447 {
   4448     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
   4449           "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
   4450           x, y, width, height, format, type, bufSize, data);
   4451 
   4452     try
   4453     {
   4454         if (width < 0 || height < 0 || bufSize < 0)
   4455         {
   4456             return gl::error(GL_INVALID_VALUE);
   4457         }
   4458 
   4459         gl::Context *context = gl::getNonLostContext();
   4460 
   4461         if (context)
   4462         {
   4463             if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
   4464                                                   format, type, &bufSize, data))
   4465             {
   4466                 return;
   4467             }
   4468 
   4469             context->readPixels(x, y, width, height, format, type, &bufSize, data);
   4470         }
   4471     }
   4472     catch (...)
   4473     {
   4474         return gl::error(GL_OUT_OF_MEMORY);
   4475     }
   4476 }
   4477 
   4478 void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   4479                             GLenum format, GLenum type, GLvoid* pixels)
   4480 {
   4481     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
   4482           "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
   4483           x, y, width, height, format, type,  pixels);
   4484 
   4485     try
   4486     {
   4487         if (width < 0 || height < 0)
   4488         {
   4489             return gl::error(GL_INVALID_VALUE);
   4490         }
   4491 
   4492         gl::Context *context = gl::getNonLostContext();
   4493 
   4494         if (context)
   4495         {
   4496             if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
   4497                                                   format, type, NULL, pixels))
   4498             {
   4499                 return;
   4500             }
   4501 
   4502             context->readPixels(x, y, width, height, format, type, NULL, pixels);
   4503         }
   4504     }
   4505     catch (...)
   4506     {
   4507         return gl::error(GL_OUT_OF_MEMORY);
   4508     }
   4509 }
   4510 
   4511 void __stdcall glReleaseShaderCompiler(void)
   4512 {
   4513     EVENT("()");
   4514 
   4515     try
   4516     {
   4517         gl::Shader::releaseCompiler();
   4518     }
   4519     catch (...)
   4520     {
   4521         return gl::error(GL_OUT_OF_MEMORY);
   4522     }
   4523 }
   4524 
   4525 void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
   4526 {
   4527     EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
   4528           target, samples, internalformat, width, height);
   4529 
   4530     try
   4531     {
   4532         gl::Context *context = gl::getNonLostContext();
   4533 
   4534         if (context)
   4535         {
   4536             if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
   4537                                                        width, height, true))
   4538             {
   4539                 return;
   4540             }
   4541 
   4542             context->setRenderbufferStorage(width, height, internalformat, samples);
   4543         }
   4544     }
   4545     catch (...)
   4546     {
   4547         return gl::error(GL_OUT_OF_MEMORY);
   4548     }
   4549 }
   4550 
   4551 void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
   4552 {
   4553     glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
   4554 }
   4555 
   4556 void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
   4557 {
   4558     EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert);
   4559 
   4560     try
   4561     {
   4562         gl::Context* context = gl::getNonLostContext();
   4563 
   4564         if (context)
   4565         {
   4566             context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
   4567         }
   4568     }
   4569     catch (...)
   4570     {
   4571         return gl::error(GL_OUT_OF_MEMORY);
   4572     }
   4573 }
   4574 
   4575 void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
   4576 {
   4577     EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
   4578 
   4579     try
   4580     {
   4581         if (condition != GL_ALL_COMPLETED_NV)
   4582         {
   4583             return gl::error(GL_INVALID_ENUM);
   4584         }
   4585 
   4586         gl::Context *context = gl::getNonLostContext();
   4587 
   4588         if (context)
   4589         {
   4590             gl::FenceNV *fenceObject = context->getFenceNV(fence);
   4591 
   4592             if (fenceObject == NULL)
   4593             {
   4594                 return gl::error(GL_INVALID_OPERATION);
   4595             }
   4596 
   4597             fenceObject->setFence(condition);
   4598         }
   4599     }
   4600     catch (...)
   4601     {
   4602         return gl::error(GL_OUT_OF_MEMORY);
   4603     }
   4604 }
   4605 
   4606 void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
   4607 {
   4608     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
   4609 
   4610     try
   4611     {
   4612         if (width < 0 || height < 0)
   4613         {
   4614             return gl::error(GL_INVALID_VALUE);
   4615         }
   4616 
   4617         gl::Context* context = gl::getNonLostContext();
   4618 
   4619         if (context)
   4620         {
   4621             context->setScissorParams(x, y, width, height);
   4622         }
   4623     }
   4624     catch (...)
   4625     {
   4626         return gl::error(GL_OUT_OF_MEMORY);
   4627     }
   4628 }
   4629 
   4630 void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
   4631 {
   4632     EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
   4633           "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
   4634           n, shaders, binaryformat, binary, length);
   4635 
   4636     try
   4637     {
   4638         // No binary shader formats are supported.
   4639         return gl::error(GL_INVALID_ENUM);
   4640     }
   4641     catch (...)
   4642     {
   4643         return gl::error(GL_OUT_OF_MEMORY);
   4644     }
   4645 }
   4646 
   4647 void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
   4648 {
   4649     EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
   4650           shader, count, string, length);
   4651 
   4652     try
   4653     {
   4654         if (count < 0)
   4655         {
   4656             return gl::error(GL_INVALID_VALUE);
   4657         }
   4658 
   4659         gl::Context *context = gl::getNonLostContext();
   4660 
   4661         if (context)
   4662         {
   4663             gl::Shader *shaderObject = context->getShader(shader);
   4664 
   4665             if (!shaderObject)
   4666             {
   4667                 if (context->getProgram(shader))
   4668                 {
   4669                     return gl::error(GL_INVALID_OPERATION);
   4670                 }
   4671                 else
   4672                 {
   4673                     return gl::error(GL_INVALID_VALUE);
   4674                 }
   4675             }
   4676 
   4677             shaderObject->setSource(count, string, length);
   4678         }
   4679     }
   4680     catch (...)
   4681     {
   4682         return gl::error(GL_OUT_OF_MEMORY);
   4683     }
   4684 }
   4685 
   4686 void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
   4687 {
   4688     glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
   4689 }
   4690 
   4691 void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
   4692 {
   4693     EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
   4694 
   4695     try
   4696     {
   4697         switch (face)
   4698         {
   4699           case GL_FRONT:
   4700           case GL_BACK:
   4701           case GL_FRONT_AND_BACK:
   4702             break;
   4703           default:
   4704             return gl::error(GL_INVALID_ENUM);
   4705         }
   4706 
   4707         switch (func)
   4708         {
   4709           case GL_NEVER:
   4710           case GL_ALWAYS:
   4711           case GL_LESS:
   4712           case GL_LEQUAL:
   4713           case GL_EQUAL:
   4714           case GL_GEQUAL:
   4715           case GL_GREATER:
   4716           case GL_NOTEQUAL:
   4717             break;
   4718           default:
   4719             return gl::error(GL_INVALID_ENUM);
   4720         }
   4721 
   4722         gl::Context *context = gl::getNonLostContext();
   4723 
   4724         if (context)
   4725         {
   4726             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
   4727             {
   4728                 context->setStencilParams(func, ref, mask);
   4729             }
   4730 
   4731             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
   4732             {
   4733                 context->setStencilBackParams(func, ref, mask);
   4734             }
   4735         }
   4736     }
   4737     catch (...)
   4738     {
   4739         return gl::error(GL_OUT_OF_MEMORY);
   4740     }
   4741 }
   4742 
   4743 void __stdcall glStencilMask(GLuint mask)
   4744 {
   4745     glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
   4746 }
   4747 
   4748 void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
   4749 {
   4750     EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
   4751 
   4752     try
   4753     {
   4754         switch (face)
   4755         {
   4756           case GL_FRONT:
   4757           case GL_BACK:
   4758           case GL_FRONT_AND_BACK:
   4759             break;
   4760           default:
   4761             return gl::error(GL_INVALID_ENUM);
   4762         }
   4763 
   4764         gl::Context *context = gl::getNonLostContext();
   4765 
   4766         if (context)
   4767         {
   4768             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
   4769             {
   4770                 context->setStencilWritemask(mask);
   4771             }
   4772 
   4773             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
   4774             {
   4775                 context->setStencilBackWritemask(mask);
   4776             }
   4777         }
   4778     }
   4779     catch (...)
   4780     {
   4781         return gl::error(GL_OUT_OF_MEMORY);
   4782     }
   4783 }
   4784 
   4785 void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
   4786 {
   4787     glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
   4788 }
   4789 
   4790 void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
   4791 {
   4792     EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
   4793           face, fail, zfail, zpass);
   4794 
   4795     try
   4796     {
   4797         switch (face)
   4798         {
   4799           case GL_FRONT:
   4800           case GL_BACK:
   4801           case GL_FRONT_AND_BACK:
   4802             break;
   4803           default:
   4804             return gl::error(GL_INVALID_ENUM);
   4805         }
   4806 
   4807         switch (fail)
   4808         {
   4809           case GL_ZERO:
   4810           case GL_KEEP:
   4811           case GL_REPLACE:
   4812           case GL_INCR:
   4813           case GL_DECR:
   4814           case GL_INVERT:
   4815           case GL_INCR_WRAP:
   4816           case GL_DECR_WRAP:
   4817             break;
   4818           default:
   4819             return gl::error(GL_INVALID_ENUM);
   4820         }
   4821 
   4822         switch (zfail)
   4823         {
   4824           case GL_ZERO:
   4825           case GL_KEEP:
   4826           case GL_REPLACE:
   4827           case GL_INCR:
   4828           case GL_DECR:
   4829           case GL_INVERT:
   4830           case GL_INCR_WRAP:
   4831           case GL_DECR_WRAP:
   4832             break;
   4833           default:
   4834             return gl::error(GL_INVALID_ENUM);
   4835         }
   4836 
   4837         switch (zpass)
   4838         {
   4839           case GL_ZERO:
   4840           case GL_KEEP:
   4841           case GL_REPLACE:
   4842           case GL_INCR:
   4843           case GL_DECR:
   4844           case GL_INVERT:
   4845           case GL_INCR_WRAP:
   4846           case GL_DECR_WRAP:
   4847             break;
   4848           default:
   4849             return gl::error(GL_INVALID_ENUM);
   4850         }
   4851 
   4852         gl::Context *context = gl::getNonLostContext();
   4853 
   4854         if (context)
   4855         {
   4856             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
   4857             {
   4858                 context->setStencilOperations(fail, zfail, zpass);
   4859             }
   4860 
   4861             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
   4862             {
   4863                 context->setStencilBackOperations(fail, zfail, zpass);
   4864             }
   4865         }
   4866     }
   4867     catch (...)
   4868     {
   4869         return gl::error(GL_OUT_OF_MEMORY);
   4870     }
   4871 }
   4872 
   4873 GLboolean __stdcall glTestFenceNV(GLuint fence)
   4874 {
   4875     EVENT("(GLuint fence = %d)", fence);
   4876 
   4877     try
   4878     {
   4879         gl::Context *context = gl::getNonLostContext();
   4880 
   4881         if (context)
   4882         {
   4883             gl::FenceNV *fenceObject = context->getFenceNV(fence);
   4884 
   4885             if (fenceObject == NULL)
   4886             {
   4887                 return gl::error(GL_INVALID_OPERATION, GL_TRUE);
   4888             }
   4889 
   4890             if (fenceObject->isFence() != GL_TRUE)
   4891             {
   4892                 return gl::error(GL_INVALID_OPERATION, GL_TRUE);
   4893             }
   4894 
   4895             return fenceObject->testFence();
   4896         }
   4897     }
   4898     catch (...)
   4899     {
   4900         gl::error(GL_OUT_OF_MEMORY);
   4901     }
   4902 
   4903     return GL_TRUE;
   4904 }
   4905 
   4906 void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
   4907                             GLint border, GLenum format, GLenum type, const GLvoid* pixels)
   4908 {
   4909     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
   4910           "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
   4911           target, level, internalformat, width, height, border, format, type, pixels);
   4912 
   4913     try
   4914     {
   4915         gl::Context *context = gl::getNonLostContext();
   4916 
   4917         if (context)
   4918         {
   4919             if (context->getClientVersion() < 3 &&
   4920                 !ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
   4921                                                0, 0, width, height, border, format, type, pixels))
   4922             {
   4923                 return;
   4924             }
   4925 
   4926             if (context->getClientVersion() >= 3 &&
   4927                 !ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
   4928                                                0, 0, 0, width, height, 1, border, format, type, pixels))
   4929             {
   4930                 return;
   4931             }
   4932 
   4933             switch (target)
   4934             {
   4935               case GL_TEXTURE_2D:
   4936                 {
   4937                     gl::Texture2D *texture = context->getTexture2D();
   4938                     texture->setImage(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
   4939                 }
   4940                 break;
   4941               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   4942                 {
   4943                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
   4944                     texture->setImagePosX(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
   4945                 }
   4946                 break;
   4947               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   4948                 {
   4949                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
   4950                     texture->setImageNegX(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
   4951                 }
   4952                 break;
   4953               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   4954                 {
   4955                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
   4956                     texture->setImagePosY(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
   4957                 }
   4958                 break;
   4959               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   4960                 {
   4961                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
   4962                     texture->setImageNegY(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
   4963                 }
   4964                 break;
   4965               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   4966                 {
   4967                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
   4968                     texture->setImagePosZ(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
   4969                 }
   4970                 break;
   4971               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   4972                 {
   4973                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
   4974                     texture->setImageNegZ(level, width, height, internalformat, format, type, context->getUnpackState(), pixels);
   4975                 }
   4976                 break;
   4977               default: UNREACHABLE();
   4978             }
   4979         }
   4980     }
   4981     catch (...)
   4982     {
   4983         return gl::error(GL_OUT_OF_MEMORY);
   4984     }
   4985 }
   4986 
   4987 void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
   4988 {
   4989     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
   4990 
   4991     try
   4992     {
   4993         gl::Context *context = gl::getNonLostContext();
   4994 
   4995         if (context)
   4996         {
   4997             if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
   4998             {
   4999                 return;
   5000             }
   5001 
   5002             gl::Texture *texture = context->getTargetTexture(target);
   5003 
   5004             if (!texture)
   5005             {
   5006                 return gl::error(GL_INVALID_ENUM);
   5007             }
   5008 
   5009             switch (pname)
   5010             {
   5011               case GL_TEXTURE_WRAP_S:               texture->setWrapS(gl::uiround<GLenum>(param));       break;
   5012               case GL_TEXTURE_WRAP_T:               texture->setWrapT(gl::uiround<GLenum>(param));       break;
   5013               case GL_TEXTURE_WRAP_R:               texture->setWrapR(gl::uiround<GLenum>(param));       break;
   5014               case GL_TEXTURE_MIN_FILTER:           texture->setMinFilter(gl::uiround<GLenum>(param));   break;
   5015               case GL_TEXTURE_MAG_FILTER:           texture->setMagFilter(gl::uiround<GLenum>(param));   break;
   5016               case GL_TEXTURE_USAGE_ANGLE:          texture->setUsage(gl::uiround<GLenum>(param));       break;
   5017               case GL_TEXTURE_MAX_ANISOTROPY_EXT:   texture->setMaxAnisotropy(param, context->getTextureMaxAnisotropy()); break;
   5018               case GL_TEXTURE_COMPARE_MODE:         texture->setCompareMode(gl::uiround<GLenum>(param)); break;
   5019               case GL_TEXTURE_COMPARE_FUNC:         texture->setCompareFunc(gl::uiround<GLenum>(param)); break;
   5020               case GL_TEXTURE_SWIZZLE_R:            texture->setSwizzleRed(gl::uiround<GLenum>(param));   break;
   5021               case GL_TEXTURE_SWIZZLE_G:            texture->setSwizzleGreen(gl::uiround<GLenum>(param)); break;
   5022               case GL_TEXTURE_SWIZZLE_B:            texture->setSwizzleBlue(gl::uiround<GLenum>(param));  break;
   5023               case GL_TEXTURE_SWIZZLE_A:            texture->setSwizzleAlpha(gl::uiround<GLenum>(param)); break;
   5024               case GL_TEXTURE_BASE_LEVEL:           texture->setBaseLevel(gl::iround<GLint>(param));      break;
   5025               case GL_TEXTURE_MAX_LEVEL:            texture->setMaxLevel(gl::iround<GLint>(param));       break;
   5026               case GL_TEXTURE_MIN_LOD:              texture->setMinLod(param);                            break;
   5027               case GL_TEXTURE_MAX_LOD:              texture->setMaxLod(param);                            break;
   5028               default: UNREACHABLE(); break;
   5029             }
   5030         }
   5031     }
   5032     catch (...)
   5033     {
   5034         return gl::error(GL_OUT_OF_MEMORY);
   5035     }
   5036 }
   5037 
   5038 void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
   5039 {
   5040     glTexParameterf(target, pname, (GLfloat)*params);
   5041 }
   5042 
   5043 void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
   5044 {
   5045     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
   5046 
   5047     try
   5048     {
   5049         gl::Context *context = gl::getNonLostContext();
   5050 
   5051         if (context)
   5052         {
   5053             if (!ValidateTexParamParameters(context, pname, param))
   5054             {
   5055                 return;
   5056             }
   5057 
   5058             gl::Texture *texture = context->getTargetTexture(target);
   5059 
   5060             if (!texture)
   5061             {
   5062                 return gl::error(GL_INVALID_ENUM);
   5063             }
   5064 
   5065             switch (pname)
   5066             {
   5067               case GL_TEXTURE_WRAP_S:               texture->setWrapS((GLenum)param);       break;
   5068               case GL_TEXTURE_WRAP_T:               texture->setWrapT((GLenum)param);       break;
   5069               case GL_TEXTURE_WRAP_R:               texture->setWrapR((GLenum)param);       break;
   5070               case GL_TEXTURE_MIN_FILTER:           texture->setMinFilter((GLenum)param);   break;
   5071               case GL_TEXTURE_MAG_FILTER:           texture->setMagFilter((GLenum)param);   break;
   5072               case GL_TEXTURE_USAGE_ANGLE:          texture->setUsage((GLenum)param);       break;
   5073               case GL_TEXTURE_MAX_ANISOTROPY_EXT:   texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()); break;
   5074               case GL_TEXTURE_COMPARE_MODE:         texture->setCompareMode((GLenum)param); break;
   5075               case GL_TEXTURE_COMPARE_FUNC:         texture->setCompareFunc((GLenum)param); break;
   5076               case GL_TEXTURE_SWIZZLE_R:            texture->setSwizzleRed((GLenum)param);   break;
   5077               case GL_TEXTURE_SWIZZLE_G:            texture->setSwizzleGreen((GLenum)param); break;
   5078               case GL_TEXTURE_SWIZZLE_B:            texture->setSwizzleBlue((GLenum)param);  break;
   5079               case GL_TEXTURE_SWIZZLE_A:            texture->setSwizzleAlpha((GLenum)param); break;
   5080               case GL_TEXTURE_BASE_LEVEL:           texture->setBaseLevel(param);            break;
   5081               case GL_TEXTURE_MAX_LEVEL:            texture->setMaxLevel(param);             break;
   5082               case GL_TEXTURE_MIN_LOD:              texture->setMinLod((GLfloat)param);      break;
   5083               case GL_TEXTURE_MAX_LOD:              texture->setMaxLod((GLfloat)param);      break;
   5084               default: UNREACHABLE(); break;
   5085             }
   5086         }
   5087     }
   5088     catch (...)
   5089     {
   5090         return gl::error(GL_OUT_OF_MEMORY);
   5091     }
   5092 }
   5093 
   5094 void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
   5095 {
   5096     glTexParameteri(target, pname, *params);
   5097 }
   5098 
   5099 void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
   5100 {
   5101     EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
   5102            target, levels, internalformat, width, height);
   5103 
   5104     try
   5105     {
   5106         gl::Context *context = gl::getNonLostContext();
   5107 
   5108         if (context)
   5109         {
   5110             if (context->getClientVersion() < 3 &&
   5111                 !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, height))
   5112             {
   5113                 return;
   5114             }
   5115 
   5116             if (context->getClientVersion() >= 3 &&
   5117                 !ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
   5118             {
   5119                 return;
   5120             }
   5121 
   5122             switch (target)
   5123             {
   5124               case GL_TEXTURE_2D:
   5125                 {
   5126                     gl::Texture2D *texture2d = context->getTexture2D();
   5127                     texture2d->storage(levels, internalformat, width, height);
   5128                 }
   5129                 break;
   5130 
   5131               case GL_TEXTURE_CUBE_MAP:
   5132                 {
   5133                     gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
   5134                     textureCube->storage(levels, internalformat, width);
   5135                 }
   5136                 break;
   5137 
   5138               default:
   5139                 return gl::error(GL_INVALID_ENUM);
   5140             }
   5141         }
   5142     }
   5143     catch (...)
   5144     {
   5145         return gl::error(GL_OUT_OF_MEMORY);
   5146     }
   5147 }
   5148 
   5149 void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
   5150                                GLenum format, GLenum type, const GLvoid* pixels)
   5151 {
   5152     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
   5153           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
   5154           "const GLvoid* pixels = 0x%0.8p)",
   5155            target, level, xoffset, yoffset, width, height, format, type, pixels);
   5156 
   5157     try
   5158     {
   5159         gl::Context *context = gl::getNonLostContext();
   5160 
   5161         if (context)
   5162         {
   5163             if (context->getClientVersion() < 3 &&
   5164                 !ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true,
   5165                                                xoffset, yoffset, width, height, 0, format, type, pixels))
   5166             {
   5167                 return;
   5168             }
   5169 
   5170             if (context->getClientVersion() >= 3 &&
   5171                 !ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
   5172                                                xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels))
   5173             {
   5174                 return;
   5175             }
   5176 
   5177             // Zero sized uploads are valid but no-ops
   5178             if (width == 0 || height == 0)
   5179             {
   5180                 return;
   5181             }
   5182 
   5183             switch (target)
   5184             {
   5185               case GL_TEXTURE_2D:
   5186                 {
   5187                     gl::Texture2D *texture = context->getTexture2D();
   5188                     texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackState(), pixels);
   5189                 }
   5190                 break;
   5191 
   5192               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   5193               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   5194               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   5195               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   5196               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   5197               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   5198                 {
   5199                     gl::TextureCubeMap *texture = context->getTextureCubeMap();
   5200                     texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackState(), pixels);
   5201                 }
   5202                 break;
   5203 
   5204               default:
   5205                 UNREACHABLE();
   5206             }
   5207         }
   5208     }
   5209     catch (...)
   5210     {
   5211         return gl::error(GL_OUT_OF_MEMORY);
   5212     }
   5213 }
   5214 
   5215 void __stdcall glUniform1f(GLint location, GLfloat x)
   5216 {
   5217     glUniform1fv(location, 1, &x);
   5218 }
   5219 
   5220 void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
   5221 {
   5222     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
   5223 
   5224     try
   5225     {
   5226         gl::Context *context = gl::getNonLostContext();
   5227 
   5228         if (context)
   5229         {
   5230             if (!ValidateUniform(context, GL_FLOAT, location, count))
   5231             {
   5232                 return;
   5233             }
   5234 
   5235             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5236             programBinary->setUniform1fv(location, count, v);
   5237         }
   5238     }
   5239     catch (...)
   5240     {
   5241         return gl::error(GL_OUT_OF_MEMORY);
   5242     }
   5243 }
   5244 
   5245 void __stdcall glUniform1i(GLint location, GLint x)
   5246 {
   5247     glUniform1iv(location, 1, &x);
   5248 }
   5249 
   5250 void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
   5251 {
   5252     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
   5253 
   5254     try
   5255     {
   5256         gl::Context *context = gl::getNonLostContext();
   5257 
   5258         if (context)
   5259         {
   5260             if (!ValidateUniform(context, GL_INT, location, count))
   5261             {
   5262                 return;
   5263             }
   5264 
   5265             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5266             programBinary->setUniform1iv(location, count, v);
   5267         }
   5268     }
   5269     catch (...)
   5270     {
   5271         return gl::error(GL_OUT_OF_MEMORY);
   5272     }
   5273 }
   5274 
   5275 void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
   5276 {
   5277     GLfloat xy[2] = {x, y};
   5278 
   5279     glUniform2fv(location, 1, xy);
   5280 }
   5281 
   5282 void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
   5283 {
   5284     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
   5285 
   5286     try
   5287     {
   5288         gl::Context *context = gl::getNonLostContext();
   5289 
   5290         if (context)
   5291         {
   5292             if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count))
   5293             {
   5294                 return;
   5295             }
   5296 
   5297             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5298             programBinary->setUniform2fv(location, count, v);
   5299         }
   5300     }
   5301     catch (...)
   5302     {
   5303         return gl::error(GL_OUT_OF_MEMORY);
   5304     }
   5305 }
   5306 
   5307 void __stdcall glUniform2i(GLint location, GLint x, GLint y)
   5308 {
   5309     GLint xy[2] = {x, y};
   5310 
   5311     glUniform2iv(location, 1, xy);
   5312 }
   5313 
   5314 void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
   5315 {
   5316     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
   5317 
   5318     try
   5319     {
   5320         gl::Context *context = gl::getNonLostContext();
   5321 
   5322         if (context)
   5323         {
   5324             if (!ValidateUniform(context, GL_INT_VEC2, location, count))
   5325             {
   5326                 return;
   5327             }
   5328 
   5329             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5330             programBinary->setUniform2iv(location, count, v);
   5331         }
   5332     }
   5333     catch (...)
   5334     {
   5335         return gl::error(GL_OUT_OF_MEMORY);
   5336     }
   5337 }
   5338 
   5339 void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
   5340 {
   5341     GLfloat xyz[3] = {x, y, z};
   5342 
   5343     glUniform3fv(location, 1, xyz);
   5344 }
   5345 
   5346 void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
   5347 {
   5348     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
   5349 
   5350     try
   5351     {
   5352         gl::Context *context = gl::getNonLostContext();
   5353 
   5354         if (context)
   5355         {
   5356             if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count))
   5357             {
   5358                 return;
   5359             }
   5360 
   5361             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5362             programBinary->setUniform3fv(location, count, v);
   5363         }
   5364     }
   5365     catch (...)
   5366     {
   5367         return gl::error(GL_OUT_OF_MEMORY);
   5368     }
   5369 }
   5370 
   5371 void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
   5372 {
   5373     GLint xyz[3] = {x, y, z};
   5374 
   5375     glUniform3iv(location, 1, xyz);
   5376 }
   5377 
   5378 void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
   5379 {
   5380     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
   5381 
   5382     try
   5383     {
   5384         gl::Context *context = gl::getNonLostContext();
   5385 
   5386         if (context)
   5387         {
   5388             if (!ValidateUniform(context, GL_INT_VEC3, location, count))
   5389             {
   5390                 return;
   5391             }
   5392 
   5393             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5394             programBinary->setUniform3iv(location, count, v);
   5395         }
   5396     }
   5397     catch (...)
   5398     {
   5399         return gl::error(GL_OUT_OF_MEMORY);
   5400     }
   5401 }
   5402 
   5403 void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
   5404 {
   5405     GLfloat xyzw[4] = {x, y, z, w};
   5406 
   5407     glUniform4fv(location, 1, xyzw);
   5408 }
   5409 
   5410 void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
   5411 {
   5412     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
   5413 
   5414     try
   5415     {
   5416         gl::Context *context = gl::getNonLostContext();
   5417 
   5418         if (context)
   5419         {
   5420             if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count))
   5421             {
   5422                 return;
   5423             }
   5424 
   5425             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5426             programBinary->setUniform4fv(location, count, v);
   5427         }
   5428     }
   5429     catch (...)
   5430     {
   5431         return gl::error(GL_OUT_OF_MEMORY);
   5432     }
   5433 }
   5434 
   5435 void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
   5436 {
   5437     GLint xyzw[4] = {x, y, z, w};
   5438 
   5439     glUniform4iv(location, 1, xyzw);
   5440 }
   5441 
   5442 void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
   5443 {
   5444     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
   5445 
   5446     try
   5447     {
   5448         gl::Context *context = gl::getNonLostContext();
   5449 
   5450         if (context)
   5451         {
   5452             if (!ValidateUniform(context, GL_INT_VEC4, location, count))
   5453             {
   5454                 return;
   5455             }
   5456 
   5457             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5458             programBinary->setUniform4iv(location, count, v);
   5459         }
   5460     }
   5461     catch (...)
   5462     {
   5463         return gl::error(GL_OUT_OF_MEMORY);
   5464     }
   5465 }
   5466 
   5467 void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   5468 {
   5469     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
   5470           location, count, transpose, value);
   5471 
   5472     try
   5473     {
   5474         gl::Context *context = gl::getNonLostContext();
   5475 
   5476         if (context)
   5477         {
   5478             if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose))
   5479             {
   5480                 return;
   5481             }
   5482 
   5483             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5484             programBinary->setUniformMatrix2fv(location, count, transpose, value);
   5485         }
   5486     }
   5487     catch (...)
   5488     {
   5489         return gl::error(GL_OUT_OF_MEMORY);
   5490     }
   5491 }
   5492 
   5493 void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   5494 {
   5495     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
   5496           location, count, transpose, value);
   5497 
   5498     try
   5499     {
   5500         gl::Context *context = gl::getNonLostContext();
   5501 
   5502         if (context)
   5503         {
   5504             if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose))
   5505             {
   5506                 return;
   5507             }
   5508 
   5509             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5510             programBinary->setUniformMatrix3fv(location, count, transpose, value);
   5511         }
   5512     }
   5513     catch (...)
   5514     {
   5515         return gl::error(GL_OUT_OF_MEMORY);
   5516     }
   5517 }
   5518 
   5519 void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   5520 {
   5521     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
   5522           location, count, transpose, value);
   5523 
   5524     try
   5525     {
   5526         gl::Context *context = gl::getNonLostContext();
   5527 
   5528         if (context)
   5529         {
   5530             if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose))
   5531             {
   5532                 return;
   5533             }
   5534 
   5535             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   5536             programBinary->setUniformMatrix4fv(location, count, transpose, value);
   5537         }
   5538     }
   5539     catch (...)
   5540     {
   5541         return gl::error(GL_OUT_OF_MEMORY);
   5542     }
   5543 }
   5544 
   5545 void __stdcall glUseProgram(GLuint program)
   5546 {
   5547     EVENT("(GLuint program = %d)", program);
   5548 
   5549     try
   5550     {
   5551         gl::Context *context = gl::getNonLostContext();
   5552 
   5553         if (context)
   5554         {
   5555             gl::Program *programObject = context->getProgram(program);
   5556 
   5557             if (!programObject && program != 0)
   5558             {
   5559                 if (context->getShader(program))
   5560                 {
   5561                     return gl::error(GL_INVALID_OPERATION);
   5562                 }
   5563                 else
   5564                 {
   5565                     return gl::error(GL_INVALID_VALUE);
   5566                 }
   5567             }
   5568 
   5569             if (program != 0 && !programObject->isLinked())
   5570             {
   5571                 return gl::error(GL_INVALID_OPERATION);
   5572             }
   5573 
   5574             context->useProgram(program);
   5575         }
   5576     }
   5577     catch (...)
   5578     {
   5579         return gl::error(GL_OUT_OF_MEMORY);
   5580     }
   5581 }
   5582 
   5583 void __stdcall glValidateProgram(GLuint program)
   5584 {
   5585     EVENT("(GLuint program = %d)", program);
   5586 
   5587     try
   5588     {
   5589         gl::Context *context = gl::getNonLostContext();
   5590 
   5591         if (context)
   5592         {
   5593             gl::Program *programObject = context->getProgram(program);
   5594 
   5595             if (!programObject)
   5596             {
   5597                 if (context->getShader(program))
   5598                 {
   5599                     return gl::error(GL_INVALID_OPERATION);
   5600                 }
   5601                 else
   5602                 {
   5603                     return gl::error(GL_INVALID_VALUE);
   5604                 }
   5605             }
   5606 
   5607             programObject->validate();
   5608         }
   5609     }
   5610     catch (...)
   5611     {
   5612         return gl::error(GL_OUT_OF_MEMORY);
   5613     }
   5614 }
   5615 
   5616 void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
   5617 {
   5618     EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
   5619 
   5620     try
   5621     {
   5622         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5623         {
   5624             return gl::error(GL_INVALID_VALUE);
   5625         }
   5626 
   5627         gl::Context *context = gl::getNonLostContext();
   5628 
   5629         if (context)
   5630         {
   5631             GLfloat vals[4] = { x, 0, 0, 1 };
   5632             context->setVertexAttribf(index, vals);
   5633         }
   5634     }
   5635     catch (...)
   5636     {
   5637         return gl::error(GL_OUT_OF_MEMORY);
   5638     }
   5639 }
   5640 
   5641 void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
   5642 {
   5643     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
   5644 
   5645     try
   5646     {
   5647         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5648         {
   5649             return gl::error(GL_INVALID_VALUE);
   5650         }
   5651 
   5652         gl::Context *context = gl::getNonLostContext();
   5653 
   5654         if (context)
   5655         {
   5656             GLfloat vals[4] = { values[0], 0, 0, 1 };
   5657             context->setVertexAttribf(index, vals);
   5658         }
   5659     }
   5660     catch (...)
   5661     {
   5662         return gl::error(GL_OUT_OF_MEMORY);
   5663     }
   5664 }
   5665 
   5666 void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
   5667 {
   5668     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
   5669 
   5670     try
   5671     {
   5672         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5673         {
   5674             return gl::error(GL_INVALID_VALUE);
   5675         }
   5676 
   5677         gl::Context *context = gl::getNonLostContext();
   5678 
   5679         if (context)
   5680         {
   5681             GLfloat vals[4] = { x, y, 0, 1 };
   5682             context->setVertexAttribf(index, vals);
   5683         }
   5684     }
   5685     catch (...)
   5686     {
   5687         return gl::error(GL_OUT_OF_MEMORY);
   5688     }
   5689 }
   5690 
   5691 void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
   5692 {
   5693     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
   5694 
   5695     try
   5696     {
   5697         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5698         {
   5699             return gl::error(GL_INVALID_VALUE);
   5700         }
   5701 
   5702         gl::Context *context = gl::getNonLostContext();
   5703 
   5704         if (context)
   5705         {
   5706             GLfloat vals[4] = { values[0], values[1], 0, 1 };
   5707             context->setVertexAttribf(index, vals);
   5708         }
   5709     }
   5710     catch (...)
   5711     {
   5712         return gl::error(GL_OUT_OF_MEMORY);
   5713     }
   5714 }
   5715 
   5716 void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
   5717 {
   5718     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
   5719 
   5720     try
   5721     {
   5722         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5723         {
   5724             return gl::error(GL_INVALID_VALUE);
   5725         }
   5726 
   5727         gl::Context *context = gl::getNonLostContext();
   5728 
   5729         if (context)
   5730         {
   5731             GLfloat vals[4] = { x, y, z, 1 };
   5732             context->setVertexAttribf(index, vals);
   5733         }
   5734     }
   5735     catch (...)
   5736     {
   5737         return gl::error(GL_OUT_OF_MEMORY);
   5738     }
   5739 }
   5740 
   5741 void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
   5742 {
   5743     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
   5744 
   5745     try
   5746     {
   5747         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5748         {
   5749             return gl::error(GL_INVALID_VALUE);
   5750         }
   5751 
   5752         gl::Context *context = gl::getNonLostContext();
   5753 
   5754         if (context)
   5755         {
   5756             GLfloat vals[4] = { values[0], values[1], values[2], 1 };
   5757             context->setVertexAttribf(index, vals);
   5758         }
   5759     }
   5760     catch (...)
   5761     {
   5762         return gl::error(GL_OUT_OF_MEMORY);
   5763     }
   5764 }
   5765 
   5766 void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
   5767 {
   5768     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
   5769 
   5770     try
   5771     {
   5772         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5773         {
   5774             return gl::error(GL_INVALID_VALUE);
   5775         }
   5776 
   5777         gl::Context *context = gl::getNonLostContext();
   5778 
   5779         if (context)
   5780         {
   5781             GLfloat vals[4] = { x, y, z, w };
   5782             context->setVertexAttribf(index, vals);
   5783         }
   5784     }
   5785     catch (...)
   5786     {
   5787         return gl::error(GL_OUT_OF_MEMORY);
   5788     }
   5789 }
   5790 
   5791 void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
   5792 {
   5793     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
   5794 
   5795     try
   5796     {
   5797         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5798         {
   5799             return gl::error(GL_INVALID_VALUE);
   5800         }
   5801 
   5802         gl::Context *context = gl::getNonLostContext();
   5803 
   5804         if (context)
   5805         {
   5806             context->setVertexAttribf(index, values);
   5807         }
   5808     }
   5809     catch (...)
   5810     {
   5811         return gl::error(GL_OUT_OF_MEMORY);
   5812     }
   5813 }
   5814 
   5815 void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
   5816 {
   5817     EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
   5818 
   5819     try
   5820     {
   5821         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5822         {
   5823             return gl::error(GL_INVALID_VALUE);
   5824         }
   5825 
   5826         gl::Context *context = gl::getNonLostContext();
   5827 
   5828         if (context)
   5829         {
   5830             context->setVertexAttribDivisor(index, divisor);
   5831         }
   5832     }
   5833     catch (...)
   5834     {
   5835         return gl::error(GL_OUT_OF_MEMORY);
   5836     }
   5837 }
   5838 
   5839 void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
   5840 {
   5841     EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
   5842           "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
   5843           index, size, type, normalized, stride, ptr);
   5844 
   5845     try
   5846     {
   5847         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5848         {
   5849             return gl::error(GL_INVALID_VALUE);
   5850         }
   5851 
   5852         if (size < 1 || size > 4)
   5853         {
   5854             return gl::error(GL_INVALID_VALUE);
   5855         }
   5856 
   5857         gl::Context *context = gl::getNonLostContext();
   5858 
   5859         switch (type)
   5860         {
   5861           case GL_BYTE:
   5862           case GL_UNSIGNED_BYTE:
   5863           case GL_SHORT:
   5864           case GL_UNSIGNED_SHORT:
   5865           case GL_FIXED:
   5866           case GL_FLOAT:
   5867             break;
   5868           case GL_HALF_FLOAT:
   5869           case GL_INT:
   5870           case GL_UNSIGNED_INT:
   5871           case GL_INT_2_10_10_10_REV:
   5872           case GL_UNSIGNED_INT_2_10_10_10_REV:
   5873             if (context && context->getClientVersion() < 3)
   5874             {
   5875                 return gl::error(GL_INVALID_ENUM);
   5876             }
   5877             else
   5878             {
   5879                 break;
   5880             }
   5881           default:
   5882             return gl::error(GL_INVALID_ENUM);
   5883         }
   5884 
   5885         if (stride < 0)
   5886         {
   5887             return gl::error(GL_INVALID_VALUE);
   5888         }
   5889 
   5890         if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
   5891         {
   5892             return gl::error(GL_INVALID_OPERATION);
   5893         }
   5894 
   5895         if (context)
   5896         {
   5897             // [OpenGL ES 3.0.2] Section 2.8 page 24:
   5898             // An INVALID_OPERATION error is generated when a non-zero vertex array object
   5899             // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
   5900             // and the pointer argument is not NULL.
   5901             if (context->getVertexArrayHandle() != 0 && context->getArrayBufferHandle() == 0 && ptr != NULL)
   5902             {
   5903                 return gl::error(GL_INVALID_OPERATION);
   5904             }
   5905 
   5906             context->setVertexAttribState(index, context->getArrayBuffer(), size, type,
   5907                                           normalized == GL_TRUE, false, stride, ptr);
   5908         }
   5909     }
   5910     catch (...)
   5911     {
   5912         return gl::error(GL_OUT_OF_MEMORY);
   5913     }
   5914 }
   5915 
   5916 void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
   5917 {
   5918     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
   5919 
   5920     try
   5921     {
   5922         if (width < 0 || height < 0)
   5923         {
   5924             return gl::error(GL_INVALID_VALUE);
   5925         }
   5926 
   5927         gl::Context *context = gl::getNonLostContext();
   5928 
   5929         if (context)
   5930         {
   5931             context->setViewportParams(x, y, width, height);
   5932         }
   5933     }
   5934     catch (...)
   5935     {
   5936         return gl::error(GL_OUT_OF_MEMORY);
   5937     }
   5938 }
   5939 
   5940 // OpenGL ES 3.0 functions
   5941 
   5942 void __stdcall glReadBuffer(GLenum mode)
   5943 {
   5944     EVENT("(GLenum mode = 0x%X)", mode);
   5945 
   5946     try
   5947     {
   5948         gl::Context *context = gl::getNonLostContext();
   5949 
   5950         if (context)
   5951         {
   5952             if (context->getClientVersion() < 3)
   5953             {
   5954                 return gl::error(GL_INVALID_OPERATION);
   5955             }
   5956 
   5957             // glReadBuffer
   5958             UNIMPLEMENTED();
   5959         }
   5960     }
   5961     catch (...)
   5962     {
   5963         return gl::error(GL_OUT_OF_MEMORY);
   5964     }
   5965 }
   5966 
   5967 void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices)
   5968 {
   5969     EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, "
   5970           "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices);
   5971 
   5972     try
   5973     {
   5974         gl::Context *context = gl::getNonLostContext();
   5975 
   5976         if (context)
   5977         {
   5978             if (context->getClientVersion() < 3)
   5979             {
   5980                 return gl::error(GL_INVALID_OPERATION);
   5981             }
   5982 
   5983             // glDrawRangeElements
   5984             UNIMPLEMENTED();
   5985         }
   5986     }
   5987     catch (...)
   5988     {
   5989         return gl::error(GL_OUT_OF_MEMORY);
   5990     }
   5991 }
   5992 
   5993 void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
   5994 {
   5995     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
   5996           "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, "
   5997           "GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
   5998           target, level, internalformat, width, height, depth, border, format, type, pixels);
   5999 
   6000     try
   6001     {
   6002         gl::Context *context = gl::getNonLostContext();
   6003 
   6004         if (context)
   6005         {
   6006             if (context->getClientVersion() < 3)
   6007             {
   6008                 return gl::error(GL_INVALID_OPERATION);
   6009             }
   6010 
   6011             // validateES3TexImageFormat sets the error code if there is an error
   6012             if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
   6013                                                0, 0, 0, width, height, depth, border, format, type, pixels))
   6014             {
   6015                 return;
   6016             }
   6017 
   6018             switch(target)
   6019             {
   6020               case GL_TEXTURE_3D:
   6021                 {
   6022                     gl::Texture3D *texture = context->getTexture3D();
   6023                     texture->setImage(level, width, height, depth, internalformat, format, type, context->getUnpackState(), pixels);
   6024                 }
   6025                 break;
   6026 
   6027               case GL_TEXTURE_2D_ARRAY:
   6028                 {
   6029                     gl::Texture2DArray *texture = context->getTexture2DArray();
   6030                     texture->setImage(level, width, height, depth, internalformat, format, type, context->getUnpackState(), pixels);
   6031                 }
   6032                 break;
   6033 
   6034               default:
   6035                 return gl::error(GL_INVALID_ENUM);
   6036             }
   6037         }
   6038     }
   6039     catch (...)
   6040     {
   6041         return gl::error(GL_OUT_OF_MEMORY);
   6042     }
   6043 }
   6044 
   6045 void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
   6046 {
   6047     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
   6048           "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
   6049           "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
   6050           target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
   6051 
   6052     try
   6053     {
   6054         gl::Context *context = gl::getNonLostContext();
   6055 
   6056         if (context)
   6057         {
   6058             if (context->getClientVersion() < 3)
   6059             {
   6060                 return gl::error(GL_INVALID_OPERATION);
   6061             }
   6062 
   6063             // validateES3TexImageFormat sets the error code if there is an error
   6064             if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
   6065                                                xoffset, yoffset, zoffset, width, height, depth, 0,
   6066                                                format, type, pixels))
   6067             {
   6068                 return;
   6069             }
   6070 
   6071             // Zero sized uploads are valid but no-ops
   6072             if (width == 0 || height == 0 || depth == 0)
   6073             {
   6074                 return;
   6075             }
   6076 
   6077             switch(target)
   6078             {
   6079               case GL_TEXTURE_3D:
   6080                 {
   6081                     gl::Texture3D *texture = context->getTexture3D();
   6082                     texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackState(), pixels);
   6083                 }
   6084                 break;
   6085 
   6086               case GL_TEXTURE_2D_ARRAY:
   6087                 {
   6088                     gl::Texture2DArray *texture = context->getTexture2DArray();
   6089                     texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackState(), pixels);
   6090                 }
   6091                 break;
   6092 
   6093               default:
   6094                 return gl::error(GL_INVALID_ENUM);
   6095             }
   6096         }
   6097     }
   6098     catch (...)
   6099     {
   6100         return gl::error(GL_OUT_OF_MEMORY);
   6101     }
   6102 }
   6103 
   6104 void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
   6105 {
   6106     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
   6107           "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
   6108           target, level, xoffset, yoffset, zoffset, x, y, width, height);
   6109 
   6110     try
   6111     {
   6112         gl::Context *context = gl::getNonLostContext();
   6113 
   6114         if (context)
   6115         {
   6116             if (context->getClientVersion() < 3)
   6117             {
   6118                 return gl::error(GL_INVALID_OPERATION);
   6119             }
   6120 
   6121             if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset,
   6122                                                    x, y, width, height, 0))
   6123             {
   6124                 return;
   6125             }
   6126 
   6127             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
   6128             gl::Texture *texture = NULL;
   6129             switch (target)
   6130             {
   6131               case GL_TEXTURE_3D:
   6132                 texture = context->getTexture3D();
   6133                 break;
   6134 
   6135               case GL_TEXTURE_2D_ARRAY:
   6136                 texture = context->getTexture2DArray();
   6137                 break;
   6138 
   6139               default:
   6140                 return gl::error(GL_INVALID_ENUM);
   6141             }
   6142 
   6143             texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
   6144         }
   6145     }
   6146     catch (...)
   6147     {
   6148         return gl::error(GL_OUT_OF_MEMORY);
   6149     }
   6150 }
   6151 
   6152 void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
   6153 {
   6154     EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
   6155           "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, "
   6156           "const GLvoid* data = 0x%0.8p)",
   6157           target, level, internalformat, width, height, depth, border, imageSize, data);
   6158 
   6159     try
   6160     {
   6161         gl::Context *context = gl::getNonLostContext();
   6162 
   6163         if (context)
   6164         {
   6165             if (context->getClientVersion() < 3)
   6166             {
   6167                 return gl::error(GL_INVALID_OPERATION);
   6168             }
   6169 
   6170             if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height))
   6171             {
   6172                 return gl::error(GL_INVALID_VALUE);
   6173             }
   6174 
   6175             // validateES3TexImageFormat sets the error code if there is an error
   6176             if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
   6177                                                0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data))
   6178             {
   6179                 return;
   6180             }
   6181 
   6182             switch(target)
   6183             {
   6184               case GL_TEXTURE_3D:
   6185                 {
   6186                     gl::Texture3D *texture = context->getTexture3D();
   6187                     texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
   6188                 }
   6189                 break;
   6190 
   6191               case GL_TEXTURE_2D_ARRAY:
   6192                 {
   6193                     gl::Texture2DArray *texture = context->getTexture2DArray();
   6194                     texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
   6195                 }
   6196                 break;
   6197 
   6198               default:
   6199                 return gl::error(GL_INVALID_ENUM);
   6200             }
   6201         }
   6202     }
   6203     catch (...)
   6204     {
   6205         return gl::error(GL_OUT_OF_MEMORY);
   6206     }
   6207 }
   6208 
   6209 void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
   6210 {
   6211     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
   6212         "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
   6213         "GLenum format = 0x%X, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
   6214         target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
   6215 
   6216     try
   6217     {
   6218         gl::Context *context = gl::getNonLostContext();
   6219 
   6220         if (context)
   6221         {
   6222             if (context->getClientVersion() < 3)
   6223             {
   6224                 return gl::error(GL_INVALID_OPERATION);
   6225             }
   6226 
   6227             if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height))
   6228             {
   6229                 return gl::error(GL_INVALID_VALUE);
   6230             }
   6231 
   6232             if (!data)
   6233             {
   6234                 return gl::error(GL_INVALID_VALUE);
   6235             }
   6236 
   6237             // validateES3TexImageFormat sets the error code if there is an error
   6238             if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
   6239                                                0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data))
   6240             {
   6241                 return;
   6242             }
   6243 
   6244             // Zero sized uploads are valid but no-ops
   6245             if (width == 0 || height == 0)
   6246             {
   6247                 return;
   6248             }
   6249 
   6250             switch(target)
   6251             {
   6252               case GL_TEXTURE_3D:
   6253                 {
   6254                     gl::Texture3D *texture = context->getTexture3D();
   6255                     texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
   6256                                                 format, imageSize, data);
   6257                 }
   6258                 break;
   6259 
   6260               case GL_TEXTURE_2D_ARRAY:
   6261                 {
   6262                     gl::Texture2DArray *texture = context->getTexture2DArray();
   6263                     texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
   6264                                                 format, imageSize, data);
   6265                 }
   6266                 break;
   6267 
   6268             default:
   6269                 return gl::error(GL_INVALID_ENUM);
   6270             }
   6271         }
   6272     }
   6273     catch (...)
   6274     {
   6275         return gl::error(GL_OUT_OF_MEMORY);
   6276     }
   6277 }
   6278 
   6279 void __stdcall glGenQueries(GLsizei n, GLuint* ids)
   6280 {
   6281     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
   6282 
   6283     try
   6284     {
   6285         gl::Context *context = gl::getNonLostContext();
   6286 
   6287         if (context)
   6288         {
   6289             if (context->getClientVersion() < 3)
   6290             {
   6291                 return gl::error(GL_INVALID_OPERATION);
   6292             }
   6293 
   6294             if (n < 0)
   6295             {
   6296                 return gl::error(GL_INVALID_VALUE);
   6297             }
   6298 
   6299             for (GLsizei i = 0; i < n; i++)
   6300             {
   6301                 ids[i] = context->createQuery();
   6302             }
   6303         }
   6304     }
   6305     catch (...)
   6306     {
   6307         return gl::error(GL_OUT_OF_MEMORY);
   6308     }
   6309 }
   6310 
   6311 void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids)
   6312 {
   6313     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
   6314 
   6315     try
   6316     {
   6317         gl::Context *context = gl::getNonLostContext();
   6318 
   6319         if (context)
   6320         {
   6321             if (context->getClientVersion() < 3)
   6322             {
   6323                 return gl::error(GL_INVALID_OPERATION);
   6324             }
   6325 
   6326             if (n < 0)
   6327             {
   6328                 return gl::error(GL_INVALID_VALUE);
   6329             }
   6330 
   6331             for (GLsizei i = 0; i < n; i++)
   6332             {
   6333                 context->deleteQuery(ids[i]);
   6334             }
   6335         }
   6336     }
   6337     catch (...)
   6338     {
   6339         return gl::error(GL_OUT_OF_MEMORY);
   6340     }
   6341 }
   6342 
   6343 GLboolean __stdcall glIsQuery(GLuint id)
   6344 {
   6345     EVENT("(GLuint id = %u)", id);
   6346 
   6347     try
   6348     {
   6349         gl::Context *context = gl::getNonLostContext();
   6350 
   6351         if (context)
   6352         {
   6353             if (context->getClientVersion() < 3)
   6354             {
   6355                 return gl::error(GL_INVALID_OPERATION, GL_FALSE);
   6356             }
   6357 
   6358             return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
   6359         }
   6360     }
   6361     catch (...)
   6362     {
   6363         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   6364     }
   6365 
   6366     return GL_FALSE;
   6367 }
   6368 
   6369 void __stdcall glBeginQuery(GLenum target, GLuint id)
   6370 {
   6371     EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
   6372 
   6373     try
   6374     {
   6375         gl::Context *context = gl::getNonLostContext();
   6376 
   6377         if (context)
   6378         {
   6379             if (context->getClientVersion() < 3)
   6380             {
   6381                 return gl::error(GL_INVALID_OPERATION);
   6382             }
   6383 
   6384             if (!ValidateBeginQuery(context, target, id))
   6385             {
   6386                 return;
   6387             }
   6388             context->beginQuery(target, id);
   6389         }
   6390     }
   6391     catch (...)
   6392     {
   6393         return gl::error(GL_OUT_OF_MEMORY);
   6394     }
   6395 }
   6396 
   6397 void __stdcall glEndQuery(GLenum target)
   6398 {
   6399     EVENT("(GLenum target = 0x%X)", target);
   6400 
   6401     try
   6402     {
   6403         gl::Context *context = gl::getNonLostContext();
   6404 
   6405         if (context)
   6406         {
   6407             if (context->getClientVersion() < 3)
   6408             {
   6409                 return gl::error(GL_INVALID_OPERATION);
   6410             }
   6411 
   6412             if (!ValidateEndQuery(context, target))
   6413             {
   6414                 return;
   6415             }
   6416 
   6417             context->endQuery(target);
   6418         }
   6419     }
   6420     catch (...)
   6421     {
   6422         return gl::error(GL_OUT_OF_MEMORY);
   6423     }
   6424 }
   6425 
   6426 void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params)
   6427 {
   6428     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
   6429 
   6430     try
   6431     {
   6432         gl::Context *context = gl::getNonLostContext();
   6433 
   6434         if (context)
   6435         {
   6436             if (context->getClientVersion() < 3)
   6437             {
   6438                 return gl::error(GL_INVALID_OPERATION);
   6439             }
   6440 
   6441             if (!ValidQueryType(context, target))
   6442             {
   6443                 return gl::error(GL_INVALID_ENUM);
   6444             }
   6445 
   6446             switch (pname)
   6447             {
   6448               case GL_CURRENT_QUERY:
   6449                 params[0] = static_cast<GLint>(context->getActiveQueryId(target));
   6450                 break;
   6451 
   6452               default:
   6453                 return gl::error(GL_INVALID_ENUM);
   6454             }
   6455         }
   6456     }
   6457     catch (...)
   6458     {
   6459         return gl::error(GL_OUT_OF_MEMORY);
   6460     }
   6461 }
   6462 
   6463 void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
   6464 {
   6465     EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params);
   6466 
   6467     try
   6468     {
   6469         gl::Context *context = gl::getNonLostContext();
   6470 
   6471         if (context)
   6472         {
   6473             if (context->getClientVersion() < 3)
   6474             {
   6475                 return gl::error(GL_INVALID_OPERATION);
   6476             }
   6477 
   6478             gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
   6479 
   6480             if (!queryObject)
   6481             {
   6482                 return gl::error(GL_INVALID_OPERATION);
   6483             }
   6484 
   6485             if (context->getActiveQueryId(queryObject->getType()) == id)
   6486             {
   6487                 return gl::error(GL_INVALID_OPERATION);
   6488             }
   6489 
   6490             switch(pname)
   6491             {
   6492               case GL_QUERY_RESULT:
   6493                 params[0] = queryObject->getResult();
   6494                 break;
   6495               case GL_QUERY_RESULT_AVAILABLE:
   6496                 params[0] = queryObject->isResultAvailable();
   6497                 break;
   6498               default:
   6499                 return gl::error(GL_INVALID_ENUM);
   6500             }
   6501         }
   6502     }
   6503     catch (...)
   6504     {
   6505         return gl::error(GL_OUT_OF_MEMORY);
   6506     }
   6507 }
   6508 
   6509 GLboolean __stdcall glUnmapBuffer(GLenum target)
   6510 {
   6511     EVENT("(GLenum target = 0x%X)", target);
   6512 
   6513     try
   6514     {
   6515         gl::Context *context = gl::getNonLostContext();
   6516 
   6517         if (context)
   6518         {
   6519             if (context->getClientVersion() < 3)
   6520             {
   6521                 return gl::error(GL_INVALID_OPERATION, GL_FALSE);
   6522             }
   6523 
   6524             return glUnmapBufferOES(target);
   6525         }
   6526     }
   6527     catch (...)
   6528     {
   6529         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   6530     }
   6531 
   6532     return GL_FALSE;
   6533 }
   6534 
   6535 void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
   6536 {
   6537     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
   6538 
   6539     try
   6540     {
   6541         gl::Context *context = gl::getNonLostContext();
   6542 
   6543         if (context)
   6544         {
   6545             if (context->getClientVersion() < 3)
   6546             {
   6547                 return gl::error(GL_INVALID_OPERATION);
   6548             }
   6549 
   6550             glGetBufferPointervOES(target, pname, params);
   6551         }
   6552     }
   6553     catch (...)
   6554     {
   6555         return gl::error(GL_OUT_OF_MEMORY);
   6556     }
   6557 }
   6558 
   6559 void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs)
   6560 {
   6561     try
   6562     {
   6563         gl::Context *context = gl::getNonLostContext();
   6564 
   6565         if (context)
   6566         {
   6567             if (context->getClientVersion() < 3)
   6568             {
   6569                 return gl::error(GL_INVALID_OPERATION);
   6570             }
   6571 
   6572             glDrawBuffersEXT(n, bufs);
   6573         }
   6574     }
   6575     catch (...)
   6576     {
   6577         return gl::error(GL_OUT_OF_MEMORY);
   6578     }
   6579 }
   6580 
   6581 void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   6582 {
   6583     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
   6584           location, count, transpose, value);
   6585 
   6586     try
   6587     {
   6588         gl::Context *context = gl::getNonLostContext();
   6589 
   6590         if (context)
   6591         {
   6592             if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose))
   6593             {
   6594                 return;
   6595             }
   6596 
   6597             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   6598             programBinary->setUniformMatrix2x3fv(location, count, transpose, value);
   6599         }
   6600     }
   6601     catch (...)
   6602     {
   6603         return gl::error(GL_OUT_OF_MEMORY);
   6604     }
   6605 }
   6606 
   6607 void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   6608 {
   6609     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
   6610           location, count, transpose, value);
   6611 
   6612     try
   6613     {
   6614         gl::Context *context = gl::getNonLostContext();
   6615 
   6616         if (context)
   6617         {
   6618             if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose))
   6619             {
   6620                 return;
   6621             }
   6622 
   6623             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   6624             programBinary->setUniformMatrix3x2fv(location, count, transpose, value);
   6625         }
   6626     }
   6627     catch (...)
   6628     {
   6629         return gl::error(GL_OUT_OF_MEMORY);
   6630     }
   6631 }
   6632 
   6633 void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   6634 {
   6635     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
   6636           location, count, transpose, value);
   6637 
   6638     try
   6639     {
   6640         gl::Context *context = gl::getNonLostContext();
   6641 
   6642         if (context)
   6643         {
   6644             if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose))
   6645             {
   6646                 return;
   6647             }
   6648 
   6649             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   6650             programBinary->setUniformMatrix2x4fv(location, count, transpose, value);
   6651         }
   6652     }
   6653     catch (...)
   6654     {
   6655         return gl::error(GL_OUT_OF_MEMORY);
   6656     }
   6657 }
   6658 
   6659 void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   6660 {
   6661     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
   6662           location, count, transpose, value);
   6663 
   6664     try
   6665     {
   6666         gl::Context *context = gl::getNonLostContext();
   6667 
   6668         if (context)
   6669         {
   6670             if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose))
   6671             {
   6672                 return;
   6673             }
   6674 
   6675             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   6676             programBinary->setUniformMatrix4x2fv(location, count, transpose, value);
   6677         }
   6678     }
   6679     catch (...)
   6680     {
   6681         return gl::error(GL_OUT_OF_MEMORY);
   6682     }
   6683 }
   6684 
   6685 void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   6686 {
   6687     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
   6688           location, count, transpose, value);
   6689 
   6690     try
   6691     {
   6692         gl::Context *context = gl::getNonLostContext();
   6693 
   6694         if (context)
   6695         {
   6696             if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose))
   6697             {
   6698                 return;
   6699             }
   6700 
   6701             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   6702             programBinary->setUniformMatrix3x4fv(location, count, transpose, value);
   6703         }
   6704     }
   6705     catch (...)
   6706     {
   6707         return gl::error(GL_OUT_OF_MEMORY);
   6708     }
   6709 }
   6710 
   6711 void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   6712 {
   6713     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
   6714           location, count, transpose, value);
   6715 
   6716     try
   6717     {
   6718         gl::Context *context = gl::getNonLostContext();
   6719 
   6720         if (context)
   6721         {
   6722             if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose))
   6723             {
   6724                 return;
   6725             }
   6726 
   6727             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   6728             programBinary->setUniformMatrix4x3fv(location, count, transpose, value);
   6729         }
   6730     }
   6731     catch (...)
   6732     {
   6733         return gl::error(GL_OUT_OF_MEMORY);
   6734     }
   6735 }
   6736 
   6737 void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
   6738 {
   6739     EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, "
   6740           "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
   6741           srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
   6742 
   6743     try
   6744     {
   6745         gl::Context *context = gl::getNonLostContext();
   6746         if (context)
   6747         {
   6748             if (context->getClientVersion() < 3)
   6749             {
   6750                 return gl::error(GL_INVALID_OPERATION);
   6751             }
   6752 
   6753             if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
   6754                                                    dstX0, dstY0, dstX1, dstY1, mask, filter,
   6755                                                    false))
   6756             {
   6757                 return;
   6758             }
   6759 
   6760             context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
   6761                                      mask, filter);
   6762         }
   6763     }
   6764     catch (...)
   6765     {
   6766         return gl::error(GL_OUT_OF_MEMORY);
   6767     }
   6768 }
   6769 
   6770 void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
   6771 {
   6772     EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
   6773         target, samples, internalformat, width, height);
   6774 
   6775     try
   6776     {
   6777         gl::Context *context = gl::getNonLostContext();
   6778 
   6779         if (context)
   6780         {
   6781             if (context->getClientVersion() < 3)
   6782             {
   6783                 return gl::error(GL_INVALID_OPERATION);
   6784             }
   6785 
   6786             if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
   6787                                                        width, height, false))
   6788             {
   6789                 return;
   6790             }
   6791 
   6792             context->setRenderbufferStorage(width, height, internalformat, samples);
   6793         }
   6794     }
   6795     catch (...)
   6796     {
   6797         return gl::error(GL_OUT_OF_MEMORY);
   6798     }
   6799 }
   6800 
   6801 void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
   6802 {
   6803     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)",
   6804         target, attachment, texture, level, layer);
   6805 
   6806     try
   6807     {
   6808         gl::Context *context = gl::getNonLostContext();
   6809 
   6810         if (context)
   6811         {
   6812             if (context->getClientVersion() < 3)
   6813             {
   6814                 return gl::error(GL_INVALID_OPERATION);
   6815             }
   6816 
   6817             if (!ValidateES3FramebufferTextureParameters(context, target, attachment, GL_NONE, texture, level, layer, true))
   6818             {
   6819                 return;
   6820             }
   6821 
   6822             gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
   6823             ASSERT(framebuffer);
   6824 
   6825             gl::Texture *textureObject = context->getTexture(texture);
   6826             GLenum textarget = textureObject ? textureObject->getTarget() : GL_NONE;
   6827 
   6828             if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
   6829             {
   6830                 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
   6831                 framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, layer);
   6832             }
   6833             else
   6834             {
   6835                 switch (attachment)
   6836                 {
   6837                 case GL_DEPTH_ATTACHMENT:         framebuffer->setDepthbuffer(textarget, texture, level, layer);        break;
   6838                 case GL_STENCIL_ATTACHMENT:       framebuffer->setStencilbuffer(textarget, texture, level, layer);      break;
   6839                 case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, layer); break;
   6840                 }
   6841             }
   6842         }
   6843     }
   6844     catch (...)
   6845     {
   6846         return gl::error(GL_OUT_OF_MEMORY);
   6847     }
   6848 }
   6849 
   6850 GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
   6851 {
   6852     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
   6853           target, offset, length, access);
   6854 
   6855     try
   6856     {
   6857         gl::Context *context = gl::getNonLostContext();
   6858 
   6859         if (context)
   6860         {
   6861             if (context->getClientVersion() < 3)
   6862             {
   6863                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
   6864             }
   6865 
   6866             return glMapBufferRangeEXT(target, offset, length, access);
   6867         }
   6868     }
   6869     catch (...)
   6870     {
   6871         return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL));
   6872     }
   6873 
   6874     return NULL;
   6875 }
   6876 
   6877 void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
   6878 {
   6879     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
   6880 
   6881     try
   6882     {
   6883         gl::Context *context = gl::getNonLostContext();
   6884 
   6885         if (context)
   6886         {
   6887             if (context->getClientVersion() < 3)
   6888             {
   6889                 return gl::error(GL_INVALID_OPERATION);
   6890             }
   6891 
   6892             glFlushMappedBufferRangeEXT(target, offset, length);
   6893         }
   6894     }
   6895     catch (...)
   6896     {
   6897         return gl::error(GL_OUT_OF_MEMORY);
   6898     }
   6899 }
   6900 
   6901 void __stdcall glBindVertexArray(GLuint array)
   6902 {
   6903     EVENT("(GLuint array = %u)", array);
   6904 
   6905     try
   6906     {
   6907         gl::Context *context = gl::getNonLostContext();
   6908 
   6909         if (context)
   6910         {
   6911             if (context->getClientVersion() < 3)
   6912             {
   6913                 return gl::error(GL_INVALID_OPERATION);
   6914             }
   6915 
   6916             gl::VertexArray *vao = context->getVertexArray(array);
   6917 
   6918             if (!vao)
   6919             {
   6920                 // The default VAO should always exist
   6921                 ASSERT(array != 0);
   6922                 return gl::error(GL_INVALID_OPERATION);
   6923             }
   6924 
   6925             context->bindVertexArray(array);
   6926         }
   6927     }
   6928     catch (...)
   6929     {
   6930         return gl::error(GL_OUT_OF_MEMORY);
   6931     }
   6932 }
   6933 
   6934 void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays)
   6935 {
   6936     EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
   6937 
   6938     try
   6939     {
   6940         gl::Context *context = gl::getNonLostContext();
   6941 
   6942         if (context)
   6943         {
   6944             if (context->getClientVersion() < 3)
   6945             {
   6946                 return gl::error(GL_INVALID_OPERATION);
   6947             }
   6948 
   6949             if (n < 0)
   6950             {
   6951                 return gl::error(GL_INVALID_VALUE);
   6952             }
   6953 
   6954             for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
   6955             {
   6956                 if (arrays[arrayIndex] != 0)
   6957                 {
   6958                     context->deleteVertexArray(arrays[arrayIndex]);
   6959                 }
   6960             }
   6961         }
   6962     }
   6963     catch (...)
   6964     {
   6965         return gl::error(GL_OUT_OF_MEMORY);
   6966     }
   6967 }
   6968 
   6969 void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays)
   6970 {
   6971     EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
   6972 
   6973     try
   6974     {
   6975         gl::Context *context = gl::getNonLostContext();
   6976 
   6977         if (context)
   6978         {
   6979             if (context->getClientVersion() < 3)
   6980             {
   6981                 return gl::error(GL_INVALID_OPERATION);
   6982             }
   6983 
   6984             if (n < 0)
   6985             {
   6986                 return gl::error(GL_INVALID_VALUE);
   6987             }
   6988 
   6989             for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
   6990             {
   6991                 arrays[arrayIndex] = context->createVertexArray();
   6992             }
   6993         }
   6994     }
   6995     catch (...)
   6996     {
   6997         return gl::error(GL_OUT_OF_MEMORY);
   6998     }
   6999 }
   7000 
   7001 GLboolean __stdcall glIsVertexArray(GLuint array)
   7002 {
   7003     EVENT("(GLuint array = %u)", array);
   7004 
   7005     try
   7006     {
   7007         gl::Context *context = gl::getNonLostContext();
   7008 
   7009         if (context)
   7010         {
   7011             if (context->getClientVersion() < 3)
   7012             {
   7013                 return gl::error(GL_INVALID_OPERATION, GL_FALSE);
   7014             }
   7015 
   7016             if (array == 0)
   7017             {
   7018                 return GL_FALSE;
   7019             }
   7020 
   7021             gl::VertexArray *vao = context->getVertexArray(array);
   7022 
   7023             return (vao != NULL ? GL_TRUE : GL_FALSE);
   7024         }
   7025     }
   7026     catch (...)
   7027     {
   7028         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   7029     }
   7030 
   7031     return GL_FALSE;
   7032 }
   7033 
   7034 void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
   7035 {
   7036     EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)",
   7037           target, index, data);
   7038 
   7039     try
   7040     {
   7041         gl::Context *context = gl::getNonLostContext();
   7042 
   7043         if (context)
   7044         {
   7045             if (context->getClientVersion() < 3)
   7046             {
   7047                 return gl::error(GL_INVALID_OPERATION);
   7048             }
   7049 
   7050             switch (target)
   7051             {
   7052               case GL_TRANSFORM_FEEDBACK_BUFFER_START:
   7053               case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
   7054               case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   7055                 if (index >= context->getMaxTransformFeedbackBufferBindings())
   7056                     return gl::error(GL_INVALID_VALUE);
   7057                 break;
   7058               case GL_UNIFORM_BUFFER_START:
   7059               case GL_UNIFORM_BUFFER_SIZE:
   7060               case GL_UNIFORM_BUFFER_BINDING:
   7061                 if (index >= context->getMaximumCombinedUniformBufferBindings())
   7062                     return gl::error(GL_INVALID_VALUE);
   7063                 break;
   7064               default:
   7065                 return gl::error(GL_INVALID_ENUM);
   7066             }
   7067 
   7068             if (!(context->getIndexedIntegerv(target, index, data)))
   7069             {
   7070                 GLenum nativeType;
   7071                 unsigned int numParams = 0;
   7072                 if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
   7073                     return gl::error(GL_INVALID_ENUM);
   7074 
   7075                 if (numParams == 0)
   7076                     return; // it is known that pname is valid, but there are no parameters to return
   7077 
   7078                 if (nativeType == GL_INT_64_ANGLEX)
   7079                 {
   7080                     GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<int>::min());
   7081                     GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<int>::max());
   7082                     GLint64 *int64Params = new GLint64[numParams];
   7083 
   7084                     context->getIndexedInteger64v(target, index, int64Params);
   7085 
   7086                     for (unsigned int i = 0; i < numParams; ++i)
   7087                     {
   7088                         GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue);
   7089                         data[i] = static_cast<GLint>(clampedValue);
   7090                     }
   7091 
   7092                     delete [] int64Params;
   7093                 }
   7094                 else
   7095                 {
   7096                     UNREACHABLE();
   7097                 }
   7098             }
   7099         }
   7100     }
   7101     catch (...)
   7102     {
   7103         return gl::error(GL_OUT_OF_MEMORY);
   7104     }
   7105 }
   7106 
   7107 void __stdcall glBeginTransformFeedback(GLenum primitiveMode)
   7108 {
   7109     EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
   7110 
   7111     try
   7112     {
   7113         gl::Context *context = gl::getNonLostContext();
   7114 
   7115         if (context)
   7116         {
   7117             if (context->getClientVersion() < 3)
   7118             {
   7119                 return gl::error(GL_INVALID_OPERATION);
   7120             }
   7121 
   7122             switch (primitiveMode)
   7123             {
   7124               case GL_TRIANGLES:
   7125               case GL_LINES:
   7126               case GL_POINTS:
   7127                 break;
   7128               default:
   7129                 return gl::error(GL_INVALID_ENUM);
   7130             }
   7131 
   7132             gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
   7133             ASSERT(transformFeedback != NULL);
   7134 
   7135             if (transformFeedback->isStarted())
   7136             {
   7137                 return gl::error(GL_INVALID_OPERATION);
   7138             }
   7139 
   7140             if (transformFeedback->isPaused())
   7141             {
   7142                 transformFeedback->resume();
   7143             }
   7144             else
   7145             {
   7146                 transformFeedback->start(primitiveMode);
   7147             }
   7148         }
   7149     }
   7150     catch (...)
   7151     {
   7152         return gl::error(GL_OUT_OF_MEMORY);
   7153     }
   7154 }
   7155 
   7156 void __stdcall glEndTransformFeedback(void)
   7157 {
   7158     EVENT("(void)");
   7159 
   7160     try
   7161     {
   7162         gl::Context *context = gl::getNonLostContext();
   7163 
   7164         if (context)
   7165         {
   7166             if (context->getClientVersion() < 3)
   7167             {
   7168                 return gl::error(GL_INVALID_OPERATION);
   7169             }
   7170 
   7171             gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
   7172             ASSERT(transformFeedback != NULL);
   7173 
   7174             if (!transformFeedback->isStarted())
   7175             {
   7176                 return gl::error(GL_INVALID_OPERATION);
   7177             }
   7178 
   7179             transformFeedback->stop();
   7180         }
   7181     }
   7182     catch (...)
   7183     {
   7184         return gl::error(GL_OUT_OF_MEMORY);
   7185     }
   7186 }
   7187 
   7188 void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
   7189 {
   7190     EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)",
   7191           target, index, buffer, offset, size);
   7192 
   7193     try
   7194     {
   7195         gl::Context *context = gl::getNonLostContext();
   7196 
   7197         if (context)
   7198         {
   7199             if (context->getClientVersion() < 3)
   7200             {
   7201                 return gl::error(GL_INVALID_OPERATION);
   7202             }
   7203 
   7204             switch (target)
   7205             {
   7206               case GL_TRANSFORM_FEEDBACK_BUFFER:
   7207                 if (index >= context->getMaxTransformFeedbackBufferBindings())
   7208                 {
   7209                     return gl::error(GL_INVALID_VALUE);
   7210                 }
   7211                 break;
   7212 
   7213               case GL_UNIFORM_BUFFER:
   7214                 if (index >= context->getMaximumCombinedUniformBufferBindings())
   7215                 {
   7216                     return gl::error(GL_INVALID_VALUE);
   7217                 }
   7218                 break;
   7219 
   7220               default:
   7221                 return gl::error(GL_INVALID_ENUM);
   7222             }
   7223 
   7224             if (buffer != 0 && size <= 0)
   7225             {
   7226                 return gl::error(GL_INVALID_VALUE);
   7227             }
   7228 
   7229             switch (target)
   7230             {
   7231               case GL_TRANSFORM_FEEDBACK_BUFFER:
   7232 
   7233                 // size and offset must be a multiple of 4
   7234                 if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
   7235                 {
   7236                     return gl::error(GL_INVALID_VALUE);
   7237                 }
   7238 
   7239                 context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
   7240                 context->bindGenericTransformFeedbackBuffer(buffer);
   7241                 break;
   7242 
   7243               case GL_UNIFORM_BUFFER:
   7244 
   7245                 // it is an error to bind an offset not a multiple of the alignment
   7246                 if (buffer != 0 && (offset % context->getUniformBufferOffsetAlignment()) != 0)
   7247                 {
   7248                     return gl::error(GL_INVALID_VALUE);
   7249                 }
   7250 
   7251                 context->bindIndexedUniformBuffer(buffer, index, offset, size);
   7252                 context->bindGenericUniformBuffer(buffer);
   7253                 break;
   7254 
   7255               default:
   7256                 UNREACHABLE();
   7257             }
   7258         }
   7259     }
   7260     catch (...)
   7261     {
   7262         return gl::error(GL_OUT_OF_MEMORY);
   7263     }
   7264 }
   7265 
   7266 void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
   7267 {
   7268     EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)",
   7269           target, index, buffer);
   7270 
   7271     try
   7272     {
   7273         gl::Context *context = gl::getNonLostContext();
   7274 
   7275         if (context)
   7276         {
   7277             if (context->getClientVersion() < 3)
   7278             {
   7279                 return gl::error(GL_INVALID_OPERATION);
   7280             }
   7281 
   7282             switch (target)
   7283             {
   7284               case GL_TRANSFORM_FEEDBACK_BUFFER:
   7285                 if (index >= context->getMaxTransformFeedbackBufferBindings())
   7286                 {
   7287                     return gl::error(GL_INVALID_VALUE);
   7288                 }
   7289                 break;
   7290 
   7291               case GL_UNIFORM_BUFFER:
   7292                 if (index >= context->getMaximumCombinedUniformBufferBindings())
   7293                 {
   7294                     return gl::error(GL_INVALID_VALUE);
   7295                 }
   7296                 break;
   7297 
   7298               default:
   7299                 return gl::error(GL_INVALID_ENUM);
   7300             }
   7301 
   7302             switch (target)
   7303             {
   7304               case GL_TRANSFORM_FEEDBACK_BUFFER:
   7305                 context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
   7306                 context->bindGenericTransformFeedbackBuffer(buffer);
   7307                 break;
   7308 
   7309               case GL_UNIFORM_BUFFER:
   7310                 context->bindIndexedUniformBuffer(buffer, index, 0, 0);
   7311                 context->bindGenericUniformBuffer(buffer);
   7312                 break;
   7313 
   7314               default:
   7315                 UNREACHABLE();
   7316             }
   7317         }
   7318     }
   7319     catch (...)
   7320     {
   7321         return gl::error(GL_OUT_OF_MEMORY);
   7322     }
   7323 }
   7324 
   7325 void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
   7326 {
   7327     EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)",
   7328           program, count, varyings, bufferMode);
   7329 
   7330     try
   7331     {
   7332         gl::Context *context = gl::getNonLostContext();
   7333 
   7334         if (context)
   7335         {
   7336             if (context->getClientVersion() < 3)
   7337             {
   7338                 return gl::error(GL_INVALID_OPERATION);
   7339             }
   7340 
   7341             if (count < 0)
   7342             {
   7343                 return gl::error(GL_INVALID_VALUE);
   7344             }
   7345 
   7346             switch (bufferMode)
   7347             {
   7348               case GL_INTERLEAVED_ATTRIBS:
   7349                 break;
   7350               case GL_SEPARATE_ATTRIBS:
   7351                 if (static_cast<GLuint>(count) > context->getMaxTransformFeedbackBufferBindings())
   7352                 {
   7353                     return gl::error(GL_INVALID_VALUE);
   7354                 }
   7355                 break;
   7356               default:
   7357                 return gl::error(GL_INVALID_ENUM);
   7358             }
   7359 
   7360             if (!gl::ValidProgram(context, program))
   7361             {
   7362                 return;
   7363             }
   7364 
   7365             gl::Program *programObject = context->getProgram(program);
   7366             ASSERT(programObject);
   7367 
   7368             programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
   7369         }
   7370     }
   7371     catch (...)
   7372     {
   7373         return gl::error(GL_OUT_OF_MEMORY);
   7374     }
   7375 }
   7376 
   7377 void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
   7378 {
   7379     EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, "
   7380           "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
   7381           program, index, bufSize, length, size, type, name);
   7382 
   7383     try
   7384     {
   7385         gl::Context *context = gl::getNonLostContext();
   7386 
   7387         if (context)
   7388         {
   7389             if (context->getClientVersion() < 3)
   7390             {
   7391                 return gl::error(GL_INVALID_OPERATION);
   7392             }
   7393 
   7394             if (bufSize < 0)
   7395             {
   7396                 return gl::error(GL_INVALID_VALUE);
   7397             }
   7398 
   7399             if (!gl::ValidProgram(context, program))
   7400             {
   7401                 return;
   7402             }
   7403 
   7404             gl::Program *programObject = context->getProgram(program);
   7405             ASSERT(programObject);
   7406 
   7407             if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
   7408             {
   7409                 return gl::error(GL_INVALID_VALUE);
   7410             }
   7411 
   7412             programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
   7413         }
   7414     }
   7415     catch (...)
   7416     {
   7417         return gl::error(GL_OUT_OF_MEMORY);
   7418     }
   7419 }
   7420 
   7421 void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
   7422 {
   7423     EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)",
   7424           index, size, type, stride, pointer);
   7425 
   7426     try
   7427     {
   7428         gl::Context *context = gl::getNonLostContext();
   7429 
   7430         if (context)
   7431         {
   7432             if (context->getClientVersion() < 3)
   7433             {
   7434                 return gl::error(GL_INVALID_OPERATION);
   7435             }
   7436         }
   7437 
   7438         if (index >= gl::MAX_VERTEX_ATTRIBS)
   7439         {
   7440             return gl::error(GL_INVALID_VALUE);
   7441         }
   7442 
   7443         if (size < 1 || size > 4)
   7444         {
   7445             return gl::error(GL_INVALID_VALUE);
   7446         }
   7447 
   7448         switch (type)
   7449         {
   7450           case GL_BYTE:
   7451           case GL_UNSIGNED_BYTE:
   7452           case GL_SHORT:
   7453           case GL_UNSIGNED_SHORT:
   7454           case GL_INT:
   7455           case GL_UNSIGNED_INT:
   7456           case GL_INT_2_10_10_10_REV:
   7457           case GL_UNSIGNED_INT_2_10_10_10_REV:
   7458             break;
   7459           default:
   7460             return gl::error(GL_INVALID_ENUM);
   7461         }
   7462 
   7463         if (stride < 0)
   7464         {
   7465             return gl::error(GL_INVALID_VALUE);
   7466         }
   7467 
   7468         if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
   7469         {
   7470             return gl::error(GL_INVALID_OPERATION);
   7471         }
   7472 
   7473         if (context)
   7474         {
   7475             // [OpenGL ES 3.0.2] Section 2.8 page 24:
   7476             // An INVALID_OPERATION error is generated when a non-zero vertex array object
   7477             // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
   7478             // and the pointer argument is not NULL.
   7479             if (context->getVertexArrayHandle() != 0 && context->getArrayBufferHandle() == 0 && pointer != NULL)
   7480             {
   7481                 return gl::error(GL_INVALID_OPERATION);
   7482             }
   7483 
   7484             context->setVertexAttribState(index, context->getArrayBuffer(), size, type, false, true,
   7485                                           stride, pointer);
   7486         }
   7487     }
   7488     catch (...)
   7489     {
   7490         return gl::error(GL_OUT_OF_MEMORY);
   7491     }
   7492 }
   7493 
   7494 void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
   7495 {
   7496     EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
   7497           index, pname, params);
   7498 
   7499     try
   7500     {
   7501         gl::Context *context = gl::getNonLostContext();
   7502 
   7503         if (context)
   7504         {
   7505             if (context->getClientVersion() < 3)
   7506             {
   7507                 return gl::error(GL_INVALID_OPERATION);
   7508             }
   7509 
   7510             if (index >= gl::MAX_VERTEX_ATTRIBS)
   7511             {
   7512                 return gl::error(GL_INVALID_VALUE);
   7513             }
   7514 
   7515             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
   7516 
   7517             if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
   7518             {
   7519                 return;
   7520             }
   7521 
   7522             if (pname == GL_CURRENT_VERTEX_ATTRIB)
   7523             {
   7524                 const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
   7525                 for (int i = 0; i < 4; ++i)
   7526                 {
   7527                     params[i] = currentValueData.IntValues[i];
   7528                 }
   7529             }
   7530             else
   7531             {
   7532                 *params = attribState.querySingleParameter<GLint>(pname);
   7533             }
   7534         }
   7535     }
   7536     catch (...)
   7537     {
   7538         return gl::error(GL_OUT_OF_MEMORY);
   7539     }
   7540 }
   7541 
   7542 void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
   7543 {
   7544     EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)",
   7545           index, pname, params);
   7546 
   7547     try
   7548     {
   7549         gl::Context *context = gl::getNonLostContext();
   7550 
   7551         if (context)
   7552         {
   7553             if (context->getClientVersion() < 3)
   7554             {
   7555                 return gl::error(GL_INVALID_OPERATION);
   7556             }
   7557 
   7558             if (index >= gl::MAX_VERTEX_ATTRIBS)
   7559             {
   7560                 return gl::error(GL_INVALID_VALUE);
   7561             }
   7562 
   7563             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
   7564 
   7565             if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
   7566             {
   7567                 return;
   7568             }
   7569 
   7570             if (pname == GL_CURRENT_VERTEX_ATTRIB)
   7571             {
   7572                 const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
   7573                 for (int i = 0; i < 4; ++i)
   7574                 {
   7575                     params[i] = currentValueData.UnsignedIntValues[i];
   7576                 }
   7577             }
   7578             else
   7579             {
   7580                 *params = attribState.querySingleParameter<GLuint>(pname);
   7581             }
   7582         }
   7583     }
   7584     catch (...)
   7585     {
   7586         return gl::error(GL_OUT_OF_MEMORY);
   7587     }
   7588 }
   7589 
   7590 void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
   7591 {
   7592     EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
   7593           index, x, y, z, w);
   7594 
   7595     try
   7596     {
   7597         gl::Context *context = gl::getNonLostContext();
   7598 
   7599         if (context)
   7600         {
   7601             if (context->getClientVersion() < 3)
   7602             {
   7603                 return gl::error(GL_INVALID_OPERATION);
   7604             }
   7605 
   7606             if (index >= gl::MAX_VERTEX_ATTRIBS)
   7607             {
   7608                 return gl::error(GL_INVALID_VALUE);
   7609             }
   7610 
   7611             GLint vals[4] = { x, y, z, w };
   7612             context->setVertexAttribi(index, vals);
   7613         }
   7614     }
   7615     catch (...)
   7616     {
   7617         return gl::error(GL_OUT_OF_MEMORY);
   7618     }
   7619 }
   7620 
   7621 void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
   7622 {
   7623     EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)",
   7624           index, x, y, z, w);
   7625 
   7626     try
   7627     {
   7628         gl::Context *context = gl::getNonLostContext();
   7629 
   7630         if (context)
   7631         {
   7632             if (context->getClientVersion() < 3)
   7633             {
   7634                 return gl::error(GL_INVALID_OPERATION);
   7635             }
   7636 
   7637             if (index >= gl::MAX_VERTEX_ATTRIBS)
   7638             {
   7639                 return gl::error(GL_INVALID_VALUE);
   7640             }
   7641 
   7642             GLuint vals[4] = { x, y, z, w };
   7643             context->setVertexAttribu(index, vals);
   7644         }
   7645     }
   7646     catch (...)
   7647     {
   7648         return gl::error(GL_OUT_OF_MEMORY);
   7649     }
   7650 }
   7651 
   7652 void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v)
   7653 {
   7654     EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v);
   7655 
   7656     try
   7657     {
   7658         gl::Context *context = gl::getNonLostContext();
   7659 
   7660         if (context)
   7661         {
   7662             if (context->getClientVersion() < 3)
   7663             {
   7664                 return gl::error(GL_INVALID_OPERATION);
   7665             }
   7666 
   7667             if (index >= gl::MAX_VERTEX_ATTRIBS)
   7668             {
   7669                 return gl::error(GL_INVALID_VALUE);
   7670             }
   7671 
   7672             context->setVertexAttribi(index, v);
   7673         }
   7674     }
   7675     catch (...)
   7676     {
   7677         return gl::error(GL_OUT_OF_MEMORY);
   7678     }
   7679 }
   7680 
   7681 void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v)
   7682 {
   7683     EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v);
   7684 
   7685     try
   7686     {
   7687         gl::Context *context = gl::getNonLostContext();
   7688 
   7689         if (context)
   7690         {
   7691             if (context->getClientVersion() < 3)
   7692             {
   7693                 return gl::error(GL_INVALID_OPERATION);
   7694             }
   7695 
   7696             if (index >= gl::MAX_VERTEX_ATTRIBS)
   7697             {
   7698                 return gl::error(GL_INVALID_VALUE);
   7699             }
   7700 
   7701             context->setVertexAttribu(index, v);
   7702         }
   7703     }
   7704     catch (...)
   7705     {
   7706         return gl::error(GL_OUT_OF_MEMORY);
   7707     }
   7708 }
   7709 
   7710 void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params)
   7711 {
   7712     EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)",
   7713           program, location, params);
   7714 
   7715     try
   7716     {
   7717         gl::Context *context = gl::getNonLostContext();
   7718 
   7719         if (context)
   7720         {
   7721             if (context->getClientVersion() < 3)
   7722             {
   7723                 return gl::error(GL_INVALID_OPERATION);
   7724             }
   7725 
   7726             if (program == 0)
   7727             {
   7728                 return gl::error(GL_INVALID_VALUE);
   7729             }
   7730 
   7731             gl::Program *programObject = context->getProgram(program);
   7732 
   7733             if (!programObject || !programObject->isLinked())
   7734             {
   7735                 return gl::error(GL_INVALID_OPERATION);
   7736             }
   7737 
   7738             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   7739             if (!programBinary)
   7740             {
   7741                 return gl::error(GL_INVALID_OPERATION);
   7742             }
   7743 
   7744             if (!programBinary->getUniformuiv(location, NULL, params))
   7745             {
   7746                 return gl::error(GL_INVALID_OPERATION);
   7747             }
   7748         }
   7749     }
   7750     catch (...)
   7751     {
   7752         return gl::error(GL_OUT_OF_MEMORY);
   7753     }
   7754 }
   7755 
   7756 GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name)
   7757 {
   7758     EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)",
   7759           program, name);
   7760 
   7761     try
   7762     {
   7763         gl::Context *context = gl::getNonLostContext();
   7764 
   7765         if (context)
   7766         {
   7767             if (context->getClientVersion() < 3)
   7768             {
   7769                 return gl::error(GL_INVALID_OPERATION, -1);
   7770             }
   7771 
   7772             if (program == 0)
   7773             {
   7774                 return gl::error(GL_INVALID_VALUE, -1);
   7775             }
   7776 
   7777             gl::Program *programObject = context->getProgram(program);
   7778 
   7779             if (!programObject || !programObject->isLinked())
   7780             {
   7781                 return gl::error(GL_INVALID_OPERATION, -1);
   7782             }
   7783 
   7784             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   7785             if (!programBinary)
   7786             {
   7787                 return gl::error(GL_INVALID_OPERATION, -1);
   7788             }
   7789 
   7790             return programBinary->getFragDataLocation(name);
   7791         }
   7792     }
   7793     catch (...)
   7794     {
   7795         return gl::error(GL_OUT_OF_MEMORY, 0);
   7796     }
   7797 
   7798     return 0;
   7799 }
   7800 
   7801 void __stdcall glUniform1ui(GLint location, GLuint v0)
   7802 {
   7803     glUniform1uiv(location, 1, &v0);
   7804 }
   7805 
   7806 void __stdcall glUniform2ui(GLint location, GLuint v0, GLuint v1)
   7807 {
   7808     const GLuint xy[] = { v0, v1 };
   7809     glUniform2uiv(location, 1, xy);
   7810 }
   7811 
   7812 void __stdcall glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
   7813 {
   7814     const GLuint xyz[] = { v0, v1, v2 };
   7815     glUniform3uiv(location, 1, xyz);
   7816 }
   7817 
   7818 void __stdcall glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
   7819 {
   7820     const GLuint xyzw[] = { v0, v1, v2, v3 };
   7821     glUniform4uiv(location, 1, xyzw);
   7822 }
   7823 
   7824 void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value)
   7825 {
   7826     EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
   7827           location, count, value);
   7828 
   7829     try
   7830     {
   7831         gl::Context *context = gl::getNonLostContext();
   7832 
   7833         if (context)
   7834         {
   7835             if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count))
   7836             {
   7837                 return;
   7838             }
   7839 
   7840             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   7841             programBinary->setUniform1uiv(location, count, value);
   7842         }
   7843     }
   7844     catch (...)
   7845     {
   7846         return gl::error(GL_OUT_OF_MEMORY);
   7847     }
   7848 }
   7849 
   7850 void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value)
   7851 {
   7852     EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
   7853           location, count, value);
   7854 
   7855     try
   7856     {
   7857         gl::Context *context = gl::getNonLostContext();
   7858 
   7859         if (context)
   7860         {
   7861             if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count))
   7862             {
   7863                 return;
   7864             }
   7865 
   7866             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   7867             programBinary->setUniform2uiv(location, count, value);
   7868         }
   7869     }
   7870     catch (...)
   7871     {
   7872         return gl::error(GL_OUT_OF_MEMORY);
   7873     }
   7874 }
   7875 
   7876 void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value)
   7877 {
   7878     EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)",
   7879           location, count, value);
   7880 
   7881     try
   7882     {
   7883         gl::Context *context = gl::getNonLostContext();
   7884 
   7885         if (context)
   7886         {
   7887             if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count))
   7888             {
   7889                 return;
   7890             }
   7891 
   7892             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   7893             programBinary->setUniform3uiv(location, count, value);
   7894         }
   7895     }
   7896     catch (...)
   7897     {
   7898         return gl::error(GL_OUT_OF_MEMORY);
   7899     }
   7900 }
   7901 
   7902 void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value)
   7903 {
   7904     EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
   7905           location, count, value);
   7906 
   7907     try
   7908     {
   7909         gl::Context *context = gl::getNonLostContext();
   7910 
   7911         if (context)
   7912         {
   7913             if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count))
   7914             {
   7915                 return;
   7916             }
   7917 
   7918             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
   7919             programBinary->setUniform4uiv(location, count, value);
   7920         }
   7921     }
   7922     catch (...)
   7923     {
   7924         return gl::error(GL_OUT_OF_MEMORY);
   7925     }
   7926 }
   7927 
   7928 void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value)
   7929 {
   7930     EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)",
   7931           buffer, drawbuffer, value);
   7932 
   7933     try
   7934     {
   7935         gl::Context *context = gl::getNonLostContext();
   7936 
   7937         if (context)
   7938         {
   7939             if (context->getClientVersion() < 3)
   7940             {
   7941                 return gl::error(GL_INVALID_OPERATION);
   7942             }
   7943 
   7944             switch (buffer)
   7945             {
   7946               case GL_COLOR:
   7947                 if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets()))
   7948                 {
   7949                     return gl::error(GL_INVALID_VALUE);
   7950                 }
   7951                 break;
   7952               case GL_STENCIL:
   7953                 if (drawbuffer != 0)
   7954                 {
   7955                     return gl::error(GL_INVALID_VALUE);
   7956                 }
   7957                 break;
   7958               default:
   7959                 return gl::error(GL_INVALID_ENUM);
   7960             }
   7961 
   7962             context->clearBufferiv(buffer, drawbuffer, value);
   7963         }
   7964     }
   7965     catch (...)
   7966     {
   7967         return gl::error(GL_OUT_OF_MEMORY);
   7968     }
   7969 }
   7970 
   7971 void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value)
   7972 {
   7973     EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)",
   7974           buffer, drawbuffer, value);
   7975 
   7976     try
   7977     {
   7978         gl::Context *context = gl::getNonLostContext();
   7979 
   7980         if (context)
   7981         {
   7982             if (context->getClientVersion() < 3)
   7983             {
   7984                 return gl::error(GL_INVALID_OPERATION);
   7985             }
   7986 
   7987             switch (buffer)
   7988             {
   7989               case GL_COLOR:
   7990                 if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets()))
   7991                 {
   7992                     return gl::error(GL_INVALID_VALUE);
   7993                 }
   7994                 break;
   7995               default:
   7996                 return gl::error(GL_INVALID_ENUM);
   7997             }
   7998 
   7999             context->clearBufferuiv(buffer, drawbuffer, value);
   8000         }
   8001     }
   8002     catch (...)
   8003     {
   8004         return gl::error(GL_OUT_OF_MEMORY);
   8005     }
   8006 }
   8007 
   8008 void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value)
   8009 {
   8010     EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)",
   8011           buffer, drawbuffer, value);
   8012 
   8013     try
   8014     {
   8015         gl::Context *context = gl::getNonLostContext();
   8016 
   8017         if (context)
   8018         {
   8019             if (context->getClientVersion() < 3)
   8020             {
   8021                 return gl::error(GL_INVALID_OPERATION);
   8022             }
   8023 
   8024             switch (buffer)
   8025             {
   8026               case GL_COLOR:
   8027                 if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets()))
   8028                 {
   8029                     return gl::error(GL_INVALID_VALUE);
   8030                 }
   8031                 break;
   8032               case GL_DEPTH:
   8033                 if (drawbuffer != 0)
   8034                 {
   8035                     return gl::error(GL_INVALID_VALUE);
   8036                 }
   8037                 break;
   8038               default:
   8039                 return gl::error(GL_INVALID_ENUM);
   8040             }
   8041 
   8042             context->clearBufferfv(buffer, drawbuffer, value);
   8043         }
   8044     }
   8045     catch (...)
   8046     {
   8047         return gl::error(GL_OUT_OF_MEMORY);
   8048     }
   8049 }
   8050 
   8051 void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
   8052 {
   8053     EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)",
   8054           buffer, drawbuffer, depth, stencil);
   8055 
   8056     try
   8057     {
   8058         gl::Context *context = gl::getNonLostContext();
   8059 
   8060         if (context)
   8061         {
   8062             if (context->getClientVersion() < 3)
   8063             {
   8064                 return gl::error(GL_INVALID_OPERATION);
   8065             }
   8066 
   8067             switch (buffer)
   8068             {
   8069               case GL_DEPTH_STENCIL:
   8070                 if (drawbuffer != 0)
   8071                 {
   8072                     return gl::error(GL_INVALID_VALUE);
   8073                 }
   8074                 break;
   8075               default:
   8076                 return gl::error(GL_INVALID_ENUM);
   8077             }
   8078 
   8079             context->clearBufferfi(buffer, drawbuffer, depth, stencil);
   8080         }
   8081     }
   8082     catch (...)
   8083     {
   8084         return gl::error(GL_OUT_OF_MEMORY);
   8085     }
   8086 }
   8087 
   8088 const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index)
   8089 {
   8090     EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
   8091 
   8092     try
   8093     {
   8094         gl::Context *context = gl::getNonLostContext();
   8095 
   8096         if (context)
   8097         {
   8098             if (context->getClientVersion() < 3)
   8099             {
   8100                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLubyte*>(NULL));
   8101             }
   8102 
   8103             if (name != GL_EXTENSIONS)
   8104             {
   8105                 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLubyte*>(NULL));
   8106             }
   8107 
   8108             if (index >= context->getNumExtensions())
   8109             {
   8110                 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLubyte*>(NULL));
   8111             }
   8112 
   8113             return reinterpret_cast<const GLubyte*>(context->getExtensionString(index));
   8114         }
   8115     }
   8116     catch (...)
   8117     {
   8118         return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLubyte*>(NULL));
   8119     }
   8120 
   8121     return NULL;
   8122 }
   8123 
   8124 void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
   8125 {
   8126     EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)",
   8127           readTarget, writeTarget, readOffset, writeOffset, size);
   8128 
   8129     try
   8130     {
   8131         gl::Context *context = gl::getNonLostContext();
   8132 
   8133         if (context)
   8134         {
   8135             if (context->getClientVersion() < 3)
   8136             {
   8137                 return gl::error(GL_INVALID_OPERATION);
   8138             }
   8139 
   8140             if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget))
   8141             {
   8142                 return gl::error(GL_INVALID_ENUM);
   8143             }
   8144 
   8145             gl::Buffer *readBuffer = context->getTargetBuffer(readTarget);
   8146             gl::Buffer *writeBuffer = context->getTargetBuffer(writeTarget);
   8147 
   8148             if (!readBuffer || !writeBuffer)
   8149             {
   8150                 return gl::error(GL_INVALID_OPERATION);
   8151             }
   8152 
   8153             if (readBuffer->mapped() || writeBuffer->mapped())
   8154             {
   8155                 return gl::error(GL_INVALID_OPERATION);
   8156             }
   8157 
   8158             if (readOffset < 0 || writeOffset < 0 || size < 0 ||
   8159                 static_cast<unsigned int>(readOffset + size) > readBuffer->size() ||
   8160                 static_cast<unsigned int>(writeOffset + size) > writeBuffer->size())
   8161             {
   8162                 return gl::error(GL_INVALID_VALUE);
   8163             }
   8164 
   8165             if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size)
   8166             {
   8167                 return gl::error(GL_INVALID_VALUE);
   8168             }
   8169 
   8170             // TODO: Verify that readBuffer and writeBuffer are not currently mapped (GL_INVALID_OPERATION)
   8171 
   8172             // if size is zero, the copy is a successful no-op
   8173             if (size > 0)
   8174             {
   8175                 writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
   8176             }
   8177         }
   8178     }
   8179     catch (...)
   8180     {
   8181         return gl::error(GL_OUT_OF_MEMORY);
   8182     }
   8183 }
   8184 
   8185 void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices)
   8186 {
   8187     EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)",
   8188           program, uniformCount, uniformNames, uniformIndices);
   8189 
   8190     try
   8191     {
   8192         gl::Context *context = gl::getNonLostContext();
   8193 
   8194         if (context)
   8195         {
   8196             if (context->getClientVersion() < 3)
   8197             {
   8198                 return gl::error(GL_INVALID_OPERATION);
   8199             }
   8200 
   8201             if (uniformCount < 0)
   8202             {
   8203                 return gl::error(GL_INVALID_VALUE);
   8204             }
   8205 
   8206             gl::Program *programObject = context->getProgram(program);
   8207 
   8208             if (!programObject)
   8209             {
   8210                 if (context->getShader(program))
   8211                 {
   8212                     return gl::error(GL_INVALID_OPERATION);
   8213                 }
   8214                 else
   8215                 {
   8216                     return gl::error(GL_INVALID_VALUE);
   8217                 }
   8218             }
   8219 
   8220             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   8221             if (!programObject->isLinked() || !programBinary)
   8222             {
   8223                 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
   8224                 {
   8225                     uniformIndices[uniformId] = GL_INVALID_INDEX;
   8226                 }
   8227             }
   8228             else
   8229             {
   8230                 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
   8231                 {
   8232                     uniformIndices[uniformId] = programBinary->getUniformIndex(uniformNames[uniformId]);
   8233                 }
   8234             }
   8235         }
   8236     }
   8237     catch (...)
   8238     {
   8239         return gl::error(GL_OUT_OF_MEMORY);
   8240     }
   8241 }
   8242 
   8243 void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params)
   8244 {
   8245     EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
   8246           program, uniformCount, uniformIndices, pname, params);
   8247 
   8248     try
   8249     {
   8250         gl::Context *context = gl::getNonLostContext();
   8251 
   8252         if (context)
   8253         {
   8254             if (context->getClientVersion() < 3)
   8255             {
   8256                 return gl::error(GL_INVALID_OPERATION);
   8257             }
   8258 
   8259             if (uniformCount < 0)
   8260             {
   8261                 return gl::error(GL_INVALID_VALUE);
   8262             }
   8263 
   8264             gl::Program *programObject = context->getProgram(program);
   8265 
   8266             if (!programObject)
   8267             {
   8268                 if (context->getShader(program))
   8269                 {
   8270                     return gl::error(GL_INVALID_OPERATION);
   8271                 }
   8272                 else
   8273                 {
   8274                     return gl::error(GL_INVALID_VALUE);
   8275                 }
   8276             }
   8277 
   8278             switch (pname)
   8279             {
   8280               case GL_UNIFORM_TYPE:
   8281               case GL_UNIFORM_SIZE:
   8282               case GL_UNIFORM_NAME_LENGTH:
   8283               case GL_UNIFORM_BLOCK_INDEX:
   8284               case GL_UNIFORM_OFFSET:
   8285               case GL_UNIFORM_ARRAY_STRIDE:
   8286               case GL_UNIFORM_MATRIX_STRIDE:
   8287               case GL_UNIFORM_IS_ROW_MAJOR:
   8288                 break;
   8289               default:
   8290                 return gl::error(GL_INVALID_ENUM);
   8291             }
   8292 
   8293             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   8294 
   8295             if (!programBinary && uniformCount > 0)
   8296             {
   8297                 return gl::error(GL_INVALID_VALUE);
   8298             }
   8299 
   8300             for (int uniformId = 0; uniformId < uniformCount; uniformId++)
   8301             {
   8302                 const GLuint index = uniformIndices[uniformId];
   8303 
   8304                 if (index >= (GLuint)programBinary->getActiveUniformCount())
   8305                 {
   8306                     return gl::error(GL_INVALID_VALUE);
   8307                 }
   8308             }
   8309 
   8310             for (int uniformId = 0; uniformId < uniformCount; uniformId++)
   8311             {
   8312                 const GLuint index = uniformIndices[uniformId];
   8313                 params[uniformId] = programBinary->getActiveUniformi(index, pname);
   8314             }
   8315         }
   8316     }
   8317     catch (...)
   8318     {
   8319         return gl::error(GL_OUT_OF_MEMORY);
   8320     }
   8321 }
   8322 
   8323 GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName)
   8324 {
   8325     EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName);
   8326 
   8327     try
   8328     {
   8329         gl::Context *context = gl::getNonLostContext();
   8330 
   8331         if (context)
   8332         {
   8333             if (context->getClientVersion() < 3)
   8334             {
   8335                 return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
   8336             }
   8337 
   8338             gl::Program *programObject = context->getProgram(program);
   8339 
   8340             if (!programObject)
   8341             {
   8342                 if (context->getShader(program))
   8343                 {
   8344                     return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
   8345                 }
   8346                 else
   8347                 {
   8348                     return gl::error(GL_INVALID_VALUE, GL_INVALID_INDEX);
   8349                 }
   8350             }
   8351 
   8352             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   8353             if (!programBinary)
   8354             {
   8355                 return GL_INVALID_INDEX;
   8356             }
   8357 
   8358             return programBinary->getUniformBlockIndex(uniformBlockName);
   8359         }
   8360     }
   8361     catch (...)
   8362     {
   8363         return gl::error(GL_OUT_OF_MEMORY, 0);
   8364     }
   8365 
   8366     return 0;
   8367 }
   8368 
   8369 void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
   8370 {
   8371     EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
   8372           program, uniformBlockIndex, pname, params);
   8373 
   8374     try
   8375     {
   8376         gl::Context *context = gl::getNonLostContext();
   8377 
   8378         if (context)
   8379         {
   8380             if (context->getClientVersion() < 3)
   8381             {
   8382                 return gl::error(GL_INVALID_OPERATION);
   8383             }
   8384             gl::Program *programObject = context->getProgram(program);
   8385 
   8386             if (!programObject)
   8387             {
   8388                 if (context->getShader(program))
   8389                 {
   8390                     return gl::error(GL_INVALID_OPERATION);
   8391                 }
   8392                 else
   8393                 {
   8394                     return gl::error(GL_INVALID_VALUE);
   8395                 }
   8396             }
   8397 
   8398             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   8399 
   8400             if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
   8401             {
   8402                 return gl::error(GL_INVALID_VALUE);
   8403             }
   8404 
   8405             switch (pname)
   8406             {
   8407               case GL_UNIFORM_BLOCK_BINDING:
   8408                 *params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex));
   8409                 break;
   8410 
   8411               case GL_UNIFORM_BLOCK_DATA_SIZE:
   8412               case GL_UNIFORM_BLOCK_NAME_LENGTH:
   8413               case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
   8414               case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
   8415               case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
   8416               case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
   8417                 programBinary->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
   8418                 break;
   8419 
   8420               default:
   8421                 return gl::error(GL_INVALID_ENUM);
   8422             }
   8423         }
   8424     }
   8425     catch (...)
   8426     {
   8427         return gl::error(GL_OUT_OF_MEMORY);
   8428     }
   8429 }
   8430 
   8431 void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
   8432 {
   8433     EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)",
   8434           program, uniformBlockIndex, bufSize, length, uniformBlockName);
   8435 
   8436     try
   8437     {
   8438         gl::Context *context = gl::getNonLostContext();
   8439 
   8440         if (context)
   8441         {
   8442             if (context->getClientVersion() < 3)
   8443             {
   8444                 return gl::error(GL_INVALID_OPERATION);
   8445             }
   8446 
   8447             gl::Program *programObject = context->getProgram(program);
   8448 
   8449             if (!programObject)
   8450             {
   8451                 if (context->getShader(program))
   8452                 {
   8453                     return gl::error(GL_INVALID_OPERATION);
   8454                 }
   8455                 else
   8456                 {
   8457                     return gl::error(GL_INVALID_VALUE);
   8458                 }
   8459             }
   8460 
   8461             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   8462 
   8463             if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
   8464             {
   8465                 return gl::error(GL_INVALID_VALUE);
   8466             }
   8467 
   8468             programBinary->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
   8469         }
   8470     }
   8471     catch (...)
   8472     {
   8473         return gl::error(GL_OUT_OF_MEMORY);
   8474     }
   8475 }
   8476 
   8477 void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
   8478 {
   8479     EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)",
   8480           program, uniformBlockIndex, uniformBlockBinding);
   8481 
   8482     try
   8483     {
   8484         gl::Context *context = gl::getNonLostContext();
   8485 
   8486         if (context)
   8487         {
   8488             if (context->getClientVersion() < 3)
   8489             {
   8490                 return gl::error(GL_INVALID_OPERATION);
   8491             }
   8492 
   8493             if (uniformBlockBinding >= context->getMaximumCombinedUniformBufferBindings())
   8494             {
   8495                 return gl::error(GL_INVALID_VALUE);
   8496             }
   8497 
   8498             gl::Program *programObject = context->getProgram(program);
   8499 
   8500             if (!programObject)
   8501             {
   8502                 if (context->getShader(program))
   8503                 {
   8504                     return gl::error(GL_INVALID_OPERATION);
   8505                 }
   8506                 else
   8507                 {
   8508                     return gl::error(GL_INVALID_VALUE);
   8509                 }
   8510             }
   8511 
   8512             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   8513 
   8514             // if never linked, there won't be any uniform blocks
   8515             if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
   8516             {
   8517                 return gl::error(GL_INVALID_VALUE);
   8518             }
   8519 
   8520             programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
   8521         }
   8522     }
   8523     catch (...)
   8524     {
   8525         return gl::error(GL_OUT_OF_MEMORY);
   8526     }
   8527 }
   8528 
   8529 void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
   8530 {
   8531     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
   8532           mode, first, count, instanceCount);
   8533 
   8534     try
   8535     {
   8536         gl::Context *context = gl::getNonLostContext();
   8537 
   8538         if (context)
   8539         {
   8540             if (context->getClientVersion() < 3)
   8541             {
   8542                 return gl::error(GL_INVALID_OPERATION);
   8543             }
   8544 
   8545             // glDrawArraysInstanced
   8546             UNIMPLEMENTED();
   8547         }
   8548     }
   8549     catch (...)
   8550     {
   8551         return gl::error(GL_OUT_OF_MEMORY);
   8552     }
   8553 }
   8554 
   8555 void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount)
   8556 {
   8557     EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)",
   8558           mode, count, type, indices, instanceCount);
   8559 
   8560     try
   8561     {
   8562         gl::Context *context = gl::getNonLostContext();
   8563 
   8564         if (context)
   8565         {
   8566             if (context->getClientVersion() < 3)
   8567             {
   8568                 return gl::error(GL_INVALID_OPERATION);
   8569             }
   8570 
   8571             // glDrawElementsInstanced
   8572             UNIMPLEMENTED();
   8573         }
   8574     }
   8575     catch (...)
   8576     {
   8577         return gl::error(GL_OUT_OF_MEMORY);
   8578     }
   8579 }
   8580 
   8581 GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags)
   8582 {
   8583     EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
   8584 
   8585     try
   8586     {
   8587         gl::Context *context = gl::getNonLostContext();
   8588 
   8589         if (context)
   8590         {
   8591             if (context->getClientVersion() < 3)
   8592             {
   8593                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLsync>(0));
   8594             }
   8595 
   8596             if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
   8597             {
   8598                 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLsync>(0));
   8599             }
   8600 
   8601             if (flags != 0)
   8602             {
   8603                 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLsync>(0));
   8604             }
   8605 
   8606             return context->createFenceSync(condition);
   8607         }
   8608     }
   8609     catch (...)
   8610     {
   8611         return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLsync>(NULL));
   8612     }
   8613 
   8614     return NULL;
   8615 }
   8616 
   8617 GLboolean __stdcall glIsSync(GLsync sync)
   8618 {
   8619     EVENT("(GLsync sync = 0x%0.8p)", sync);
   8620 
   8621     try
   8622     {
   8623         gl::Context *context = gl::getNonLostContext();
   8624 
   8625         if (context)
   8626         {
   8627             if (context->getClientVersion() < 3)
   8628             {
   8629                 return gl::error(GL_INVALID_OPERATION, GL_FALSE);
   8630             }
   8631 
   8632             return (context->getFenceSync(sync) != NULL);
   8633         }
   8634     }
   8635     catch (...)
   8636     {
   8637         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   8638     }
   8639 
   8640     return GL_FALSE;
   8641 }
   8642 
   8643 void __stdcall glDeleteSync(GLsync sync)
   8644 {
   8645     EVENT("(GLsync sync = 0x%0.8p)", sync);
   8646 
   8647     try
   8648     {
   8649         gl::Context *context = gl::getNonLostContext();
   8650 
   8651         if (context)
   8652         {
   8653             if (context->getClientVersion() < 3)
   8654             {
   8655                 return gl::error(GL_INVALID_OPERATION);
   8656             }
   8657 
   8658             if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync))
   8659             {
   8660                 return gl::error(GL_INVALID_VALUE);
   8661             }
   8662 
   8663             context->deleteFenceSync(sync);
   8664         }
   8665     }
   8666     catch (...)
   8667     {
   8668         return gl::error(GL_OUT_OF_MEMORY);
   8669     }
   8670 }
   8671 
   8672 GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
   8673 {
   8674     EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
   8675           sync, flags, timeout);
   8676 
   8677     try
   8678     {
   8679         gl::Context *context = gl::getNonLostContext();
   8680 
   8681         if (context)
   8682         {
   8683             if (context->getClientVersion() < 3)
   8684             {
   8685                 return gl::error(GL_INVALID_OPERATION, GL_WAIT_FAILED);
   8686             }
   8687 
   8688             if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
   8689             {
   8690                 return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED);
   8691             }
   8692 
   8693             gl::FenceSync *fenceSync = context->getFenceSync(sync);
   8694 
   8695             if (!fenceSync)
   8696             {
   8697                 return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED);
   8698             }
   8699 
   8700             return fenceSync->clientWait(flags, timeout);
   8701         }
   8702     }
   8703     catch (...)
   8704     {
   8705         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   8706     }
   8707 
   8708     return GL_FALSE;
   8709 }
   8710 
   8711 void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
   8712 {
   8713     EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
   8714           sync, flags, timeout);
   8715 
   8716     try
   8717     {
   8718         gl::Context *context = gl::getNonLostContext();
   8719 
   8720         if (context)
   8721         {
   8722             if (context->getClientVersion() < 3)
   8723             {
   8724                 return gl::error(GL_INVALID_OPERATION);
   8725             }
   8726 
   8727             if (flags != 0)
   8728             {
   8729                 return gl::error(GL_INVALID_VALUE);
   8730             }
   8731 
   8732             if (timeout != GL_TIMEOUT_IGNORED)
   8733             {
   8734                 return gl::error(GL_INVALID_VALUE);
   8735             }
   8736 
   8737             gl::FenceSync *fenceSync = context->getFenceSync(sync);
   8738 
   8739             if (!fenceSync)
   8740             {
   8741                 return gl::error(GL_INVALID_VALUE);
   8742             }
   8743 
   8744             fenceSync->serverWait();
   8745         }
   8746     }
   8747     catch (...)
   8748     {
   8749         return gl::error(GL_OUT_OF_MEMORY);
   8750     }
   8751 }
   8752 
   8753 void __stdcall glGetInteger64v(GLenum pname, GLint64* params)
   8754 {
   8755     EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
   8756           pname, params);
   8757 
   8758     try
   8759     {
   8760         gl::Context *context = gl::getNonLostContext();
   8761 
   8762         if (context)
   8763         {
   8764             if (context->getClientVersion() < 3)
   8765             {
   8766                 return gl::error(GL_INVALID_OPERATION);
   8767             }
   8768 
   8769             GLenum nativeType;
   8770             unsigned int numParams = 0;
   8771             if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
   8772             {
   8773                 return;
   8774             }
   8775 
   8776             if (nativeType == GL_INT_64_ANGLEX)
   8777             {
   8778                 context->getInteger64v(pname, params);
   8779             }
   8780             else
   8781             {
   8782                 CastStateValues(context, nativeType, pname, numParams, params);
   8783             }
   8784         }
   8785     }
   8786     catch (...)
   8787     {
   8788         return gl::error(GL_OUT_OF_MEMORY);
   8789     }
   8790 }
   8791 
   8792 void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
   8793 {
   8794     EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)",
   8795           sync, pname, bufSize, length, values);
   8796 
   8797     try
   8798     {
   8799         gl::Context *context = gl::getNonLostContext();
   8800 
   8801         if (context)
   8802         {
   8803             if (context->getClientVersion() < 3)
   8804             {
   8805                 return gl::error(GL_INVALID_OPERATION);
   8806             }
   8807 
   8808             if (bufSize < 0)
   8809             {
   8810                 return gl::error(GL_INVALID_VALUE);
   8811             }
   8812 
   8813             gl::FenceSync *fenceSync = context->getFenceSync(sync);
   8814 
   8815             if (!fenceSync)
   8816             {
   8817                 return gl::error(GL_INVALID_VALUE);
   8818             }
   8819 
   8820             switch (pname)
   8821             {
   8822               case GL_OBJECT_TYPE:     values[0] = static_cast<GLint>(GL_SYNC_FENCE);              break;
   8823               case GL_SYNC_STATUS:     values[0] = static_cast<GLint>(fenceSync->getStatus());     break;
   8824               case GL_SYNC_CONDITION:  values[0] = static_cast<GLint>(fenceSync->getCondition());  break;
   8825               case GL_SYNC_FLAGS:      values[0] = 0;                                              break;
   8826 
   8827               default:
   8828                 return gl::error(GL_INVALID_ENUM);
   8829             }
   8830         }
   8831     }
   8832     catch (...)
   8833     {
   8834         return gl::error(GL_OUT_OF_MEMORY);
   8835     }
   8836 }
   8837 
   8838 void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
   8839 {
   8840     EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)",
   8841           target, index, data);
   8842 
   8843     try
   8844     {
   8845         gl::Context *context = gl::getNonLostContext();
   8846 
   8847         if (context)
   8848         {
   8849             if (context->getClientVersion() < 3)
   8850             {
   8851                 return gl::error(GL_INVALID_OPERATION);
   8852             }
   8853 
   8854             switch (target)
   8855             {
   8856               case GL_TRANSFORM_FEEDBACK_BUFFER_START:
   8857               case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
   8858               case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   8859                 if (index >= context->getMaxTransformFeedbackBufferBindings())
   8860                     return gl::error(GL_INVALID_VALUE);
   8861                 break;
   8862               case GL_UNIFORM_BUFFER_START:
   8863               case GL_UNIFORM_BUFFER_SIZE:
   8864               case GL_UNIFORM_BUFFER_BINDING:
   8865                 if (index >= context->getMaximumCombinedUniformBufferBindings())
   8866                     return gl::error(GL_INVALID_VALUE);
   8867                 break;
   8868               default:
   8869                 return gl::error(GL_INVALID_ENUM);
   8870             }
   8871 
   8872             if (!(context->getIndexedInteger64v(target, index, data)))
   8873             {
   8874                 GLenum nativeType;
   8875                 unsigned int numParams = 0;
   8876                 if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
   8877                     return gl::error(GL_INVALID_ENUM);
   8878 
   8879                 if (numParams == 0)
   8880                     return; // it is known that pname is valid, but there are no parameters to return
   8881 
   8882                 if (nativeType == GL_INT)
   8883                 {
   8884                     GLint *intParams = new GLint[numParams];
   8885 
   8886                     context->getIndexedIntegerv(target, index, intParams);
   8887 
   8888                     for (unsigned int i = 0; i < numParams; ++i)
   8889                     {
   8890                         data[i] = static_cast<GLint64>(intParams[i]);
   8891                     }
   8892 
   8893                     delete [] intParams;
   8894                 }
   8895                 else
   8896                 {
   8897                     UNREACHABLE();
   8898                 }
   8899             }
   8900         }
   8901     }
   8902     catch (...)
   8903     {
   8904         return gl::error(GL_OUT_OF_MEMORY);
   8905     }
   8906 }
   8907 
   8908 void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
   8909 {
   8910     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
   8911           target, pname, params);
   8912 
   8913     try
   8914     {
   8915         gl::Context *context = gl::getNonLostContext();
   8916 
   8917         if (context)
   8918         {
   8919             if (context->getClientVersion() < 3)
   8920             {
   8921                 return gl::error(GL_INVALID_OPERATION);
   8922             }
   8923 
   8924             if (!gl::ValidBufferTarget(context, target))
   8925             {
   8926                 return gl::error(GL_INVALID_ENUM);
   8927             }
   8928 
   8929             if (!gl::ValidBufferParameter(context, pname))
   8930             {
   8931                 return gl::error(GL_INVALID_ENUM);
   8932             }
   8933 
   8934             gl::Buffer *buffer = context->getTargetBuffer(target);
   8935 
   8936             if (!buffer)
   8937             {
   8938                 // A null buffer means that "0" is bound to the requested buffer target
   8939                 return gl::error(GL_INVALID_OPERATION);
   8940             }
   8941 
   8942             switch (pname)
   8943             {
   8944               case GL_BUFFER_USAGE:
   8945                 *params = static_cast<GLint64>(buffer->usage());
   8946                 break;
   8947               case GL_BUFFER_SIZE:
   8948                 *params = buffer->size();
   8949                 break;
   8950               case GL_BUFFER_ACCESS_FLAGS:
   8951                 *params = static_cast<GLint64>(buffer->accessFlags());
   8952                 break;
   8953               case GL_BUFFER_MAPPED:
   8954                 *params = static_cast<GLint64>(buffer->mapped());
   8955                 break;
   8956               case GL_BUFFER_MAP_OFFSET:
   8957                 *params = buffer->mapOffset();
   8958                 break;
   8959               case GL_BUFFER_MAP_LENGTH:
   8960                 *params = buffer->mapLength();
   8961                 break;
   8962               default: UNREACHABLE(); break;
   8963             }
   8964         }
   8965     }
   8966     catch (...)
   8967     {
   8968         return gl::error(GL_OUT_OF_MEMORY);
   8969     }
   8970 }
   8971 
   8972 void __stdcall glGenSamplers(GLsizei count, GLuint* samplers)
   8973 {
   8974     EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers);
   8975 
   8976     try
   8977     {
   8978         gl::Context *context = gl::getNonLostContext();
   8979 
   8980         if (context)
   8981         {
   8982             if (context->getClientVersion() < 3)
   8983             {
   8984                 return gl::error(GL_INVALID_OPERATION);
   8985             }
   8986 
   8987             if (count < 0)
   8988             {
   8989                 return gl::error(GL_INVALID_VALUE);
   8990             }
   8991 
   8992             for (int i = 0; i < count; i++)
   8993             {
   8994                 samplers[i] = context->createSampler();
   8995             }
   8996         }
   8997     }
   8998     catch (...)
   8999     {
   9000         return gl::error(GL_OUT_OF_MEMORY);
   9001     }
   9002 }
   9003 
   9004 void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers)
   9005 {
   9006     EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers);
   9007 
   9008     try
   9009     {
   9010         gl::Context *context = gl::getNonLostContext();
   9011 
   9012         if (context)
   9013         {
   9014             if (context->getClientVersion() < 3)
   9015             {
   9016                 return gl::error(GL_INVALID_OPERATION);
   9017             }
   9018 
   9019             if (count < 0)
   9020             {
   9021                 return gl::error(GL_INVALID_VALUE);
   9022             }
   9023 
   9024             for (int i = 0; i < count; i++)
   9025             {
   9026                 context->deleteSampler(samplers[i]);
   9027             }
   9028         }
   9029     }
   9030     catch (...)
   9031     {
   9032         return gl::error(GL_OUT_OF_MEMORY);
   9033     }
   9034 }
   9035 
   9036 GLboolean __stdcall glIsSampler(GLuint sampler)
   9037 {
   9038     EVENT("(GLuint sampler = %u)", sampler);
   9039 
   9040     try
   9041     {
   9042         gl::Context *context = gl::getNonLostContext();
   9043 
   9044         if (context)
   9045         {
   9046             if (context->getClientVersion() < 3)
   9047             {
   9048                 return gl::error(GL_INVALID_OPERATION, GL_FALSE);
   9049             }
   9050 
   9051             return context->isSampler(sampler);
   9052         }
   9053     }
   9054     catch (...)
   9055     {
   9056         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   9057     }
   9058 
   9059     return GL_FALSE;
   9060 }
   9061 
   9062 void __stdcall glBindSampler(GLuint unit, GLuint sampler)
   9063 {
   9064     EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
   9065 
   9066     try
   9067     {
   9068         gl::Context *context = gl::getNonLostContext();
   9069 
   9070         if (context)
   9071         {
   9072             if (context->getClientVersion() < 3)
   9073             {
   9074                 return gl::error(GL_INVALID_OPERATION);
   9075             }
   9076 
   9077             if (sampler != 0 && !context->isSampler(sampler))
   9078             {
   9079                 return gl::error(GL_INVALID_OPERATION);
   9080             }
   9081 
   9082             if (unit >= context->getMaximumCombinedTextureImageUnits())
   9083             {
   9084                 return gl::error(GL_INVALID_VALUE);
   9085             }
   9086 
   9087             context->bindSampler(unit, sampler);
   9088         }
   9089     }
   9090     catch (...)
   9091     {
   9092         return gl::error(GL_OUT_OF_MEMORY);
   9093     }
   9094 }
   9095 
   9096 void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
   9097 {
   9098     EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
   9099 
   9100     try
   9101     {
   9102         gl::Context *context = gl::getNonLostContext();
   9103 
   9104         if (context)
   9105         {
   9106             if (context->getClientVersion() < 3)
   9107             {
   9108                 return gl::error(GL_INVALID_OPERATION);
   9109             }
   9110 
   9111             if (!gl::ValidateSamplerObjectParameter(pname))
   9112             {
   9113                 return;
   9114             }
   9115 
   9116             if (!gl::ValidateTexParamParameters(context, pname, param))
   9117             {
   9118                 return;
   9119             }
   9120 
   9121             if (!context->isSampler(sampler))
   9122             {
   9123                 return gl::error(GL_INVALID_OPERATION);
   9124             }
   9125 
   9126             context->samplerParameteri(sampler, pname, param);
   9127         }
   9128     }
   9129     catch (...)
   9130     {
   9131         return gl::error(GL_OUT_OF_MEMORY);
   9132     }
   9133 }
   9134 
   9135 void __stdcall glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param)
   9136 {
   9137     glSamplerParameteri(sampler, pname, *param);
   9138 }
   9139 
   9140 void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
   9141 {
   9142     EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param);
   9143 
   9144     try
   9145     {
   9146         gl::Context *context = gl::getNonLostContext();
   9147 
   9148         if (context)
   9149         {
   9150             if (context->getClientVersion() < 3)
   9151             {
   9152                 return gl::error(GL_INVALID_OPERATION);
   9153             }
   9154 
   9155             if (!gl::ValidateSamplerObjectParameter(pname))
   9156             {
   9157                 return;
   9158             }
   9159 
   9160             if (!gl::ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
   9161             {
   9162                 return;
   9163             }
   9164 
   9165             if (!context->isSampler(sampler))
   9166             {
   9167                 return gl::error(GL_INVALID_OPERATION);
   9168             }
   9169 
   9170             context->samplerParameterf(sampler, pname, param);
   9171         }
   9172     }
   9173     catch (...)
   9174     {
   9175         return gl::error(GL_OUT_OF_MEMORY);
   9176     }
   9177 }
   9178 
   9179 void __stdcall glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param)
   9180 {
   9181     glSamplerParameterf(sampler, pname, *param);
   9182 }
   9183 
   9184 void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
   9185 {
   9186     EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params);
   9187 
   9188     try
   9189     {
   9190         gl::Context *context = gl::getNonLostContext();
   9191 
   9192         if (context)
   9193         {
   9194             if (context->getClientVersion() < 3)
   9195             {
   9196                 return gl::error(GL_INVALID_OPERATION);
   9197             }
   9198 
   9199             if (!gl::ValidateSamplerObjectParameter(pname))
   9200             {
   9201                 return;
   9202             }
   9203 
   9204             if (!context->isSampler(sampler))
   9205             {
   9206                 return gl::error(GL_INVALID_OPERATION);
   9207             }
   9208 
   9209             *params = context->getSamplerParameteri(sampler, pname);
   9210         }
   9211     }
   9212     catch (...)
   9213     {
   9214         return gl::error(GL_OUT_OF_MEMORY);
   9215     }
   9216 }
   9217 
   9218 void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
   9219 {
   9220     EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params);
   9221 
   9222     try
   9223     {
   9224         gl::Context *context = gl::getNonLostContext();
   9225 
   9226         if (context)
   9227         {
   9228             if (context->getClientVersion() < 3)
   9229             {
   9230                 return gl::error(GL_INVALID_OPERATION);
   9231             }
   9232 
   9233             if (!gl::ValidateSamplerObjectParameter(pname))
   9234             {
   9235                 return;
   9236             }
   9237 
   9238             if (!context->isSampler(sampler))
   9239             {
   9240                 return gl::error(GL_INVALID_OPERATION);
   9241             }
   9242 
   9243             *params = context->getSamplerParameterf(sampler, pname);
   9244         }
   9245     }
   9246     catch (...)
   9247     {
   9248         return gl::error(GL_OUT_OF_MEMORY);
   9249     }
   9250 }
   9251 
   9252 void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor)
   9253 {
   9254     EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
   9255 
   9256     try
   9257     {
   9258         if (index >= gl::MAX_VERTEX_ATTRIBS)
   9259         {
   9260             return gl::error(GL_INVALID_VALUE);
   9261         }
   9262 
   9263         gl::Context *context = gl::getNonLostContext();
   9264 
   9265         if (context)
   9266         {
   9267             if (context->getClientVersion() < 3)
   9268             {
   9269                 return gl::error(GL_INVALID_OPERATION);
   9270             }
   9271 
   9272             context->setVertexAttribDivisor(index, divisor);
   9273         }
   9274     }
   9275     catch (...)
   9276     {
   9277         return gl::error(GL_OUT_OF_MEMORY);
   9278     }
   9279 }
   9280 
   9281 void __stdcall glBindTransformFeedback(GLenum target, GLuint id)
   9282 {
   9283     EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
   9284 
   9285     try
   9286     {
   9287         gl::Context *context = gl::getNonLostContext();
   9288 
   9289         if (context)
   9290         {
   9291             if (context->getClientVersion() < 3)
   9292             {
   9293                 return gl::error(GL_INVALID_OPERATION);
   9294             }
   9295 
   9296             switch (target)
   9297             {
   9298               case GL_TRANSFORM_FEEDBACK:
   9299                 {
   9300                     // Cannot bind a transform feedback object if the current one is started and not paused (3.0.2 pg 85 section 2.14.1)
   9301                     gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
   9302                     if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
   9303                     {
   9304                         return gl::error(GL_INVALID_OPERATION);
   9305                     }
   9306 
   9307                     // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1)
   9308                     if (context->getTransformFeedback(id) == NULL)
   9309                     {
   9310                         return gl::error(GL_INVALID_OPERATION);
   9311                     }
   9312 
   9313                     context->bindTransformFeedback(id);
   9314                 }
   9315                 break;
   9316 
   9317               default:
   9318                 return gl::error(GL_INVALID_ENUM);
   9319             }
   9320         }
   9321     }
   9322     catch (...)
   9323     {
   9324         return gl::error(GL_OUT_OF_MEMORY);
   9325     }
   9326 }
   9327 
   9328 void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
   9329 {
   9330     EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids);
   9331 
   9332     try
   9333     {
   9334         gl::Context *context = gl::getNonLostContext();
   9335 
   9336         if (context)
   9337         {
   9338             if (context->getClientVersion() < 3)
   9339             {
   9340                 return gl::error(GL_INVALID_OPERATION);
   9341             }
   9342 
   9343             for (int i = 0; i < n; i++)
   9344             {
   9345                 context->deleteTransformFeedback(ids[i]);
   9346             }
   9347         }
   9348     }
   9349     catch (...)
   9350     {
   9351         return gl::error(GL_OUT_OF_MEMORY);
   9352     }
   9353 }
   9354 
   9355 void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids)
   9356 {
   9357     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
   9358 
   9359     try
   9360     {
   9361         gl::Context *context = gl::getNonLostContext();
   9362 
   9363         if (context)
   9364         {
   9365             if (context->getClientVersion() < 3)
   9366             {
   9367                 return gl::error(GL_INVALID_OPERATION);
   9368             }
   9369 
   9370             for (int i = 0; i < n; i++)
   9371             {
   9372                 ids[i] = context->createTransformFeedback();
   9373             }
   9374         }
   9375     }
   9376     catch (...)
   9377     {
   9378         return gl::error(GL_OUT_OF_MEMORY);
   9379     }
   9380 }
   9381 
   9382 GLboolean __stdcall glIsTransformFeedback(GLuint id)
   9383 {
   9384     EVENT("(GLuint id = %u)", id);
   9385 
   9386     try
   9387     {
   9388         gl::Context *context = gl::getNonLostContext();
   9389 
   9390         if (context)
   9391         {
   9392             if (context->getClientVersion() < 3)
   9393             {
   9394                 return gl::error(GL_INVALID_OPERATION, GL_FALSE);
   9395             }
   9396 
   9397             return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE);
   9398         }
   9399     }
   9400     catch (...)
   9401     {
   9402         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   9403     }
   9404 
   9405     return GL_FALSE;
   9406 }
   9407 
   9408 void __stdcall glPauseTransformFeedback(void)
   9409 {
   9410     EVENT("(void)");
   9411 
   9412     try
   9413     {
   9414         gl::Context *context = gl::getNonLostContext();
   9415 
   9416         if (context)
   9417         {
   9418             if (context->getClientVersion() < 3)
   9419             {
   9420                 return gl::error(GL_INVALID_OPERATION);
   9421             }
   9422 
   9423             gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
   9424             ASSERT(transformFeedback != NULL);
   9425 
   9426             // Current transform feedback must be started and not paused in order to pause (3.0.2 pg 86)
   9427             if (!transformFeedback->isStarted() || transformFeedback->isPaused())
   9428             {
   9429                 return gl::error(GL_INVALID_OPERATION);
   9430             }
   9431 
   9432             transformFeedback->pause();
   9433         }
   9434     }
   9435     catch (...)
   9436     {
   9437         return gl::error(GL_OUT_OF_MEMORY);
   9438     }
   9439 }
   9440 
   9441 void __stdcall glResumeTransformFeedback(void)
   9442 {
   9443     EVENT("(void)");
   9444 
   9445     try
   9446     {
   9447         gl::Context *context = gl::getNonLostContext();
   9448 
   9449         if (context)
   9450         {
   9451             if (context->getClientVersion() < 3)
   9452             {
   9453                 return gl::error(GL_INVALID_OPERATION);
   9454             }
   9455 
   9456             gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback();
   9457             ASSERT(transformFeedback != NULL);
   9458 
   9459             // Current transform feedback must be started and paused in order to resume (3.0.2 pg 86)
   9460             if (!transformFeedback->isStarted() || !transformFeedback->isPaused())
   9461             {
   9462                 return gl::error(GL_INVALID_OPERATION);
   9463             }
   9464 
   9465             transformFeedback->resume();
   9466         }
   9467     }
   9468     catch (...)
   9469     {
   9470         return gl::error(GL_OUT_OF_MEMORY);
   9471     }
   9472 }
   9473 
   9474 void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)
   9475 {
   9476     EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)",
   9477           program, bufSize, length, binaryFormat, binary);
   9478 
   9479     try
   9480     {
   9481         gl::Context *context = gl::getNonLostContext();
   9482 
   9483         if (context)
   9484         {
   9485             if (context->getClientVersion() < 3)
   9486             {
   9487                 return gl::error(GL_INVALID_OPERATION);
   9488             }
   9489 
   9490             // glGetProgramBinary
   9491             UNIMPLEMENTED();
   9492         }
   9493     }
   9494     catch (...)
   9495     {
   9496         return gl::error(GL_OUT_OF_MEMORY);
   9497     }
   9498 }
   9499 
   9500 void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length)
   9501 {
   9502     EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
   9503           program, binaryFormat, binary, length);
   9504 
   9505     try
   9506     {
   9507         gl::Context *context = gl::getNonLostContext();
   9508 
   9509         if (context)
   9510         {
   9511             if (context->getClientVersion() < 3)
   9512             {
   9513                 return gl::error(GL_INVALID_OPERATION);
   9514             }
   9515 
   9516             // glProgramBinary
   9517             UNIMPLEMENTED();
   9518         }
   9519     }
   9520     catch (...)
   9521     {
   9522         return gl::error(GL_OUT_OF_MEMORY);
   9523     }
   9524 }
   9525 
   9526 void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value)
   9527 {
   9528     EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)",
   9529           program, pname, value);
   9530 
   9531     try
   9532     {
   9533         gl::Context *context = gl::getNonLostContext();
   9534 
   9535         if (context)
   9536         {
   9537             if (context->getClientVersion() < 3)
   9538             {
   9539                 return gl::error(GL_INVALID_OPERATION);
   9540             }
   9541 
   9542             // glProgramParameteri
   9543             UNIMPLEMENTED();
   9544         }
   9545     }
   9546     catch (...)
   9547     {
   9548         return gl::error(GL_OUT_OF_MEMORY);
   9549     }
   9550 }
   9551 
   9552 void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments)
   9553 {
   9554     EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)",
   9555           target, numAttachments, attachments);
   9556 
   9557     try
   9558     {
   9559         gl::Context *context = gl::getNonLostContext();
   9560 
   9561         if (context)
   9562         {
   9563             if (context->getClientVersion() < 3)
   9564             {
   9565                 return gl::error(GL_INVALID_OPERATION);
   9566             }
   9567 
   9568             if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
   9569             {
   9570                 return;
   9571             }
   9572 
   9573             int maxDimension = context->getMaximumRenderbufferDimension();
   9574             context->invalidateFrameBuffer(target, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
   9575         }
   9576     }
   9577     catch (...)
   9578     {
   9579         return gl::error(GL_OUT_OF_MEMORY);
   9580     }
   9581 }
   9582 
   9583 void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height)
   9584 {
   9585     EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, "
   9586           "GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
   9587           target, numAttachments, attachments, x, y, width, height);
   9588 
   9589     try
   9590     {
   9591         gl::Context *context = gl::getNonLostContext();
   9592 
   9593         if (context)
   9594         {
   9595             if (context->getClientVersion() < 3)
   9596             {
   9597                 return gl::error(GL_INVALID_OPERATION);
   9598             }
   9599 
   9600             if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
   9601             {
   9602                 return;
   9603             }
   9604 
   9605             context->invalidateFrameBuffer(target, numAttachments, attachments, x, y, width, height);
   9606         }
   9607     }
   9608     catch (...)
   9609     {
   9610         return gl::error(GL_OUT_OF_MEMORY);
   9611     }
   9612 }
   9613 
   9614 void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
   9615 {
   9616     EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
   9617           target, levels, internalformat, width, height);
   9618 
   9619     try
   9620     {
   9621         gl::Context *context = gl::getNonLostContext();
   9622 
   9623         if (context)
   9624         {
   9625             if (context->getClientVersion() < 3)
   9626             {
   9627                 return gl::error(GL_INVALID_OPERATION);
   9628             }
   9629 
   9630             if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
   9631             {
   9632                 return;
   9633             }
   9634 
   9635             switch (target)
   9636             {
   9637               case GL_TEXTURE_2D:
   9638                 {
   9639                     gl::Texture2D *texture2d = context->getTexture2D();
   9640                     texture2d->storage(levels, internalformat, width, height);
   9641                 }
   9642                 break;
   9643 
   9644               case GL_TEXTURE_CUBE_MAP:
   9645                 {
   9646                     gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
   9647                     textureCube->storage(levels, internalformat, width);
   9648                 }
   9649                 break;
   9650 
   9651               default:
   9652                 return gl::error(GL_INVALID_ENUM);
   9653             }
   9654         }
   9655     }
   9656     catch (...)
   9657     {
   9658         return gl::error(GL_OUT_OF_MEMORY);
   9659     }
   9660 }
   9661 
   9662 void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
   9663 {
   9664     EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
   9665           "GLsizei height = %d, GLsizei depth = %d)",
   9666           target, levels, internalformat, width, height, depth);
   9667 
   9668     try
   9669     {
   9670         gl::Context *context = gl::getNonLostContext();
   9671 
   9672         if (context)
   9673         {
   9674             if (context->getClientVersion() < 3)
   9675             {
   9676                 return gl::error(GL_INVALID_OPERATION);
   9677             }
   9678 
   9679             if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth))
   9680             {
   9681                 return;
   9682             }
   9683 
   9684             switch (target)
   9685             {
   9686               case GL_TEXTURE_3D:
   9687                 {
   9688                     gl::Texture3D *texture3d = context->getTexture3D();
   9689                     texture3d->storage(levels, internalformat, width, height, depth);
   9690                 }
   9691                 break;
   9692 
   9693               case GL_TEXTURE_2D_ARRAY:
   9694                 {
   9695                     gl::Texture2DArray *texture2darray = context->getTexture2DArray();
   9696                     texture2darray->storage(levels, internalformat, width, height, depth);
   9697                 }
   9698                 break;
   9699 
   9700               default:
   9701                 UNREACHABLE();
   9702             }
   9703         }
   9704     }
   9705     catch (...)
   9706     {
   9707         return gl::error(GL_OUT_OF_MEMORY);
   9708     }
   9709 }
   9710 
   9711 void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
   9712 {
   9713     EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, "
   9714           "GLint* params = 0x%0.8p)",
   9715           target, internalformat, pname, bufSize, params);
   9716 
   9717     try
   9718     {
   9719         gl::Context *context = gl::getNonLostContext();
   9720 
   9721         if (context)
   9722         {
   9723             if (context->getClientVersion() < 3)
   9724             {
   9725                 return gl::error(GL_INVALID_OPERATION);
   9726             }
   9727 
   9728             if (!gl::IsColorRenderingSupported(internalformat, context) &&
   9729                 !gl::IsDepthRenderingSupported(internalformat, context) &&
   9730                 !gl::IsStencilRenderingSupported(internalformat, context))
   9731             {
   9732                 return gl::error(GL_INVALID_ENUM);
   9733             }
   9734 
   9735             if (target != GL_RENDERBUFFER)
   9736             {
   9737                 return gl::error(GL_INVALID_ENUM);
   9738             }
   9739 
   9740             if (bufSize < 0)
   9741             {
   9742                 return gl::error(GL_INVALID_VALUE);
   9743             }
   9744 
   9745             switch (pname)
   9746             {
   9747               case GL_NUM_SAMPLE_COUNTS:
   9748                 if (bufSize != 0)
   9749                     *params = context->getNumSampleCounts(internalformat);
   9750                 break;
   9751               case GL_SAMPLES:
   9752                 context->getSampleCounts(internalformat, bufSize, params);
   9753                 break;
   9754               default:
   9755                 return gl::error(GL_INVALID_ENUM);
   9756             }
   9757         }
   9758     }
   9759     catch (...)
   9760     {
   9761         return gl::error(GL_OUT_OF_MEMORY);
   9762     }
   9763 }
   9764 
   9765 // Extension functions
   9766 
   9767 void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   9768                                       GLbitfield mask, GLenum filter)
   9769 {
   9770     EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
   9771           "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
   9772           "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
   9773           srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
   9774 
   9775     try
   9776     {
   9777         gl::Context *context = gl::getNonLostContext();
   9778 
   9779         if (context)
   9780         {
   9781             if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
   9782                                                    dstX0, dstY0, dstX1, dstY1, mask, filter,
   9783                                                    true))
   9784             {
   9785                 return;
   9786             }
   9787 
   9788             context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
   9789                                      mask, filter);
   9790         }
   9791     }
   9792     catch (...)
   9793     {
   9794         return gl::error(GL_OUT_OF_MEMORY);
   9795     }
   9796 }
   9797 
   9798 void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
   9799                                GLint border, GLenum format, GLenum type, const GLvoid* pixels)
   9800 {
   9801     EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
   9802           "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
   9803           "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
   9804           target, level, internalformat, width, height, depth, border, format, type, pixels);
   9805 
   9806     try
   9807     {
   9808         UNIMPLEMENTED();   // FIXME
   9809     }
   9810     catch (...)
   9811     {
   9812         return gl::error(GL_OUT_OF_MEMORY);
   9813     }
   9814 }
   9815 
   9816 void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length,
   9817                                      GLenum *binaryFormat, void *binary)
   9818 {
   9819     EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)",
   9820           program, bufSize, length, binaryFormat, binary);
   9821 
   9822     try
   9823     {
   9824         gl::Context *context = gl::getNonLostContext();
   9825 
   9826         if (context)
   9827         {
   9828             gl::Program *programObject = context->getProgram(program);
   9829 
   9830             if (!programObject || !programObject->isLinked())
   9831             {
   9832                 return gl::error(GL_INVALID_OPERATION);
   9833             }
   9834 
   9835             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
   9836 
   9837             if (!programBinary)
   9838             {
   9839                 return gl::error(GL_INVALID_OPERATION);
   9840             }
   9841 
   9842             if (!programBinary->save(binary, bufSize, length))
   9843             {
   9844                 return gl::error(GL_INVALID_OPERATION);
   9845             }
   9846 
   9847             *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
   9848         }
   9849     }
   9850     catch (...)
   9851     {
   9852         return gl::error(GL_OUT_OF_MEMORY);
   9853     }
   9854 }
   9855 
   9856 void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
   9857                                   const void *binary, GLint length)
   9858 {
   9859     EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)",
   9860           program, binaryFormat, binary, length);
   9861 
   9862     try
   9863     {
   9864         gl::Context *context = gl::getNonLostContext();
   9865 
   9866         if (context)
   9867         {
   9868             if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
   9869             {
   9870                 return gl::error(GL_INVALID_ENUM);
   9871             }
   9872 
   9873             gl::Program *programObject = context->getProgram(program);
   9874 
   9875             if (!programObject)
   9876             {
   9877                 return gl::error(GL_INVALID_OPERATION);
   9878             }
   9879 
   9880             context->setProgramBinary(program, binary, length);
   9881         }
   9882     }
   9883     catch (...)
   9884     {
   9885         return gl::error(GL_OUT_OF_MEMORY);
   9886     }
   9887 }
   9888 
   9889 void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
   9890 {
   9891     EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
   9892 
   9893     try
   9894     {
   9895         gl::Context *context = gl::getNonLostContext();
   9896 
   9897         if (context)
   9898         {
   9899             if (n < 0 || (unsigned int)n > context->getMaximumRenderTargets())
   9900             {
   9901                 return gl::error(GL_INVALID_VALUE);
   9902             }
   9903 
   9904             if (context->getDrawFramebufferHandle() == 0)
   9905             {
   9906                 if (n != 1)
   9907                 {
   9908                     return gl::error(GL_INVALID_OPERATION);
   9909                 }
   9910 
   9911                 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
   9912                 {
   9913                     return gl::error(GL_INVALID_OPERATION);
   9914                 }
   9915             }
   9916             else
   9917             {
   9918                 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
   9919                 {
   9920                     const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
   9921                     if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
   9922                     {
   9923                         return gl::error(GL_INVALID_OPERATION);
   9924                     }
   9925                 }
   9926             }
   9927 
   9928             gl::Framebuffer *framebuffer = context->getDrawFramebuffer();
   9929 
   9930             for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
   9931             {
   9932                 framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]);
   9933             }
   9934 
   9935             for (int colorAttachment = n; colorAttachment < (int)context->getMaximumRenderTargets(); colorAttachment++)
   9936             {
   9937                 framebuffer->setDrawBufferState(colorAttachment, GL_NONE);
   9938             }
   9939         }
   9940     }
   9941     catch (...)
   9942     {
   9943         return gl::error(GL_OUT_OF_MEMORY);
   9944     }
   9945 }
   9946 
   9947 void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params)
   9948 {
   9949     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
   9950 
   9951     try
   9952     {
   9953         gl::Context *context = gl::getNonLostContext();
   9954 
   9955         if (context)
   9956         {
   9957             if (!context->supportsPBOs())
   9958             {
   9959                 return gl::error(GL_INVALID_OPERATION);
   9960             }
   9961 
   9962             if (!gl::ValidBufferTarget(context, target))
   9963             {
   9964                 return gl::error(GL_INVALID_ENUM);
   9965             }
   9966 
   9967             if (pname != GL_BUFFER_MAP_POINTER)
   9968             {
   9969                 return gl::error(GL_INVALID_ENUM);
   9970             }
   9971 
   9972             gl::Buffer *buffer = context->getTargetBuffer(target);
   9973 
   9974             if (!buffer || !buffer->mapped())
   9975             {
   9976                 *params = NULL;
   9977             }
   9978 
   9979             *params = buffer->mapPointer();
   9980         }
   9981     }
   9982     catch (...)
   9983     {
   9984         return gl::error(GL_OUT_OF_MEMORY);
   9985     }
   9986 }
   9987 
   9988 void * __stdcall glMapBufferOES(GLenum target, GLenum access)
   9989 {
   9990     EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access);
   9991 
   9992     try
   9993     {
   9994         gl::Context *context = gl::getNonLostContext();
   9995 
   9996         if (context)
   9997         {
   9998             if (!gl::ValidBufferTarget(context, target))
   9999             {
   10000                 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
   10001             }
   10002 
   10003             gl::Buffer *buffer = context->getTargetBuffer(target);
   10004 
   10005             if (buffer == NULL)
   10006             {
   10007                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
   10008             }
   10009 
   10010             if (access != GL_WRITE_ONLY_OES)
   10011             {
   10012                 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
   10013             }
   10014 
   10015             if (buffer->mapped())
   10016             {
   10017                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
   10018             }
   10019 
   10020             return buffer->mapRange(0, buffer->size(), GL_MAP_WRITE_BIT);
   10021         }
   10022     }
   10023     catch (...)
   10024     {
   10025         return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL));
   10026     }
   10027 
   10028     return NULL;
   10029 }
   10030 
   10031 GLboolean __stdcall glUnmapBufferOES(GLenum target)
   10032 {
   10033     EVENT("(GLenum target = 0x%X)", target);
   10034 
   10035     try
   10036     {
   10037         gl::Context *context = gl::getNonLostContext();
   10038 
   10039         if (context)
   10040         {
   10041             if (!gl::ValidBufferTarget(context, target))
   10042             {
   10043                 return gl::error(GL_INVALID_ENUM, GL_FALSE);
   10044             }
   10045 
   10046             gl::Buffer *buffer = context->getTargetBuffer(target);
   10047 
   10048             if (buffer == NULL || !buffer->mapped())
   10049             {
   10050                 return gl::error(GL_INVALID_OPERATION, GL_FALSE);
   10051             }
   10052 
   10053             // TODO: detect if we had corruption. if so, throw an error and return false.
   10054 
   10055             buffer->unmap();
   10056 
   10057             return GL_TRUE;
   10058         }
   10059     }
   10060     catch (...)
   10061     {
   10062         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
   10063     }
   10064 
   10065     return GL_FALSE;
   10066 }
   10067 
   10068 void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
   10069 {
   10070     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
   10071           target, offset, length, access);
   10072 
   10073     try
   10074     {
   10075         gl::Context *context = gl::getNonLostContext();
   10076 
   10077         if (context)
   10078         {
   10079             if (!gl::ValidBufferTarget(context, target))
   10080             {
   10081                 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
   10082             }
   10083 
   10084             if (offset < 0 || length < 0)
   10085             {
   10086                 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
   10087             }
   10088 
   10089             gl::Buffer *buffer = context->getTargetBuffer(target);
   10090 
   10091             if (buffer == NULL)
   10092             {
   10093                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
   10094             }
   10095 
   10096             // Check for buffer overflow
   10097             size_t offsetSize = static_cast<size_t>(offset);
   10098             size_t lengthSize = static_cast<size_t>(length);
   10099 
   10100             if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
   10101                 offsetSize + lengthSize > static_cast<size_t>(buffer->size()))
   10102             {
   10103                 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
   10104             }
   10105 
   10106             // Check for invalid bits in the mask
   10107             GLbitfield allAccessBits = GL_MAP_READ_BIT |
   10108                                        GL_MAP_WRITE_BIT |
   10109                                        GL_MAP_INVALIDATE_RANGE_BIT |
   10110                                        GL_MAP_INVALIDATE_BUFFER_BIT |
   10111                                        GL_MAP_FLUSH_EXPLICIT_BIT |
   10112                                        GL_MAP_UNSYNCHRONIZED_BIT;
   10113 
   10114             if (access & ~(allAccessBits))
   10115             {
   10116                 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
   10117             }
   10118 
   10119             if (length == 0 || buffer->mapped())
   10120             {
   10121                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
   10122             }
   10123 
   10124             // Check for invalid bit combinations
   10125             if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
   10126             {
   10127                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
   10128             }
   10129 
   10130             GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT |
   10131                                        GL_MAP_INVALIDATE_BUFFER_BIT |
   10132                                        GL_MAP_UNSYNCHRONIZED_BIT;
   10133 
   10134             if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
   10135             {
   10136                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
   10137             }
   10138 
   10139             if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
   10140             {
   10141                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
   10142             }
   10143 
   10144             return buffer->mapRange(offset, length, access);
   10145         }
   10146     }
   10147     catch (...)
   10148     {
   10149         return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL));
   10150     }
   10151 
   10152     return NULL;
   10153 }
   10154 
   10155 void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length)
   10156 {
   10157     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
   10158 
   10159     try
   10160     {
   10161         gl::Context *context = gl::getNonLostContext();
   10162 
   10163         if (context)
   10164         {
   10165             if (offset < 0 || length < 0)
   10166             {
   10167                 return gl::error(GL_INVALID_VALUE);
   10168             }
   10169 
   10170             if (!gl::ValidBufferTarget(context, target))
   10171             {
   10172                 return gl::error(GL_INVALID_ENUM);
   10173             }
   10174 
   10175             gl::Buffer *buffer = context->getTargetBuffer(target);
   10176 
   10177             if (buffer == NULL)
   10178             {
   10179                 return gl::error(GL_INVALID_OPERATION);
   10180             }
   10181 
   10182             if (!buffer->mapped() || (buffer->accessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
   10183             {
   10184                 return gl::error(GL_INVALID_OPERATION);
   10185             }
   10186 
   10187             // Check for buffer overflow
   10188             size_t offsetSize = static_cast<size_t>(offset);
   10189             size_t lengthSize = static_cast<size_t>(length);
   10190 
   10191             if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
   10192                 offsetSize + lengthSize > static_cast<size_t>(buffer->mapLength()))
   10193             {
   10194                 return gl::error(GL_INVALID_VALUE);
   10195             }
   10196 
   10197             // We do not currently support a non-trivial implementation of FlushMappedBufferRange
   10198         }
   10199     }
   10200     catch (...)
   10201     {
   10202         return gl::error(GL_OUT_OF_MEMORY);
   10203     }
   10204 }
   10205 
   10206 __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
   10207 {
   10208     struct Extension
   10209     {
   10210         const char *name;
   10211         __eglMustCastToProperFunctionPointerType address;
   10212     };
   10213 
   10214     static const Extension glExtensions[] =
   10215     {
   10216         {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
   10217         {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
   10218         {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
   10219         {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
   10220         {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
   10221         {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
   10222         {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
   10223         {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
   10224         {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
   10225         {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
   10226         {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
   10227         {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
   10228         {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
   10229         {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
   10230         {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
   10231         {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
   10232         {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
   10233         {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
   10234         {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
   10235         {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
   10236         {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
   10237         {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
   10238         {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
   10239         {"glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)glDrawBuffersEXT},
   10240         {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
   10241         {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
   10242         {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
   10243         {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES},
   10244         {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES},
   10245         {"glGetBufferPointervOES", (__eglMustCastToProperFunctionPointerType)glGetBufferPointervOES},
   10246         {"glMapBufferOES", (__eglMustCastToProperFunctionPointerType)glMapBufferOES},
   10247         {"glUnmapBufferOES", (__eglMustCastToProperFunctionPointerType)glUnmapBufferOES},
   10248         {"glMapBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)glMapBufferRangeEXT},
   10249         {"glFlushMappedBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)glFlushMappedBufferRangeEXT},    };
   10250 
   10251     for (unsigned int ext = 0; ext < ArraySize(glExtensions); ext++)
   10252     {
   10253         if (strcmp(procname, glExtensions[ext].name) == 0)
   10254         {
   10255             return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
   10256         }
   10257     }
   10258 
   10259     return NULL;
   10260 }
   10261 
   10262 // Non-public functions used by EGL
   10263 
   10264 bool __stdcall glBindTexImage(egl::Surface *surface)
   10265 {
   10266     EVENT("(egl::Surface* surface = 0x%0.8p)",
   10267           surface);
   10268 
   10269     try
   10270     {
   10271         gl::Context *context = gl::getNonLostContext();
   10272 
   10273         if (context)
   10274         {
   10275             gl::Texture2D *textureObject = context->getTexture2D();
   10276             ASSERT(textureObject != NULL);
   10277 
   10278             if (textureObject->isImmutable())
   10279             {
   10280                 return false;
   10281             }
   10282 
   10283             textureObject->bindTexImage(surface);
   10284         }
   10285     }
   10286     catch (...)
   10287     {
   10288         return gl::error(GL_OUT_OF_MEMORY, false);
   10289     }
   10290 
   10291     return true;
   10292 }
   10293 
   10294 }
   10295