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