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