OSDN Git Service

2ba91769fd45f29e3b7a0b1ae3bf5a6225aa603e
[android-x86/external-swiftshader.git] / src / OpenGL / libGLESv2 / libGLESv2.cpp
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
15
16 #include "main.h"
17 #include "mathutil.h"
18 #include "utilities.h"
19 #include "Buffer.h"
20 #include "Context.h"
21 #include "Fence.h"
22 #include "Framebuffer.h"
23 #include "Program.h"
24 #include "Renderbuffer.h"
25 #include "Shader.h"
26 #include "Texture.h"
27 #include "Query.h"
28 #include "TransformFeedback.h"
29 #include "VertexArray.h"
30 #include "common/debug.h"
31 #include "Common/Version.h"
32
33 #include <GLES2/gl2.h>
34 #include <GLES2/gl2ext.h>
35 #include <GLES3/gl3.h>
36
37 #include <limits>
38
39 #ifdef __ANDROID__
40 #include <cutils/log.h>
41 #endif
42
43 namespace es2
44 {
45
46 static bool validImageSize(GLint level, GLsizei width, GLsizei height)
47 {
48         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
49         {
50                 return false;
51         }
52
53         return true;
54 }
55
56 static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
57 {
58         GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);
59         if(validationError != GL_NONE)
60         {
61                 return error(validationError, false);
62         }
63
64         // [OpenGL ES 2.0.24] table 3.9
65         switch(textureFormat)
66         {
67         case GL_ALPHA:
68                 if(colorbufferFormat != GL_ALPHA &&
69                    colorbufferFormat != GL_RGBA &&
70                    colorbufferFormat != GL_RGBA4 &&
71                    colorbufferFormat != GL_RGB5_A1 &&
72                    colorbufferFormat != GL_RGBA8_OES &&
73                    colorbufferFormat != GL_BGRA8_EXT &&
74                    colorbufferFormat != GL_RGBA16F_EXT &&
75                    colorbufferFormat != GL_RGBA32F_EXT)
76                 {
77                         return error(GL_INVALID_OPERATION, false);
78                 }
79                 break;
80         case GL_LUMINANCE:
81         case GL_RGB:
82                 if(colorbufferFormat != GL_RGB &&
83                    colorbufferFormat != GL_RGB565 &&
84                    colorbufferFormat != GL_RGB8_OES &&
85                    colorbufferFormat != GL_RGBA &&
86                    colorbufferFormat != GL_RGBA4 &&
87                    colorbufferFormat != GL_RGB5_A1 &&
88                    colorbufferFormat != GL_RGBA8_OES &&
89                    colorbufferFormat != GL_RGB16F_EXT &&
90                    colorbufferFormat != GL_RGB32F_EXT &&
91                    colorbufferFormat != GL_BGRA8_EXT &&
92                    colorbufferFormat != GL_RGBA16F_EXT &&
93                    colorbufferFormat != GL_RGBA32F_EXT)
94                 {
95                         return error(GL_INVALID_OPERATION, false);
96                 }
97                 break;
98         case GL_LUMINANCE_ALPHA:
99         case GL_RGBA:
100                 if(colorbufferFormat != GL_RGBA &&
101                    colorbufferFormat != GL_RGBA4 &&
102                    colorbufferFormat != GL_RGB5_A1 &&
103                    colorbufferFormat != GL_RGBA8_OES &&
104                    colorbufferFormat != GL_BGRA8_EXT &&
105                    colorbufferFormat != GL_RGBA16F_EXT &&
106                    colorbufferFormat != GL_RGBA32F_EXT)
107                 {
108                         return error(GL_INVALID_OPERATION, false);
109                 }
110                 break;
111         case GL_DEPTH_COMPONENT:
112         case GL_DEPTH_STENCIL_OES:
113                 return error(GL_INVALID_OPERATION, false);
114         default:
115                 return error(GL_INVALID_ENUM, false);
116         }
117         return true;
118 }
119
120 void ActiveTexture(GLenum texture)
121 {
122         TRACE("(GLenum texture = 0x%X)", texture);
123
124         es2::Context *context = es2::getContext();
125
126         if(context)
127         {
128                 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
129                 {
130                         return error(GL_INVALID_ENUM);
131                 }
132
133                 context->setActiveSampler(texture - GL_TEXTURE0);
134         }
135 }
136
137 void AttachShader(GLuint program, GLuint shader)
138 {
139         TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
140
141         es2::Context *context = es2::getContext();
142
143         if(context)
144         {
145                 es2::Program *programObject = context->getProgram(program);
146                 es2::Shader *shaderObject = context->getShader(shader);
147
148                 if(!programObject)
149                 {
150                         if(context->getShader(program))
151                         {
152                                 return error(GL_INVALID_OPERATION);
153                         }
154                         else
155                         {
156                                 return error(GL_INVALID_VALUE);
157                         }
158                 }
159
160                 if(!shaderObject)
161                 {
162                         if(context->getProgram(shader))
163                         {
164                                 return error(GL_INVALID_OPERATION);
165                         }
166                         else
167                         {
168                                 return error(GL_INVALID_VALUE);
169                         }
170                 }
171
172                 if(!programObject->attachShader(shaderObject))
173                 {
174                         return error(GL_INVALID_OPERATION);
175                 }
176         }
177 }
178
179 void BeginQueryEXT(GLenum target, GLuint name)
180 {
181         TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
182
183         switch(target)
184         {
185         case GL_ANY_SAMPLES_PASSED_EXT:
186         case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
187                 break;
188         default:
189                 return error(GL_INVALID_ENUM);
190         }
191
192         if(name == 0)
193         {
194                 return error(GL_INVALID_OPERATION);
195         }
196
197         es2::Context *context = es2::getContext();
198
199         if(context)
200         {
201                 context->beginQuery(target, name);
202         }
203 }
204
205 void BindAttribLocation(GLuint program, GLuint index, const GLchar* name)
206 {
207         TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
208
209         if(index >= es2::MAX_VERTEX_ATTRIBS)
210         {
211                 return error(GL_INVALID_VALUE);
212         }
213
214         es2::Context *context = es2::getContext();
215
216         if(context)
217         {
218                 es2::Program *programObject = context->getProgram(program);
219
220                 if(!programObject)
221                 {
222                         if(context->getShader(program))
223                         {
224                                 return error(GL_INVALID_OPERATION);
225                         }
226                         else
227                         {
228                                 return error(GL_INVALID_VALUE);
229                         }
230                 }
231
232                 if(strncmp(name, "gl_", 3) == 0)
233                 {
234                         return error(GL_INVALID_OPERATION);
235                 }
236
237                 programObject->bindAttributeLocation(index, name);
238         }
239 }
240
241 void BindBuffer(GLenum target, GLuint buffer)
242 {
243         TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
244
245         es2::Context *context = es2::getContext();
246
247         if(context)
248         {
249                 GLint clientVersion = egl::getClientVersion();
250
251                 switch(target)
252                 {
253                 case GL_ARRAY_BUFFER:
254                         context->bindArrayBuffer(buffer);
255                         return;
256                 case GL_ELEMENT_ARRAY_BUFFER:
257                         context->bindElementArrayBuffer(buffer);
258                         return;
259                 case GL_COPY_READ_BUFFER:
260                         if(clientVersion >= 3)
261                         {
262                                 context->bindCopyReadBuffer(buffer);
263                                 return;
264                         }
265                         else return error(GL_INVALID_ENUM);
266                 case GL_COPY_WRITE_BUFFER:
267                         if(clientVersion >= 3)
268                         {
269                                 context->bindCopyWriteBuffer(buffer);
270                                 return;
271                         }
272                         else return error(GL_INVALID_ENUM);
273                 case GL_PIXEL_PACK_BUFFER:
274                         if(clientVersion >= 3)
275                         {
276                                 context->bindPixelPackBuffer(buffer);
277                                 return;
278                         }
279                         else return error(GL_INVALID_ENUM);
280                 case GL_PIXEL_UNPACK_BUFFER:
281                         if(clientVersion >= 3)
282                         {
283                                 context->bindPixelUnpackBuffer(buffer);
284                                 return;
285                         }
286                         else return error(GL_INVALID_ENUM);
287                 case GL_TRANSFORM_FEEDBACK_BUFFER:
288                         if(clientVersion >= 3)
289                         {
290                                 context->bindTransformFeedbackBuffer(buffer);
291                                 return;
292                         }
293                         else return error(GL_INVALID_ENUM);
294                 case GL_UNIFORM_BUFFER:
295                         if(clientVersion >= 3)
296                         {
297                                 context->bindGenericUniformBuffer(buffer);
298                                 return;
299                         }
300                         else return error(GL_INVALID_ENUM);
301                 default:
302                         return error(GL_INVALID_ENUM);
303                 }
304         }
305 }
306
307 void BindFramebuffer(GLenum target, GLuint framebuffer)
308 {
309         TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
310
311         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
312         {
313                 return error(GL_INVALID_ENUM);
314         }
315
316         es2::Context *context = es2::getContext();
317
318         if(context)
319         {
320                 if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
321                 {
322                         context->bindReadFramebuffer(framebuffer);
323                 }
324
325                 if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
326                 {
327                         context->bindDrawFramebuffer(framebuffer);
328                 }
329         }
330 }
331
332 void BindRenderbuffer(GLenum target, GLuint renderbuffer)
333 {
334         TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
335
336         if(target != GL_RENDERBUFFER)
337         {
338                 return error(GL_INVALID_ENUM);
339         }
340
341         es2::Context *context = es2::getContext();
342
343         if(context)
344         {
345                 // [OpenGL ES 2.0.25] Section 4.4.3 page 110
346                 // [OpenGL ES 3.0.4] Section 4.4.2 page 204
347                 // If renderbuffer is not zero, then the resulting renderbuffer object
348                 // is a new state vector, initialized with a zero-sized memory buffer.
349                 context->bindRenderbuffer(renderbuffer);
350         }
351 }
352
353 void BindTexture(GLenum target, GLuint texture)
354 {
355         TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
356
357         es2::Context *context = es2::getContext();
358
359         if(context)
360         {
361                 es2::Texture *textureObject = context->getTexture(texture);
362
363                 if(textureObject && textureObject->getTarget() != target && texture != 0)
364                 {
365                         return error(GL_INVALID_OPERATION);
366                 }
367
368                 GLint clientVersion = context->getClientVersion();
369
370                 switch(target)
371                 {
372                 case GL_TEXTURE_2D:
373                         context->bindTexture2D(texture);
374                         break;
375                 case GL_TEXTURE_CUBE_MAP:
376                         context->bindTextureCubeMap(texture);
377                         break;
378                 case GL_TEXTURE_EXTERNAL_OES:
379                         context->bindTextureExternal(texture);
380                         break;
381                 case GL_TEXTURE_2D_ARRAY:
382                         if(clientVersion < 3)
383                         {
384                                 return error(GL_INVALID_ENUM);
385                         }
386                         context->bindTexture2DArray(texture);
387                         break;
388                 case GL_TEXTURE_3D_OES:
389                         context->bindTexture3D(texture);
390                         break;
391                 default:
392                         return error(GL_INVALID_ENUM);
393                 }
394         }
395 }
396
397 void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
398 {
399         TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
400                 red, green, blue, alpha);
401
402         es2::Context* context = es2::getContext();
403
404         if(context)
405         {
406                 context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));
407         }
408 }
409
410 void BlendEquation(GLenum mode)
411 {
412         glBlendEquationSeparate(mode, mode);
413 }
414
415 void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
416 {
417         TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
418
419         switch(modeRGB)
420         {
421         case GL_FUNC_ADD:
422         case GL_FUNC_SUBTRACT:
423         case GL_FUNC_REVERSE_SUBTRACT:
424         case GL_MIN_EXT:
425         case GL_MAX_EXT:
426                 break;
427         default:
428                 return error(GL_INVALID_ENUM);
429         }
430
431         switch(modeAlpha)
432         {
433         case GL_FUNC_ADD:
434         case GL_FUNC_SUBTRACT:
435         case GL_FUNC_REVERSE_SUBTRACT:
436         case GL_MIN_EXT:
437         case GL_MAX_EXT:
438                 break;
439         default:
440                 return error(GL_INVALID_ENUM);
441         }
442
443         es2::Context *context = es2::getContext();
444
445         if(context)
446         {
447                 context->setBlendEquation(modeRGB, modeAlpha);
448         }
449 }
450
451 void BlendFunc(GLenum sfactor, GLenum dfactor)
452 {
453         glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
454 }
455
456 void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
457 {
458         TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
459               srcRGB, dstRGB, srcAlpha, dstAlpha);
460
461         GLint clientVersion = egl::getClientVersion();
462
463         switch(srcRGB)
464         {
465         case GL_ZERO:
466         case GL_ONE:
467         case GL_SRC_COLOR:
468         case GL_ONE_MINUS_SRC_COLOR:
469         case GL_DST_COLOR:
470         case GL_ONE_MINUS_DST_COLOR:
471         case GL_SRC_ALPHA:
472         case GL_ONE_MINUS_SRC_ALPHA:
473         case GL_DST_ALPHA:
474         case GL_ONE_MINUS_DST_ALPHA:
475         case GL_CONSTANT_COLOR:
476         case GL_ONE_MINUS_CONSTANT_COLOR:
477         case GL_CONSTANT_ALPHA:
478         case GL_ONE_MINUS_CONSTANT_ALPHA:
479         case GL_SRC_ALPHA_SATURATE:
480                 break;
481         default:
482                 return error(GL_INVALID_ENUM);
483         }
484
485         switch(dstRGB)
486         {
487         case GL_ZERO:
488         case GL_ONE:
489         case GL_SRC_COLOR:
490         case GL_ONE_MINUS_SRC_COLOR:
491         case GL_DST_COLOR:
492         case GL_ONE_MINUS_DST_COLOR:
493         case GL_SRC_ALPHA:
494         case GL_ONE_MINUS_SRC_ALPHA:
495         case GL_DST_ALPHA:
496         case GL_ONE_MINUS_DST_ALPHA:
497         case GL_CONSTANT_COLOR:
498         case GL_ONE_MINUS_CONSTANT_COLOR:
499         case GL_CONSTANT_ALPHA:
500         case GL_ONE_MINUS_CONSTANT_ALPHA:
501                 break;
502         case GL_SRC_ALPHA_SATURATE:
503                 if(clientVersion < 3)
504                 {
505                         return error(GL_INVALID_ENUM);
506                 }
507                 break;
508         default:
509                 return error(GL_INVALID_ENUM);
510         }
511
512         switch(srcAlpha)
513         {
514         case GL_ZERO:
515         case GL_ONE:
516         case GL_SRC_COLOR:
517         case GL_ONE_MINUS_SRC_COLOR:
518         case GL_DST_COLOR:
519         case GL_ONE_MINUS_DST_COLOR:
520         case GL_SRC_ALPHA:
521         case GL_ONE_MINUS_SRC_ALPHA:
522         case GL_DST_ALPHA:
523         case GL_ONE_MINUS_DST_ALPHA:
524         case GL_CONSTANT_COLOR:
525         case GL_ONE_MINUS_CONSTANT_COLOR:
526         case GL_CONSTANT_ALPHA:
527         case GL_ONE_MINUS_CONSTANT_ALPHA:
528         case GL_SRC_ALPHA_SATURATE:
529                 break;
530         default:
531                 return error(GL_INVALID_ENUM);
532         }
533
534         switch(dstAlpha)
535         {
536         case GL_ZERO:
537         case GL_ONE:
538         case GL_SRC_COLOR:
539         case GL_ONE_MINUS_SRC_COLOR:
540         case GL_DST_COLOR:
541         case GL_ONE_MINUS_DST_COLOR:
542         case GL_SRC_ALPHA:
543         case GL_ONE_MINUS_SRC_ALPHA:
544         case GL_DST_ALPHA:
545         case GL_ONE_MINUS_DST_ALPHA:
546         case GL_CONSTANT_COLOR:
547         case GL_ONE_MINUS_CONSTANT_COLOR:
548         case GL_CONSTANT_ALPHA:
549         case GL_ONE_MINUS_CONSTANT_ALPHA:
550                 break;
551         case GL_SRC_ALPHA_SATURATE:
552                 if(clientVersion < 3)
553                 {
554                         return error(GL_INVALID_ENUM);
555                 }
556                 break;
557         default:
558                 return error(GL_INVALID_ENUM);
559         }
560
561         es2::Context *context = es2::getContext();
562
563         if(context)
564         {
565                 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
566         }
567 }
568
569 void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
570 {
571         size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications
572
573         TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
574               target, size, data, usage);
575
576         if(size < 0)
577         {
578                 return error(GL_INVALID_VALUE);
579         }
580
581         GLint clientVersion = egl::getClientVersion();
582
583         switch(usage)
584         {
585         case GL_STREAM_DRAW:
586         case GL_STATIC_DRAW:
587         case GL_DYNAMIC_DRAW:
588                 break;
589         case GL_STREAM_READ:
590         case GL_STREAM_COPY:
591         case GL_STATIC_READ:
592         case GL_STATIC_COPY:
593         case GL_DYNAMIC_READ:
594         case GL_DYNAMIC_COPY:
595                 if(clientVersion < 3)
596                 {
597                         return error(GL_INVALID_ENUM);
598                 }
599                 break;
600         default:
601                 return error(GL_INVALID_ENUM);
602         }
603
604         es2::Context *context = es2::getContext();
605
606         if(context)
607         {
608                 es2::Buffer *buffer = nullptr;
609                 if(!context->getBuffer(target, &buffer))
610                 {
611                         return error(GL_INVALID_ENUM);
612                 }
613
614                 if(!buffer)
615                 {
616                         // A null buffer means that "0" is bound to the requested buffer target
617                         return error(GL_INVALID_OPERATION);
618                 }
619
620                 buffer->bufferData(data, size, usage);
621         }
622 }
623
624 void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
625 {
626         size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications
627         offset = static_cast<GLint>(offset);
628
629         TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
630               target, offset, size, data);
631
632         if(size < 0 || offset < 0)
633         {
634                 return error(GL_INVALID_VALUE);
635         }
636
637         es2::Context *context = es2::getContext();
638
639         if(context)
640         {
641                 es2::Buffer *buffer = nullptr;
642                 if(!context->getBuffer(target, &buffer))
643                 {
644                         return error(GL_INVALID_ENUM);
645                 }
646
647                 if(!buffer)
648                 {
649                         // A null buffer means that "0" is bound to the requested buffer target
650                         return error(GL_INVALID_OPERATION);
651                 }
652
653                 if(buffer->isMapped())
654                 {
655                         // It is an invalid operation to update an already mapped buffer
656                         return error(GL_INVALID_OPERATION);
657                 }
658
659                 if((size_t)size + offset > buffer->size())
660                 {
661                         return error(GL_INVALID_VALUE);
662                 }
663
664                 buffer->bufferSubData(data, size, offset);
665         }
666 }
667
668 GLenum CheckFramebufferStatus(GLenum target)
669 {
670         TRACE("(GLenum target = 0x%X)", target);
671
672         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
673         {
674                 return error(GL_INVALID_ENUM, 0);
675         }
676
677         es2::Context *context = es2::getContext();
678
679         if(context)
680         {
681                 es2::Framebuffer *framebuffer = nullptr;
682                 if(target == GL_READ_FRAMEBUFFER_ANGLE)
683                 {
684                         framebuffer = context->getReadFramebuffer();
685                 }
686                 else
687                 {
688                         framebuffer = context->getDrawFramebuffer();
689                 }
690
691                 return framebuffer->completeness();
692         }
693
694         return 0;
695 }
696
697 void Clear(GLbitfield mask)
698 {
699         TRACE("(GLbitfield mask = %X)", mask);
700
701         if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
702         {
703                 return error(GL_INVALID_VALUE);
704         }
705
706         es2::Context *context = es2::getContext();
707
708         if(context)
709         {
710                 context->clear(mask);
711         }
712 }
713
714 void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
715 {
716         TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
717               red, green, blue, alpha);
718
719         es2::Context *context = es2::getContext();
720
721         if(context)
722         {
723                 context->setClearColor(red, green, blue, alpha);
724         }
725 }
726
727 void ClearDepthf(GLclampf depth)
728 {
729         TRACE("(GLclampf depth = %f)", depth);
730
731         es2::Context *context = es2::getContext();
732
733         if(context)
734         {
735                 context->setClearDepth(depth);
736         }
737 }
738
739 void ClearStencil(GLint s)
740 {
741         TRACE("(GLint s = %d)", s);
742
743         es2::Context *context = es2::getContext();
744
745         if(context)
746         {
747                 context->setClearStencil(s);
748         }
749 }
750
751 void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
752 {
753         TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
754               red, green, blue, alpha);
755
756         es2::Context *context = es2::getContext();
757
758         if(context)
759         {
760                 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
761         }
762 }
763
764 void CompileShader(GLuint shader)
765 {
766         TRACE("(GLuint shader = %d)", shader);
767
768         es2::Context *context = es2::getContext();
769
770         if(context)
771         {
772                 es2::Shader *shaderObject = context->getShader(shader);
773
774                 if(!shaderObject)
775                 {
776                         if(context->getProgram(shader))
777                         {
778                                 return error(GL_INVALID_OPERATION);
779                         }
780                         else
781                         {
782                                 return error(GL_INVALID_VALUE);
783                         }
784                 }
785
786                 shaderObject->compile();
787         }
788 }
789
790 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
791                           GLint border, GLsizei imageSize, const GLvoid* data)
792 {
793         TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
794               "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
795               target, level, internalformat, width, height, border, imageSize, data);
796
797         if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
798         {
799                 return error(GL_INVALID_VALUE);
800         }
801
802         switch(internalformat)
803         {
804         case GL_DEPTH_COMPONENT:
805         case GL_DEPTH_COMPONENT16:
806         case GL_DEPTH_COMPONENT32_OES:
807         case GL_DEPTH_STENCIL_OES:
808         case GL_DEPTH24_STENCIL8_OES:
809                 return error(GL_INVALID_OPERATION);
810         default:
811                 {
812                         GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
813                         if(validationError != GL_NONE)
814                         {
815                                 return error(validationError);
816                         }
817                 }
818                 break;
819         }
820
821         if(border != 0)
822         {
823                 return error(GL_INVALID_VALUE);
824         }
825
826         es2::Context *context = es2::getContext();
827
828         if(context)
829         {
830                 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
831                 {
832                         return error(GL_INVALID_VALUE);
833                 }
834
835                 switch(target)
836                 {
837                 case GL_TEXTURE_2D:
838                         if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
839                            height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
840                         {
841                                 return error(GL_INVALID_VALUE);
842                         }
843                         break;
844                 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
845                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
846                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
847                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
848                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
849                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
850                         if(width != height)
851                         {
852                                 return error(GL_INVALID_VALUE);
853                         }
854
855                         if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
856                            height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
857                         {
858                                 return error(GL_INVALID_VALUE);
859                         }
860                         break;
861                 default:
862                         return error(GL_INVALID_ENUM);
863                 }
864
865                 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
866                 {
867                         return error(GL_INVALID_VALUE);
868                 }
869
870                 if(target == GL_TEXTURE_2D)
871                 {
872                         es2::Texture2D *texture = context->getTexture2D();
873
874                         if(!texture)
875                         {
876                                 return error(GL_INVALID_OPERATION);
877                         }
878
879                         GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
880                         if(validationError != GL_NONE)
881                         {
882                                 return error(validationError);
883                         }
884
885                         texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
886                 }
887                 else
888                 {
889                         es2::TextureCubeMap *texture = context->getTextureCubeMap();
890
891                         if(!texture)
892                         {
893                                 return error(GL_INVALID_OPERATION);
894                         }
895
896                         switch(target)
897                         {
898                         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
899                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
900                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
901                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
902                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
903                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
904                                 {
905
906                                         GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
907                                         if(validationError != GL_NONE)
908                                         {
909                                                 return error(validationError);
910                                         }
911
912                                         texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
913                                 }
914                                 break;
915                         default: UNREACHABLE(target);
916                         }
917                 }
918         }
919 }
920
921 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
922                              GLenum format, GLsizei imageSize, const GLvoid* data)
923 {
924         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
925               "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
926               "GLsizei imageSize = %d, const GLvoid* data = %p)",
927               target, level, xoffset, yoffset, width, height, format, imageSize, data);
928
929         if(!es2::IsTextureTarget(target))
930         {
931                 return error(GL_INVALID_ENUM);
932         }
933
934         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
935         {
936                 return error(GL_INVALID_VALUE);
937         }
938
939         if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
940         {
941                 return error(GL_INVALID_VALUE);
942         }
943
944         GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
945         if(validationError != GL_NONE)
946         {
947                 return error(validationError);
948         }
949
950         if(width == 0 || height == 0)
951         {
952                 return;
953         }
954
955         es2::Context *context = es2::getContext();
956
957         if(context)
958         {
959                 if(imageSize != egl::ComputeCompressedSize(width, height, format))
960                 {
961                         return error(GL_INVALID_VALUE);
962                 }
963
964                 if(xoffset % 4 != 0 || yoffset % 4 != 0)
965                 {
966                         // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
967                         return error(GL_INVALID_OPERATION);
968                 }
969
970                 GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);
971
972                 if(target == GL_TEXTURE_2D)
973                 {
974                         es2::Texture2D *texture = context->getTexture2D();
975
976                         GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
977
978                         if(validationError == GL_NONE)
979                         {
980                                 validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
981                         }
982
983                         if(validationError == GL_NONE)
984                         {
985                                 texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
986                         }
987                         else
988                         {
989                                 return error(validationError);
990                         }
991                 }
992                 else if(es2::IsCubemapTextureTarget(target))
993                 {
994                         es2::TextureCubeMap *texture = context->getTextureCubeMap();
995
996                         GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
997
998                         if(validationError == GL_NONE)
999                         {
1000                                 validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
1001                         }
1002
1003                         if(validationError == GL_NONE)
1004                         {
1005                                 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
1006                         }
1007                         else
1008                         {
1009                                 return error(validationError);
1010                         }
1011                 }
1012                 else UNREACHABLE(target);
1013         }
1014 }
1015
1016 void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1017 {
1018         TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
1019               "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
1020               target, level, internalformat, x, y, width, height, border);
1021
1022         if(!validImageSize(level, width, height))
1023         {
1024                 return error(GL_INVALID_VALUE);
1025         }
1026
1027         if(border != 0)
1028         {
1029                 return error(GL_INVALID_VALUE);
1030         }
1031
1032         es2::Context *context = es2::getContext();
1033
1034         if(context)
1035         {
1036                 switch(target)
1037                 {
1038                 case GL_TEXTURE_2D:
1039                         if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1040                            height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
1041                         {
1042                                 return error(GL_INVALID_VALUE);
1043                         }
1044                         break;
1045                 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1046                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1047                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1048                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1049                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1050                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1051                         if(width != height)
1052                         {
1053                                 return error(GL_INVALID_VALUE);
1054                         }
1055
1056                         if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1057                            height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1058                         {
1059                                 return error(GL_INVALID_VALUE);
1060                         }
1061                         break;
1062                 default:
1063                         return error(GL_INVALID_ENUM);
1064                 }
1065
1066                 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
1067
1068                 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1069                 {
1070                         return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1071                 }
1072
1073                 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
1074
1075                 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
1076                 {
1077                         return error(GL_INVALID_OPERATION);
1078                 }
1079
1080                 GLenum colorbufferFormat = source->getFormat();
1081
1082                 if(!validateColorBufferFormat(internalformat, colorbufferFormat))
1083                 {
1084                         return;
1085                 }
1086
1087                 if(target == GL_TEXTURE_2D)
1088                 {
1089                         es2::Texture2D *texture = context->getTexture2D();
1090
1091                         if(!texture)
1092                         {
1093                                 return error(GL_INVALID_OPERATION);
1094                         }
1095
1096                         texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1097                 }
1098                 else if(es2::IsCubemapTextureTarget(target))
1099                 {
1100                         es2::TextureCubeMap *texture = context->getTextureCubeMap();
1101
1102                         if(!texture)
1103                         {
1104                                 return error(GL_INVALID_OPERATION);
1105                         }
1106
1107                         texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1108                 }
1109                 else UNREACHABLE(target);
1110         }
1111 }
1112
1113 void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1114 {
1115         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1116               "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1117               target, level, xoffset, yoffset, x, y, width, height);
1118
1119         if(!es2::IsTextureTarget(target))
1120         {
1121                 return error(GL_INVALID_ENUM);
1122         }
1123
1124         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1125         {
1126                 return error(GL_INVALID_VALUE);
1127         }
1128
1129         if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1130         {
1131                 return error(GL_INVALID_VALUE);
1132         }
1133
1134         if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1135         {
1136                 return error(GL_INVALID_VALUE);
1137         }
1138
1139         if(width == 0 || height == 0)
1140         {
1141                 return;
1142         }
1143
1144         es2::Context *context = es2::getContext();
1145
1146         if(context)
1147         {
1148                 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
1149
1150                 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1151                 {
1152                         return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1153                 }
1154
1155                 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
1156
1157                 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
1158                 {
1159                         return error(GL_INVALID_OPERATION);
1160                 }
1161
1162                 es2::Texture *texture = nullptr;
1163
1164                 if(target == GL_TEXTURE_2D)
1165                 {
1166                         texture = context->getTexture2D();
1167                 }
1168                 else if(es2::IsCubemapTextureTarget(target))
1169                 {
1170                         texture = context->getTextureCubeMap();
1171                 }
1172                 else UNREACHABLE(target);
1173
1174                 GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);
1175                 if(validationError != GL_NONE)
1176                 {
1177                         return error(validationError);
1178                 }
1179
1180                 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
1181         }
1182 }
1183
1184 GLuint CreateProgram(void)
1185 {
1186         TRACE("()");
1187
1188         es2::Context *context = es2::getContext();
1189
1190         if(context)
1191         {
1192                 return context->createProgram();
1193         }
1194
1195         return 0;
1196 }
1197
1198 GLuint CreateShader(GLenum type)
1199 {
1200         TRACE("(GLenum type = 0x%X)", type);
1201
1202         es2::Context *context = es2::getContext();
1203
1204         if(context)
1205         {
1206                 switch(type)
1207                 {
1208                 case GL_FRAGMENT_SHADER:
1209                 case GL_VERTEX_SHADER:
1210                         return context->createShader(type);
1211                 default:
1212                         return error(GL_INVALID_ENUM, 0);
1213                 }
1214         }
1215
1216         return 0;
1217 }
1218
1219 void CullFace(GLenum mode)
1220 {
1221         TRACE("(GLenum mode = 0x%X)", mode);
1222
1223         switch(mode)
1224         {
1225         case GL_FRONT:
1226         case GL_BACK:
1227         case GL_FRONT_AND_BACK:
1228                 {
1229                         es2::Context *context = es2::getContext();
1230
1231                         if(context)
1232                         {
1233                                 context->setCullMode(mode);
1234                         }
1235                 }
1236                 break;
1237         default:
1238                 return error(GL_INVALID_ENUM);
1239         }
1240 }
1241
1242 void DeleteBuffers(GLsizei n, const GLuint* buffers)
1243 {
1244         TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
1245
1246         if(n < 0)
1247         {
1248                 return error(GL_INVALID_VALUE);
1249         }
1250
1251         es2::Context *context = es2::getContext();
1252
1253         if(context)
1254         {
1255                 for(int i = 0; i < n; i++)
1256                 {
1257                         context->deleteBuffer(buffers[i]);
1258                 }
1259         }
1260 }
1261
1262 void DeleteFencesNV(GLsizei n, const GLuint* fences)
1263 {
1264         TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
1265
1266         if(n < 0)
1267         {
1268                 return error(GL_INVALID_VALUE);
1269         }
1270
1271         es2::Context *context = es2::getContext();
1272
1273         if(context)
1274         {
1275                 for(int i = 0; i < n; i++)
1276                 {
1277                         context->deleteFence(fences[i]);
1278                 }
1279         }
1280 }
1281
1282 void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1283 {
1284         TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
1285
1286         if(n < 0)
1287         {
1288                 return error(GL_INVALID_VALUE);
1289         }
1290
1291         es2::Context *context = es2::getContext();
1292
1293         if(context)
1294         {
1295                 for(int i = 0; i < n; i++)
1296                 {
1297                         if(framebuffers[i] != 0)
1298                         {
1299                                 context->deleteFramebuffer(framebuffers[i]);
1300                         }
1301                 }
1302         }
1303 }
1304
1305 void DeleteProgram(GLuint program)
1306 {
1307         TRACE("(GLuint program = %d)", program);
1308
1309         if(program == 0)
1310         {
1311                 return;
1312         }
1313
1314         es2::Context *context = es2::getContext();
1315
1316         if(context)
1317         {
1318                 if(!context->getProgram(program))
1319                 {
1320                         if(context->getShader(program))
1321                         {
1322                                 return error(GL_INVALID_OPERATION);
1323                         }
1324                         else
1325                         {
1326                                 return error(GL_INVALID_VALUE);
1327                         }
1328                 }
1329
1330                 context->deleteProgram(program);
1331         }
1332 }
1333
1334 void DeleteQueriesEXT(GLsizei n, const GLuint *ids)
1335 {
1336         TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
1337
1338         if(n < 0)
1339         {
1340                 return error(GL_INVALID_VALUE);
1341         }
1342
1343         es2::Context *context = es2::getContext();
1344
1345         if(context)
1346         {
1347                 for(int i = 0; i < n; i++)
1348                 {
1349                         context->deleteQuery(ids[i]);
1350                 }
1351         }
1352 }
1353
1354 void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1355 {
1356         TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
1357
1358         if(n < 0)
1359         {
1360                 return error(GL_INVALID_VALUE);
1361         }
1362
1363         es2::Context *context = es2::getContext();
1364
1365         if(context)
1366         {
1367                 for(int i = 0; i < n; i++)
1368                 {
1369                         context->deleteRenderbuffer(renderbuffers[i]);
1370                 }
1371         }
1372 }
1373
1374 void DeleteShader(GLuint shader)
1375 {
1376         TRACE("(GLuint shader = %d)", shader);
1377
1378         if(shader == 0)
1379         {
1380                 return;
1381         }
1382
1383         es2::Context *context = es2::getContext();
1384
1385         if(context)
1386         {
1387                 if(!context->getShader(shader))
1388                 {
1389                         if(context->getProgram(shader))
1390                         {
1391                                 return error(GL_INVALID_OPERATION);
1392                         }
1393                         else
1394                         {
1395                                 return error(GL_INVALID_VALUE);
1396                         }
1397                 }
1398
1399                 context->deleteShader(shader);
1400         }
1401 }
1402
1403 void DeleteTextures(GLsizei n, const GLuint* textures)
1404 {
1405         TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
1406
1407         if(n < 0)
1408         {
1409                 return error(GL_INVALID_VALUE);
1410         }
1411
1412         es2::Context *context = es2::getContext();
1413
1414         if(context)
1415         {
1416                 for(int i = 0; i < n; i++)
1417                 {
1418                         if(textures[i] != 0)
1419                         {
1420                                 context->deleteTexture(textures[i]);
1421                         }
1422                 }
1423         }
1424 }
1425
1426 void DepthFunc(GLenum func)
1427 {
1428         TRACE("(GLenum func = 0x%X)", func);
1429
1430         switch(func)
1431         {
1432         case GL_NEVER:
1433         case GL_ALWAYS:
1434         case GL_LESS:
1435         case GL_LEQUAL:
1436         case GL_EQUAL:
1437         case GL_GREATER:
1438         case GL_GEQUAL:
1439         case GL_NOTEQUAL:
1440                 break;
1441         default:
1442                 return error(GL_INVALID_ENUM);
1443         }
1444
1445         es2::Context *context = es2::getContext();
1446
1447         if(context)
1448         {
1449                 context->setDepthFunc(func);
1450         }
1451 }
1452
1453 void DepthMask(GLboolean flag)
1454 {
1455         TRACE("(GLboolean flag = %d)", flag);
1456
1457         es2::Context *context = es2::getContext();
1458
1459         if(context)
1460         {
1461                 context->setDepthMask(flag != GL_FALSE);
1462         }
1463 }
1464
1465 void DepthRangef(GLclampf zNear, GLclampf zFar)
1466 {
1467         TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1468
1469         es2::Context *context = es2::getContext();
1470
1471         if(context)
1472         {
1473                 context->setDepthRange(zNear, zFar);
1474         }
1475 }
1476
1477 void DetachShader(GLuint program, GLuint shader)
1478 {
1479         TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
1480
1481         es2::Context *context = es2::getContext();
1482
1483         if(context)
1484         {
1485
1486                 es2::Program *programObject = context->getProgram(program);
1487                 es2::Shader *shaderObject = context->getShader(shader);
1488
1489                 if(!programObject)
1490                 {
1491                         es2::Shader *shaderByProgramHandle;
1492                         shaderByProgramHandle = context->getShader(program);
1493                         if(!shaderByProgramHandle)
1494                         {
1495                                 return error(GL_INVALID_VALUE);
1496                         }
1497                         else
1498                         {
1499                                 return error(GL_INVALID_OPERATION);
1500                         }
1501                 }
1502
1503                 if(!shaderObject)
1504                 {
1505                         es2::Program *programByShaderHandle = context->getProgram(shader);
1506                         if(!programByShaderHandle)
1507                         {
1508                                 return error(GL_INVALID_VALUE);
1509                         }
1510                         else
1511                         {
1512                                 return error(GL_INVALID_OPERATION);
1513                         }
1514                 }
1515
1516                 if(!programObject->detachShader(shaderObject))
1517                 {
1518                         return error(GL_INVALID_OPERATION);
1519                 }
1520         }
1521 }
1522
1523 void Disable(GLenum cap)
1524 {
1525         TRACE("(GLenum cap = 0x%X)", cap);
1526
1527         es2::Context *context = es2::getContext();
1528
1529         if(context)
1530         {
1531                 switch(cap)
1532                 {
1533                 case GL_CULL_FACE:                     context->setCullFaceEnabled(false);                   break;
1534                 case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(false);          break;
1535                 case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(false);      break;
1536                 case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(false);             break;
1537                 case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(false);                break;
1538                 case GL_STENCIL_TEST:                  context->setStencilTestEnabled(false);                break;
1539                 case GL_DEPTH_TEST:                    context->setDepthTestEnabled(false);                  break;
1540                 case GL_BLEND:                         context->setBlendEnabled(false);                      break;
1541                 case GL_DITHER:                        context->setDitherEnabled(false);                     break;
1542                 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(false); break;
1543                 case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(false);          break;
1544                 default:
1545                         return error(GL_INVALID_ENUM);
1546                 }
1547         }
1548 }
1549
1550 void DisableVertexAttribArray(GLuint index)
1551 {
1552         TRACE("(GLuint index = %d)", index);
1553
1554         if(index >= es2::MAX_VERTEX_ATTRIBS)
1555         {
1556                 return error(GL_INVALID_VALUE);
1557         }
1558
1559         es2::Context *context = es2::getContext();
1560
1561         if(context)
1562         {
1563                 context->setVertexAttribArrayEnabled(index, false);
1564         }
1565 }
1566
1567 void DrawArrays(GLenum mode, GLint first, GLsizei count)
1568 {
1569         TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1570
1571         switch(mode)
1572         {
1573         case GL_POINTS:
1574         case GL_LINES:
1575         case GL_LINE_LOOP:
1576         case GL_LINE_STRIP:
1577         case GL_TRIANGLES:
1578         case GL_TRIANGLE_FAN:
1579         case GL_TRIANGLE_STRIP:
1580                 break;
1581         default:
1582                 return error(GL_INVALID_ENUM);
1583         }
1584
1585         if(count < 0 || first < 0)
1586         {
1587                 return error(GL_INVALID_VALUE);
1588         }
1589
1590         es2::Context *context = es2::getContext();
1591
1592         if(context)
1593         {
1594                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1595                 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1596                 {
1597                         return error(GL_INVALID_OPERATION);
1598                 }
1599
1600                 context->drawArrays(mode, first, count);
1601         }
1602 }
1603
1604 void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
1605 {
1606         TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
1607               mode, count, type, indices);
1608
1609         switch(mode)
1610         {
1611         case GL_POINTS:
1612         case GL_LINES:
1613         case GL_LINE_LOOP:
1614         case GL_LINE_STRIP:
1615         case GL_TRIANGLES:
1616         case GL_TRIANGLE_FAN:
1617         case GL_TRIANGLE_STRIP:
1618                 break;
1619         default:
1620                 return error(GL_INVALID_ENUM);
1621         }
1622
1623         if(count < 0)
1624         {
1625                 return error(GL_INVALID_VALUE);
1626         }
1627
1628         es2::Context *context = es2::getContext();
1629
1630         if(context)
1631         {
1632                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1633                 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1634                 {
1635                         return error(GL_INVALID_OPERATION);
1636                 }
1637
1638                 switch(type)
1639                 {
1640                 case GL_UNSIGNED_BYTE:
1641                 case GL_UNSIGNED_SHORT:
1642                 case GL_UNSIGNED_INT:
1643                         break;
1644                 default:
1645                         return error(GL_INVALID_ENUM);
1646                 }
1647
1648                 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices);
1649         }
1650 }
1651
1652 void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1653 {
1654         TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1655                 mode, first, count, instanceCount);
1656
1657         switch(mode)
1658         {
1659         case GL_POINTS:
1660         case GL_LINES:
1661         case GL_LINE_LOOP:
1662         case GL_LINE_STRIP:
1663         case GL_TRIANGLES:
1664         case GL_TRIANGLE_FAN:
1665         case GL_TRIANGLE_STRIP:
1666                 break;
1667         default:
1668                 return error(GL_INVALID_ENUM);
1669         }
1670
1671         if(count < 0 || instanceCount < 0)
1672         {
1673                 return error(GL_INVALID_VALUE);
1674         }
1675
1676         es2::Context *context = es2::getContext();
1677
1678         if(context)
1679         {
1680                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1681                 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1682                 {
1683                         return error(GL_INVALID_OPERATION);
1684                 }
1685
1686                 context->drawArrays(mode, first, count, instanceCount);
1687         }
1688 }
1689
1690 void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
1691 {
1692         TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
1693                 mode, count, type, indices, instanceCount);
1694
1695         switch(mode)
1696         {
1697         case GL_POINTS:
1698         case GL_LINES:
1699         case GL_LINE_LOOP:
1700         case GL_LINE_STRIP:
1701         case GL_TRIANGLES:
1702         case GL_TRIANGLE_FAN:
1703         case GL_TRIANGLE_STRIP:
1704                 break;
1705         default:
1706                 return error(GL_INVALID_ENUM);
1707         }
1708
1709         switch(type)
1710         {
1711         case GL_UNSIGNED_BYTE:
1712         case GL_UNSIGNED_SHORT:
1713         case GL_UNSIGNED_INT:
1714                 break;
1715         default:
1716                 return error(GL_INVALID_ENUM);
1717         }
1718
1719         if(count < 0 || instanceCount < 0)
1720         {
1721                 return error(GL_INVALID_VALUE);
1722         }
1723
1724         es2::Context *context = es2::getContext();
1725
1726         if(context)
1727         {
1728                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1729                 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1730                 {
1731                         return error(GL_INVALID_OPERATION);
1732                 }
1733
1734                 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
1735         }
1736 }
1737
1738 void VertexAttribDivisorEXT(GLuint index, GLuint divisor)
1739 {
1740         TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1741
1742         es2::Context *context = es2::getContext();
1743
1744         if(context)
1745         {
1746                 if(index >= es2::MAX_VERTEX_ATTRIBS)
1747                 {
1748                         return error(GL_INVALID_VALUE);
1749                 }
1750
1751                 context->setVertexAttribDivisor(index, divisor);
1752         }
1753 }
1754
1755 void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1756 {
1757         TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1758                 mode, first, count, instanceCount);
1759
1760         switch(mode)
1761         {
1762         case GL_POINTS:
1763         case GL_LINES:
1764         case GL_LINE_LOOP:
1765         case GL_LINE_STRIP:
1766         case GL_TRIANGLES:
1767         case GL_TRIANGLE_FAN:
1768         case GL_TRIANGLE_STRIP:
1769                 break;
1770         default:
1771                 return error(GL_INVALID_ENUM);
1772         }
1773
1774         if(count < 0 || instanceCount < 0)
1775         {
1776                 return error(GL_INVALID_VALUE);
1777         }
1778
1779         es2::Context *context = es2::getContext();
1780
1781         if(context)
1782         {
1783                 if(!context->hasZeroDivisor())
1784                 {
1785                         return error(GL_INVALID_OPERATION);
1786                 }
1787
1788                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1789                 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1790                 {
1791                         return error(GL_INVALID_OPERATION);
1792                 }
1793
1794                 context->drawArrays(mode, first, count, instanceCount);
1795         }
1796 }
1797
1798 void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
1799 {
1800         TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
1801                 mode, count, type, indices, instanceCount);
1802
1803         switch(mode)
1804         {
1805         case GL_POINTS:
1806         case GL_LINES:
1807         case GL_LINE_LOOP:
1808         case GL_LINE_STRIP:
1809         case GL_TRIANGLES:
1810         case GL_TRIANGLE_FAN:
1811         case GL_TRIANGLE_STRIP:
1812                 break;
1813         default:
1814                 return error(GL_INVALID_ENUM);
1815         }
1816
1817         switch(type)
1818         {
1819         case GL_UNSIGNED_BYTE:
1820         case GL_UNSIGNED_SHORT:
1821         case GL_UNSIGNED_INT:
1822                 break;
1823         default:
1824                 return error(GL_INVALID_ENUM);
1825         }
1826
1827         if(count < 0 || instanceCount < 0)
1828         {
1829                 return error(GL_INVALID_VALUE);
1830         }
1831
1832         es2::Context *context = es2::getContext();
1833
1834         if(context)
1835         {
1836                 if(!context->hasZeroDivisor())
1837                 {
1838                         return error(GL_INVALID_OPERATION);
1839                 }
1840
1841                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1842                 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1843                 {
1844                         return error(GL_INVALID_OPERATION);
1845                 }
1846
1847                 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
1848         }
1849 }
1850
1851 void VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
1852 {
1853         TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1854
1855         es2::Context *context = es2::getContext();
1856
1857         if(context)
1858         {
1859                 if(index >= MAX_VERTEX_ATTRIBS)
1860                 {
1861                         return error(GL_INVALID_VALUE);
1862                 }
1863
1864                 context->setVertexAttribDivisor(index, divisor);
1865         }
1866 }
1867
1868 void Enable(GLenum cap)
1869 {
1870         TRACE("(GLenum cap = 0x%X)", cap);
1871
1872         es2::Context *context = es2::getContext();
1873
1874         if(context)
1875         {
1876                 switch(cap)
1877                 {
1878                 case GL_CULL_FACE:                     context->setCullFaceEnabled(true);                   break;
1879                 case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(true);          break;
1880                 case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(true);      break;
1881                 case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(true);             break;
1882                 case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(true);                break;
1883                 case GL_STENCIL_TEST:                  context->setStencilTestEnabled(true);                break;
1884                 case GL_DEPTH_TEST:                    context->setDepthTestEnabled(true);                  break;
1885                 case GL_BLEND:                         context->setBlendEnabled(true);                      break;
1886                 case GL_DITHER:                        context->setDitherEnabled(true);                     break;
1887                 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(true); break;
1888                 case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(true);          break;
1889                 default:
1890                         return error(GL_INVALID_ENUM);
1891                 }
1892         }
1893 }
1894
1895 void EnableVertexAttribArray(GLuint index)
1896 {
1897         TRACE("(GLuint index = %d)", index);
1898
1899         if(index >= es2::MAX_VERTEX_ATTRIBS)
1900         {
1901                 return error(GL_INVALID_VALUE);
1902         }
1903
1904         es2::Context *context = es2::getContext();
1905
1906         if(context)
1907         {
1908                 context->setVertexAttribArrayEnabled(index, true);
1909         }
1910 }
1911
1912 void EndQueryEXT(GLenum target)
1913 {
1914         TRACE("GLenum target = 0x%X)", target);
1915
1916         switch(target)
1917         {
1918         case GL_ANY_SAMPLES_PASSED_EXT:
1919         case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1920                 break;
1921         default:
1922                 return error(GL_INVALID_ENUM);
1923         }
1924
1925         es2::Context *context = es2::getContext();
1926
1927         if(context)
1928         {
1929                 context->endQuery(target);
1930         }
1931 }
1932
1933 void FinishFenceNV(GLuint fence)
1934 {
1935         TRACE("(GLuint fence = %d)", fence);
1936
1937         es2::Context *context = es2::getContext();
1938
1939         if(context)
1940         {
1941                 es2::Fence *fenceObject = context->getFence(fence);
1942
1943                 if(!fenceObject)
1944                 {
1945                         return error(GL_INVALID_OPERATION);
1946                 }
1947
1948                 fenceObject->finishFence();
1949         }
1950 }
1951
1952 void Finish(void)
1953 {
1954         TRACE("()");
1955
1956         es2::Context *context = es2::getContext();
1957
1958         if(context)
1959         {
1960                 context->finish();
1961         }
1962 }
1963
1964 void Flush(void)
1965 {
1966         TRACE("()");
1967
1968         es2::Context *context = es2::getContext();
1969
1970         if(context)
1971         {
1972                 context->flush();
1973         }
1974 }
1975
1976 void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1977 {
1978         TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1979               "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1980
1981         if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
1982            (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
1983         {
1984                 return error(GL_INVALID_ENUM);
1985         }
1986
1987         es2::Context *context = es2::getContext();
1988
1989         if(context)
1990         {
1991                 es2::Framebuffer *framebuffer = nullptr;
1992                 GLuint framebufferName = 0;
1993                 if(target == GL_READ_FRAMEBUFFER_ANGLE)
1994                 {
1995                         framebuffer = context->getReadFramebuffer();
1996                         framebufferName = context->getReadFramebufferName();
1997                 }
1998                 else
1999                 {
2000                         framebuffer = context->getDrawFramebuffer();
2001                         framebufferName = context->getDrawFramebufferName();
2002                 }
2003
2004                 if(!framebuffer || framebufferName == 0)
2005                 {
2006                         return error(GL_INVALID_OPERATION);
2007                 }
2008
2009                 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
2010                 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
2011                 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
2012                 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
2013                 if(renderbuffer != 0)
2014                 {
2015                         if(!context->getRenderbuffer(renderbuffer))
2016                         {
2017                                 return error(GL_INVALID_OPERATION);
2018                         }
2019                 }
2020
2021                 GLint clientVersion = context->getClientVersion();
2022
2023                 switch(attachment)
2024                 {
2025                 case GL_COLOR_ATTACHMENT0:
2026                 case GL_COLOR_ATTACHMENT1:
2027                 case GL_COLOR_ATTACHMENT2:
2028                 case GL_COLOR_ATTACHMENT3:
2029                 case GL_COLOR_ATTACHMENT4:
2030                 case GL_COLOR_ATTACHMENT5:
2031                 case GL_COLOR_ATTACHMENT6:
2032                 case GL_COLOR_ATTACHMENT7:
2033                 case GL_COLOR_ATTACHMENT8:
2034                 case GL_COLOR_ATTACHMENT9:
2035                 case GL_COLOR_ATTACHMENT10:
2036                 case GL_COLOR_ATTACHMENT11:
2037                 case GL_COLOR_ATTACHMENT12:
2038                 case GL_COLOR_ATTACHMENT13:
2039                 case GL_COLOR_ATTACHMENT14:
2040                 case GL_COLOR_ATTACHMENT15:
2041                 case GL_COLOR_ATTACHMENT16:
2042                 case GL_COLOR_ATTACHMENT17:
2043                 case GL_COLOR_ATTACHMENT18:
2044                 case GL_COLOR_ATTACHMENT19:
2045                 case GL_COLOR_ATTACHMENT20:
2046                 case GL_COLOR_ATTACHMENT21:
2047                 case GL_COLOR_ATTACHMENT22:
2048                 case GL_COLOR_ATTACHMENT23:
2049                 case GL_COLOR_ATTACHMENT24:
2050                 case GL_COLOR_ATTACHMENT25:
2051                 case GL_COLOR_ATTACHMENT26:
2052                 case GL_COLOR_ATTACHMENT27:
2053                 case GL_COLOR_ATTACHMENT28:
2054                 case GL_COLOR_ATTACHMENT29:
2055                 case GL_COLOR_ATTACHMENT30:
2056                 case GL_COLOR_ATTACHMENT31:
2057                         if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
2058                         {
2059                                 return error(GL_INVALID_ENUM);
2060                         }
2061                         framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0);
2062                         break;
2063                 case GL_DEPTH_ATTACHMENT:
2064                         framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2065                         break;
2066                 case GL_STENCIL_ATTACHMENT:
2067                         framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2068                         break;
2069                 case GL_DEPTH_STENCIL_ATTACHMENT:
2070                         if(clientVersion >= 3)
2071                         {
2072                                 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2073                                 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2074                                 break;
2075                         }
2076                         else return error(GL_INVALID_ENUM);
2077                 default:
2078                         return error(GL_INVALID_ENUM);
2079                 }
2080         }
2081 }
2082
2083 void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2084 {
2085         TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
2086               "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
2087
2088         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2089         {
2090                 return error(GL_INVALID_ENUM);
2091         }
2092
2093         es2::Context *context = es2::getContext();
2094
2095         if(context)
2096         {
2097                 GLint clientVersion = context->getClientVersion();
2098
2099                 if(texture == 0)
2100                 {
2101                         textarget = GL_NONE;
2102                 }
2103                 else
2104                 {
2105                         es2::Texture *tex = context->getTexture(texture);
2106
2107                         if(!tex)
2108                         {
2109                                 return error(GL_INVALID_OPERATION);
2110                         }
2111
2112                         switch(textarget)
2113                         {
2114                         case GL_TEXTURE_2D:
2115                                 if(tex->getTarget() != GL_TEXTURE_2D)
2116                                 {
2117                                         return error(GL_INVALID_OPERATION);
2118                                 }
2119                                 break;
2120                         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2121                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2122                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2123                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2124                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2125                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2126                                 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2127                                 {
2128                                         return error(GL_INVALID_OPERATION);
2129                                 }
2130                                 break;
2131                         default:
2132                                 return error(GL_INVALID_ENUM);
2133                         }
2134
2135                         if((level != 0) && (clientVersion < 3))
2136                         {
2137                                 return error(GL_INVALID_VALUE);
2138                         }
2139
2140                         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
2141                         {
2142                                 return error(GL_INVALID_VALUE);
2143                         }
2144
2145                         if(tex->isCompressed(textarget, level))
2146                         {
2147                                 return error(GL_INVALID_OPERATION);
2148                         }
2149                 }
2150
2151                 es2::Framebuffer *framebuffer = nullptr;
2152                 GLuint framebufferName = 0;
2153                 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2154                 {
2155                         framebuffer = context->getReadFramebuffer();
2156                         framebufferName = context->getReadFramebufferName();
2157                 }
2158                 else
2159                 {
2160                         framebuffer = context->getDrawFramebuffer();
2161                         framebufferName = context->getDrawFramebufferName();
2162                 }
2163
2164                 if(framebufferName == 0 || !framebuffer)
2165                 {
2166                         return error(GL_INVALID_OPERATION);
2167                 }
2168
2169                 switch(attachment)
2170                 {
2171                 case GL_COLOR_ATTACHMENT0:
2172                 case GL_COLOR_ATTACHMENT1:
2173                 case GL_COLOR_ATTACHMENT2:
2174                 case GL_COLOR_ATTACHMENT3:
2175                 case GL_COLOR_ATTACHMENT4:
2176                 case GL_COLOR_ATTACHMENT5:
2177                 case GL_COLOR_ATTACHMENT6:
2178                 case GL_COLOR_ATTACHMENT7:
2179                 case GL_COLOR_ATTACHMENT8:
2180                 case GL_COLOR_ATTACHMENT9:
2181                 case GL_COLOR_ATTACHMENT10:
2182                 case GL_COLOR_ATTACHMENT11:
2183                 case GL_COLOR_ATTACHMENT12:
2184                 case GL_COLOR_ATTACHMENT13:
2185                 case GL_COLOR_ATTACHMENT14:
2186                 case GL_COLOR_ATTACHMENT15:
2187                 case GL_COLOR_ATTACHMENT16:
2188                 case GL_COLOR_ATTACHMENT17:
2189                 case GL_COLOR_ATTACHMENT18:
2190                 case GL_COLOR_ATTACHMENT19:
2191                 case GL_COLOR_ATTACHMENT20:
2192                 case GL_COLOR_ATTACHMENT21:
2193                 case GL_COLOR_ATTACHMENT22:
2194                 case GL_COLOR_ATTACHMENT23:
2195                 case GL_COLOR_ATTACHMENT24:
2196                 case GL_COLOR_ATTACHMENT25:
2197                 case GL_COLOR_ATTACHMENT26:
2198                 case GL_COLOR_ATTACHMENT27:
2199                 case GL_COLOR_ATTACHMENT28:
2200                 case GL_COLOR_ATTACHMENT29:
2201                 case GL_COLOR_ATTACHMENT30:
2202                 case GL_COLOR_ATTACHMENT31:
2203                         if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
2204                         {
2205                                 return error(GL_INVALID_ENUM);
2206                         }
2207                         framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);
2208                         break;
2209                 case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture, level);   break;
2210                 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;
2211                 case GL_DEPTH_STENCIL_ATTACHMENT:
2212                         if(clientVersion >= 3)
2213                         {
2214                                 framebuffer->setDepthbuffer(textarget, texture, level);
2215                                 framebuffer->setStencilbuffer(textarget, texture, level);
2216                                 break;
2217                         }
2218                         else return error(GL_INVALID_ENUM);
2219                 default:
2220                         return error(GL_INVALID_ENUM);
2221                 }
2222         }
2223 }
2224
2225 void FrontFace(GLenum mode)
2226 {
2227         TRACE("(GLenum mode = 0x%X)", mode);
2228
2229         switch(mode)
2230         {
2231         case GL_CW:
2232         case GL_CCW:
2233                 {
2234                         es2::Context *context = es2::getContext();
2235
2236                         if(context)
2237                         {
2238                                 context->setFrontFace(mode);
2239                         }
2240                 }
2241                 break;
2242         default:
2243                 return error(GL_INVALID_ENUM);
2244         }
2245 }
2246
2247 void GenBuffers(GLsizei n, GLuint* buffers)
2248 {
2249         TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
2250
2251         if(n < 0)
2252         {
2253                 return error(GL_INVALID_VALUE);
2254         }
2255
2256         es2::Context *context = es2::getContext();
2257
2258         if(context)
2259         {
2260                 for(int i = 0; i < n; i++)
2261                 {
2262                         buffers[i] = context->createBuffer();
2263                 }
2264         }
2265 }
2266
2267 void GenerateMipmap(GLenum target)
2268 {
2269         TRACE("(GLenum target = 0x%X)", target);
2270
2271         es2::Context *context = es2::getContext();
2272
2273         if(context)
2274         {
2275                 es2::Texture *texture = nullptr;
2276
2277                 GLint clientVersion = context->getClientVersion();
2278
2279                 switch(target)
2280                 {
2281                 case GL_TEXTURE_2D:
2282                         texture = context->getTexture2D();
2283                         break;
2284                 case GL_TEXTURE_CUBE_MAP:
2285                         texture = context->getTextureCubeMap();
2286                         break;
2287                 case GL_TEXTURE_2D_ARRAY:
2288                         if(clientVersion < 3)
2289                         {
2290                                 return error(GL_INVALID_ENUM);
2291                         }
2292                         else
2293                         {
2294                                 texture = context->getTexture2DArray();
2295                         }
2296                         break;
2297                 case GL_TEXTURE_3D_OES:
2298                         texture = context->getTexture3D();
2299                         break;
2300                 default:
2301                         return error(GL_INVALID_ENUM);
2302                 }
2303
2304                 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2305                 {
2306                         return error(GL_INVALID_OPERATION);
2307                 }
2308
2309                 texture->generateMipmaps();
2310         }
2311 }
2312
2313 void GenFencesNV(GLsizei n, GLuint* fences)
2314 {
2315         TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
2316
2317         if(n < 0)
2318         {
2319                 return error(GL_INVALID_VALUE);
2320         }
2321
2322         es2::Context *context = es2::getContext();
2323
2324         if(context)
2325         {
2326                 for(int i = 0; i < n; i++)
2327                 {
2328                         fences[i] = context->createFence();
2329                 }
2330         }
2331 }
2332
2333 void GenFramebuffers(GLsizei n, GLuint* framebuffers)
2334 {
2335         TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
2336
2337         if(n < 0)
2338         {
2339                 return error(GL_INVALID_VALUE);
2340         }
2341
2342         es2::Context *context = es2::getContext();
2343
2344         if(context)
2345         {
2346                 for(int i = 0; i < n; i++)
2347                 {
2348                         framebuffers[i] = context->createFramebuffer();
2349                 }
2350         }
2351 }
2352
2353 void GenQueriesEXT(GLsizei n, GLuint* ids)
2354 {
2355         TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
2356
2357         if(n < 0)
2358         {
2359                 return error(GL_INVALID_VALUE);
2360         }
2361
2362         es2::Context *context = es2::getContext();
2363
2364         if(context)
2365         {
2366                 for(int i = 0; i < n; i++)
2367                 {
2368                         ids[i] = context->createQuery();
2369                 }
2370         }
2371 }
2372
2373 void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2374 {
2375         TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
2376
2377         if(n < 0)
2378         {
2379                 return error(GL_INVALID_VALUE);
2380         }
2381
2382         es2::Context *context = es2::getContext();
2383
2384         if(context)
2385         {
2386                 for(int i = 0; i < n; i++)
2387                 {
2388                         renderbuffers[i] = context->createRenderbuffer();
2389                 }
2390         }
2391 }
2392
2393 void GenTextures(GLsizei n, GLuint* textures)
2394 {
2395         TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
2396
2397         if(n < 0)
2398         {
2399                 return error(GL_INVALID_VALUE);
2400         }
2401
2402         es2::Context *context = es2::getContext();
2403
2404         if(context)
2405         {
2406                 for(int i = 0; i < n; i++)
2407                 {
2408                         textures[i] = context->createTexture();
2409                 }
2410         }
2411 }
2412
2413 void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
2414 {
2415         TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
2416               "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
2417               program, index, bufsize, length, size, type, name);
2418
2419         if(bufsize < 0)
2420         {
2421                 return error(GL_INVALID_VALUE);
2422         }
2423
2424         es2::Context *context = es2::getContext();
2425
2426         if(context)
2427         {
2428                 es2::Program *programObject = context->getProgram(program);
2429
2430                 if(!programObject)
2431                 {
2432                         if(context->getShader(program))
2433                         {
2434                                 return error(GL_INVALID_OPERATION);
2435                         }
2436                         else
2437                         {
2438                                 return error(GL_INVALID_VALUE);
2439                         }
2440                 }
2441
2442                 if(index >= programObject->getActiveAttributeCount())
2443                 {
2444                         return error(GL_INVALID_VALUE);
2445                 }
2446
2447                 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2448         }
2449 }
2450
2451 void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
2452 {
2453         TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2454               "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
2455               program, index, bufsize, length, size, type, name);
2456
2457         if(bufsize < 0)
2458         {
2459                 return error(GL_INVALID_VALUE);
2460         }
2461
2462         es2::Context *context = es2::getContext();
2463
2464         if(context)
2465         {
2466                 es2::Program *programObject = context->getProgram(program);
2467
2468                 if(!programObject)
2469                 {
2470                         if(context->getShader(program))
2471                         {
2472                                 return error(GL_INVALID_OPERATION);
2473                         }
2474                         else
2475                         {
2476                                 return error(GL_INVALID_VALUE);
2477                         }
2478                 }
2479
2480                 if(index >= programObject->getActiveUniformCount())
2481                 {
2482                         return error(GL_INVALID_VALUE);
2483                 }
2484
2485                 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2486         }
2487 }
2488
2489 void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2490 {
2491         TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
2492               program, maxcount, count, shaders);
2493
2494         if(maxcount < 0)
2495         {
2496                 return error(GL_INVALID_VALUE);
2497         }
2498
2499         es2::Context *context = es2::getContext();
2500
2501         if(context)
2502         {
2503                 es2::Program *programObject = context->getProgram(program);
2504
2505                 if(!programObject)
2506                 {
2507                         if(context->getShader(program))
2508                         {
2509                                 return error(GL_INVALID_OPERATION);
2510                         }
2511                         else
2512                         {
2513                                 return error(GL_INVALID_VALUE);
2514                         }
2515                 }
2516
2517                 return programObject->getAttachedShaders(maxcount, count, shaders);
2518         }
2519 }
2520
2521 int GetAttribLocation(GLuint program, const GLchar* name)
2522 {
2523         TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
2524
2525         es2::Context *context = es2::getContext();
2526
2527         if(context)
2528         {
2529
2530                 es2::Program *programObject = context->getProgram(program);
2531
2532                 if(!programObject)
2533                 {
2534                         if(context->getShader(program))
2535                         {
2536                                 return error(GL_INVALID_OPERATION, -1);
2537                         }
2538                         else
2539                         {
2540                                 return error(GL_INVALID_VALUE, -1);
2541                         }
2542                 }
2543
2544                 if(!programObject->isLinked())
2545                 {
2546                         return error(GL_INVALID_OPERATION, -1);
2547                 }
2548
2549                 return programObject->getAttributeLocation(name);
2550         }
2551
2552         return -1;
2553 }
2554
2555 void GetBooleanv(GLenum pname, GLboolean* params)
2556 {
2557         TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);
2558
2559         es2::Context *context = es2::getContext();
2560
2561         if(context)
2562         {
2563                 if(!(context->getBooleanv(pname, params)))
2564                 {
2565                         GLenum nativeType;
2566                         unsigned int numParams = 0;
2567                         if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2568                                 return error(GL_INVALID_ENUM);
2569
2570                         if(numParams == 0)
2571                                 return; // it is known that the pname is valid, but there are no parameters to return
2572
2573                         if(nativeType == GL_FLOAT)
2574                         {
2575                                 GLfloat *floatParams = nullptr;
2576                                 floatParams = new GLfloat[numParams];
2577
2578                                 context->getFloatv(pname, floatParams);
2579
2580                                 for(unsigned int i = 0; i < numParams; ++i)
2581                                 {
2582                                         if(floatParams[i] == 0.0f)
2583                                                 params[i] = GL_FALSE;
2584                                         else
2585                                                 params[i] = GL_TRUE;
2586                                 }
2587
2588                                 delete [] floatParams;
2589                         }
2590                         else if(nativeType == GL_INT)
2591                         {
2592                                 GLint *intParams = nullptr;
2593                                 intParams = new GLint[numParams];
2594
2595                                 context->getIntegerv(pname, intParams);
2596
2597                                 for(unsigned int i = 0; i < numParams; ++i)
2598                                 {
2599                                         if(intParams[i] == 0)
2600                                                 params[i] = GL_FALSE;
2601                                         else
2602                                                 params[i] = GL_TRUE;
2603                                 }
2604
2605                                 delete [] intParams;
2606                         }
2607                 }
2608         }
2609 }
2610
2611 void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2612 {
2613         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
2614
2615         es2::Context *context = es2::getContext();
2616
2617         if(context)
2618         {
2619                 es2::Buffer *buffer;
2620                 if(!context->getBuffer(target, &buffer))
2621                 {
2622                         return error(GL_INVALID_ENUM);
2623                 }
2624
2625                 if(!buffer)
2626                 {
2627                         // A null buffer means that "0" is bound to the requested buffer target
2628                         return error(GL_INVALID_OPERATION);
2629                 }
2630
2631                 GLint clientVersion = context->getClientVersion();
2632
2633                 switch(pname)
2634                 {
2635                 case GL_BUFFER_USAGE:
2636                         *params = buffer->usage();
2637                         break;
2638                 case GL_BUFFER_SIZE:
2639                         *params = (GLint)buffer->size();
2640                         break;
2641                 case GL_BUFFER_ACCESS_FLAGS:
2642                         if(clientVersion >= 3)
2643                         {
2644                                 *params = buffer->access();
2645                                 break;
2646                         }
2647                         else return error(GL_INVALID_ENUM);
2648                 case GL_BUFFER_MAPPED:
2649                         if(clientVersion >= 3)
2650                         {
2651                                 *params = buffer->isMapped();
2652                                 break;
2653                         }
2654                         else return error(GL_INVALID_ENUM);
2655                 case GL_BUFFER_MAP_LENGTH:
2656                         if(clientVersion >= 3)
2657                         {
2658                                 *params = (GLint)buffer->length();
2659                                 break;
2660                         }
2661                         else return error(GL_INVALID_ENUM);
2662                 case GL_BUFFER_MAP_OFFSET:
2663                         if(clientVersion >= 3)
2664                         {
2665                                 *params = (GLint)buffer->offset();
2666                                 break;
2667                         }
2668                         else return error(GL_INVALID_ENUM);
2669                 default:
2670                         return error(GL_INVALID_ENUM);
2671                 }
2672         }
2673 }
2674
2675 GLenum GetError(void)
2676 {
2677         TRACE("()");
2678
2679         es2::Context *context = es2::getContext();
2680
2681         if(context)
2682         {
2683                 return context->getError();
2684         }
2685
2686         return GL_NO_ERROR;
2687 }
2688
2689 void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2690 {
2691         TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
2692
2693         es2::Context *context = es2::getContext();
2694
2695         if(context)
2696         {
2697                 es2::Fence *fenceObject = context->getFence(fence);
2698
2699                 if(!fenceObject)
2700                 {
2701                         return error(GL_INVALID_OPERATION);
2702                 }
2703
2704                 fenceObject->getFenceiv(pname, params);
2705         }
2706 }
2707
2708 void GetFloatv(GLenum pname, GLfloat* params)
2709 {
2710         TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
2711
2712         es2::Context *context = es2::getContext();
2713
2714         if(context)
2715         {
2716                 if(!(context->getFloatv(pname, params)))
2717                 {
2718                         GLenum nativeType;
2719                         unsigned int numParams = 0;
2720                         if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2721                                 return error(GL_INVALID_ENUM);
2722
2723                         if(numParams == 0)
2724                                 return; // it is known that the pname is valid, but that there are no parameters to return.
2725
2726                         if(nativeType == GL_BOOL)
2727                         {
2728                                 GLboolean *boolParams = nullptr;
2729                                 boolParams = new GLboolean[numParams];
2730
2731                                 context->getBooleanv(pname, boolParams);
2732
2733                                 for(unsigned int i = 0; i < numParams; ++i)
2734                                 {
2735                                         if(boolParams[i] == GL_FALSE)
2736                                                 params[i] = 0.0f;
2737                                         else
2738                                                 params[i] = 1.0f;
2739                                 }
2740
2741                                 delete [] boolParams;
2742                         }
2743                         else if(nativeType == GL_INT)
2744                         {
2745                                 GLint *intParams = nullptr;
2746                                 intParams = new GLint[numParams];
2747
2748                                 context->getIntegerv(pname, intParams);
2749
2750                                 for(unsigned int i = 0; i < numParams; ++i)
2751                                 {
2752                                         params[i] = (GLfloat)intParams[i];
2753                                 }
2754
2755                                 delete [] intParams;
2756                         }
2757                 }
2758         }
2759 }
2760
2761 void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2762 {
2763         TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
2764               target, attachment, pname, params);
2765
2766         es2::Context *context = es2::getContext();
2767
2768         if(context)
2769         {
2770                 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
2771                 {
2772                         return error(GL_INVALID_ENUM);
2773                 }
2774
2775                 GLint clientVersion = context->getClientVersion();
2776
2777                 es2::Framebuffer *framebuffer = nullptr;
2778                 if(target == GL_READ_FRAMEBUFFER)
2779                 {
2780                         if(context->getReadFramebufferName() == 0)
2781                         {
2782                                 if(clientVersion < 3)
2783                                 {
2784                                         return error(GL_INVALID_OPERATION);
2785                                 }
2786                                 else
2787                                 {
2788                                         switch(attachment)
2789                                         {
2790                                         case GL_BACK:
2791                                         case GL_DEPTH:
2792                                         case GL_STENCIL:
2793                                                 break;
2794                                         default:
2795                                                 return error(GL_INVALID_ENUM);
2796                                         }
2797                                 }
2798                         }
2799
2800                         framebuffer = context->getReadFramebuffer();
2801                 }
2802                 else
2803                 {
2804                         if(context->getDrawFramebufferName() == 0)
2805                         {
2806                                 if(clientVersion < 3)
2807                                 {
2808                                         return error(GL_INVALID_OPERATION);
2809                                 }
2810                                 else
2811                                 {
2812                                         switch(attachment)
2813                                         {
2814                                         case GL_BACK:
2815                                         case GL_DEPTH:
2816                                         case GL_STENCIL:
2817                                                 break;
2818                                         default:
2819                                                 return error(GL_INVALID_ENUM);
2820                                         }
2821                                 }
2822                         }
2823
2824                         framebuffer = context->getDrawFramebuffer();
2825                 }
2826
2827                 GLenum attachmentType;
2828                 GLuint attachmentHandle;
2829                 GLint attachmentLayer;
2830                 Renderbuffer* renderbuffer = nullptr;
2831                 switch(attachment)
2832                 {
2833                 case GL_BACK:
2834                         if(clientVersion >= 3)
2835                         {
2836                                 attachmentType = framebuffer->getColorbufferType(0);
2837                                 attachmentHandle = framebuffer->getColorbufferName(0);
2838                                 attachmentLayer = framebuffer->getColorbufferLayer(0);
2839                                 renderbuffer = framebuffer->getColorbuffer(0);
2840                         }
2841                         else return error(GL_INVALID_ENUM);
2842                         break;
2843                 case GL_COLOR_ATTACHMENT0:
2844                 case GL_COLOR_ATTACHMENT1:
2845                 case GL_COLOR_ATTACHMENT2:
2846                 case GL_COLOR_ATTACHMENT3:
2847                 case GL_COLOR_ATTACHMENT4:
2848                 case GL_COLOR_ATTACHMENT5:
2849                 case GL_COLOR_ATTACHMENT6:
2850                 case GL_COLOR_ATTACHMENT7:
2851                 case GL_COLOR_ATTACHMENT8:
2852                 case GL_COLOR_ATTACHMENT9:
2853                 case GL_COLOR_ATTACHMENT10:
2854                 case GL_COLOR_ATTACHMENT11:
2855                 case GL_COLOR_ATTACHMENT12:
2856                 case GL_COLOR_ATTACHMENT13:
2857                 case GL_COLOR_ATTACHMENT14:
2858                 case GL_COLOR_ATTACHMENT15:
2859                 case GL_COLOR_ATTACHMENT16:
2860                 case GL_COLOR_ATTACHMENT17:
2861                 case GL_COLOR_ATTACHMENT18:
2862                 case GL_COLOR_ATTACHMENT19:
2863                 case GL_COLOR_ATTACHMENT20:
2864                 case GL_COLOR_ATTACHMENT21:
2865                 case GL_COLOR_ATTACHMENT22:
2866                 case GL_COLOR_ATTACHMENT23:
2867                 case GL_COLOR_ATTACHMENT24:
2868                 case GL_COLOR_ATTACHMENT25:
2869                 case GL_COLOR_ATTACHMENT26:
2870                 case GL_COLOR_ATTACHMENT27:
2871                 case GL_COLOR_ATTACHMENT28:
2872                 case GL_COLOR_ATTACHMENT29:
2873                 case GL_COLOR_ATTACHMENT30:
2874                 case GL_COLOR_ATTACHMENT31:
2875                         if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
2876                         {
2877                                 return error(GL_INVALID_ENUM);
2878                         }
2879                         attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
2880                         attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
2881                         attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
2882                         renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
2883                         break;
2884                 case GL_DEPTH:
2885                         if(clientVersion < 3)
2886                         {
2887                                 return error(GL_INVALID_ENUM);
2888                         }
2889                         // fall through
2890                 case GL_DEPTH_ATTACHMENT:
2891                         attachmentType = framebuffer->getDepthbufferType();
2892                         attachmentHandle = framebuffer->getDepthbufferName();
2893                         attachmentLayer = framebuffer->getDepthbufferLayer();
2894                         renderbuffer = framebuffer->getDepthbuffer();
2895                         break;
2896                 case GL_STENCIL:
2897                         if(clientVersion < 3)
2898                         {
2899                                 return error(GL_INVALID_ENUM);
2900                         }
2901                         // fall through
2902                 case GL_STENCIL_ATTACHMENT:
2903                         attachmentType = framebuffer->getStencilbufferType();
2904                         attachmentHandle = framebuffer->getStencilbufferName();
2905                         attachmentLayer = framebuffer->getStencilbufferLayer();
2906                         renderbuffer = framebuffer->getStencilbuffer();
2907                         break;
2908                 case GL_DEPTH_STENCIL_ATTACHMENT:
2909                         if(clientVersion >= 3)
2910                         {
2911                                 attachmentType = framebuffer->getDepthbufferType();
2912                                 attachmentHandle = framebuffer->getDepthbufferName();
2913                                 attachmentLayer = framebuffer->getDepthbufferLayer();
2914                                 if(attachmentHandle != framebuffer->getStencilbufferName())
2915                                 {
2916                                         // Different attachments to DEPTH and STENCIL, query fails
2917                                         return error(GL_INVALID_OPERATION);
2918                                 }
2919                                 renderbuffer = framebuffer->getDepthbuffer();
2920                         }
2921                         else return error(GL_INVALID_ENUM);
2922                         break;
2923                 default:
2924                         return error(GL_INVALID_ENUM);
2925                 }
2926
2927                 GLenum attachmentObjectType = GL_NONE;   // Type category
2928                 if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))
2929                 {
2930                         attachmentObjectType = attachmentType;
2931                 }
2932                 else if(es2::IsTextureTarget(attachmentType))
2933                 {
2934                         attachmentObjectType = GL_TEXTURE;
2935                 }
2936                 else UNREACHABLE(attachmentType);
2937
2938                 if(attachmentObjectType != GL_NONE)
2939                 {
2940                         switch(pname)
2941                         {
2942                         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2943                                 *params = attachmentObjectType;
2944                                 break;
2945                         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2946                                 if(Framebuffer::IsRenderbuffer(attachmentObjectType) || attachmentObjectType == GL_TEXTURE)
2947                                 {
2948                                         *params = attachmentHandle;
2949                                 }
2950                                 else
2951                                 {
2952                                         return error(GL_INVALID_ENUM);
2953                                 }
2954                                 break;
2955                         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2956                                 if(attachmentObjectType == GL_TEXTURE)
2957                                 {
2958                                         *params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2959                                 }
2960                                 else
2961                                 {
2962                                         return error(GL_INVALID_ENUM);
2963                                 }
2964                                 break;
2965                         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2966                                 if(attachmentObjectType == GL_TEXTURE)
2967                                 {
2968                                         if(es2::IsCubemapTextureTarget(attachmentType))
2969                                         {
2970                                                 *params = attachmentType;
2971                                         }
2972                                         else
2973                                         {
2974                                                 *params = 0;
2975                                         }
2976                                 }
2977                                 else
2978                                 {
2979                                         return error(GL_INVALID_ENUM);
2980                                 }
2981                                 break;
2982                         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
2983                                 if(clientVersion >= 3)
2984                                 {
2985                                         *params = attachmentLayer;
2986                                 }
2987                                 else return error(GL_INVALID_ENUM);
2988                                 break;
2989                         case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
2990                                 if(clientVersion >= 3)
2991                                 {
2992                                         *params = renderbuffer->getRedSize();
2993                                 }
2994                                 else return error(GL_INVALID_ENUM);
2995                                 break;
2996                         case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
2997                                 if(clientVersion >= 3)
2998                                 {
2999                                         *params = renderbuffer->getGreenSize();
3000                                 }
3001                                 else return error(GL_INVALID_ENUM);
3002                                 break;
3003                         case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
3004                                 if(clientVersion >= 3)
3005                                 {
3006                                         *params = renderbuffer->getBlueSize();
3007                                 }
3008                                 else return error(GL_INVALID_ENUM);
3009                                 break;
3010                         case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
3011                                 if(clientVersion >= 3)
3012                                 {
3013                                         *params = renderbuffer->getAlphaSize();
3014                                 }
3015                                 else return error(GL_INVALID_ENUM);
3016                                 break;
3017                         case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
3018                                 if(clientVersion >= 3)
3019                                 {
3020                                         *params = renderbuffer->getDepthSize();
3021                                 }
3022                                 else return error(GL_INVALID_ENUM);
3023                                 break;
3024                         case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
3025                                 if(clientVersion >= 3)
3026                                 {
3027                                         *params = renderbuffer->getStencilSize();
3028                                 }
3029                                 else return error(GL_INVALID_ENUM);
3030                                 break;
3031                         case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
3032                 //      case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT:   // GL_EXT_color_buffer_half_float
3033                                 if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
3034                                 {
3035                                         return error(GL_INVALID_OPERATION);
3036                                 }
3037
3038                                 *params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);
3039                                 break;
3040                         case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
3041                                 if(clientVersion >= 3)
3042                                 {
3043                                         *params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added
3044                                 }
3045                                 else return error(GL_INVALID_ENUM);
3046                                 break;
3047                         default:
3048                                 return error(GL_INVALID_ENUM);
3049                         }
3050                 }
3051                 else
3052                 {
3053                         // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
3054                         // is NONE, then querying any other pname will generate INVALID_ENUM.
3055
3056                         // ES 3.0.2 spec pg 235 states that if the attachment type is none,
3057                         // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
3058                         // INVALID_OPERATION for all other pnames
3059
3060                         switch(pname)
3061                         {
3062                         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3063                                 *params = GL_NONE;
3064                                 break;
3065
3066                         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3067                                 if(clientVersion < 3)
3068                                 {
3069                                         return error(GL_INVALID_ENUM);
3070                                 }
3071                                 *params = 0;
3072                                 break;
3073
3074                         default:
3075                                 if(clientVersion < 3)
3076                                 {
3077                                         return error(GL_INVALID_ENUM);
3078                                 }
3079                                 else
3080                                 {
3081                                         return error(GL_INVALID_OPERATION);
3082                                 }
3083                         }
3084                 }
3085         }
3086 }
3087
3088 GLenum GetGraphicsResetStatusEXT(void)
3089 {
3090         TRACE("()");
3091
3092         return GL_NO_ERROR;
3093 }
3094
3095 void GetIntegerv(GLenum pname, GLint* params)
3096 {
3097         TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
3098
3099         es2::Context *context = es2::getContext();
3100
3101         if(!context)
3102         {
3103                 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
3104                 #ifdef __ANDROID__
3105                         ALOGI("expected_badness glGetIntegerv() called without current context.");
3106                 #else
3107                         ERR("glGetIntegerv() called without current context.");
3108                 #endif
3109
3110                 // This is not spec compliant! When there is no current GL context, functions should
3111                 // have no side effects. Google Maps queries these values before creating a context,
3112                 // so we need this as a bug-compatible workaround.
3113                 switch(pname)
3114                 {
3115                 case GL_MAX_TEXTURE_SIZE:                 *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE;  return;
3116                 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   return;
3117                 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
3118                 case GL_STENCIL_BITS:                     *params = 8;                                     return;
3119                 case GL_ALIASED_LINE_WIDTH_RANGE:
3120                         params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
3121                         params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
3122                         return;
3123                 }
3124         }
3125
3126         if(context)
3127         {
3128                 if(!(context->getIntegerv(pname, params)))
3129                 {
3130                         GLenum nativeType;
3131                         unsigned int numParams = 0;
3132                         if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3133                                 return error(GL_INVALID_ENUM);
3134
3135                         if(numParams == 0)
3136                                 return; // it is known that pname is valid, but there are no parameters to return
3137
3138                         if(nativeType == GL_BOOL)
3139                         {
3140                                 GLboolean *boolParams = nullptr;
3141                                 boolParams = new GLboolean[numParams];
3142
3143                                 context->getBooleanv(pname, boolParams);
3144
3145                                 for(unsigned int i = 0; i < numParams; ++i)
3146                                 {
3147                                         params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
3148                                 }
3149
3150                                 delete [] boolParams;
3151                         }
3152                         else if(nativeType == GL_FLOAT)
3153                         {
3154                                 GLfloat *floatParams = nullptr;
3155                                 floatParams = new GLfloat[numParams];
3156
3157                                 context->getFloatv(pname, floatParams);
3158
3159                                 for(unsigned int i = 0; i < numParams; ++i)
3160                                 {
3161                                         if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3162                                         {
3163                                                 params[i] = convert_float_int(floatParams[i]);
3164                                         }
3165                                         else
3166                                         {
3167                                                 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3168                                         }
3169                                 }
3170
3171                                 delete [] floatParams;
3172                         }
3173                 }
3174         }
3175 }
3176
3177 void GetProgramiv(GLuint program, GLenum pname, GLint* params)
3178 {
3179         TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
3180
3181         es2::Context *context = es2::getContext();
3182
3183         if(context)
3184         {
3185                 es2::Program *programObject = context->getProgram(program);
3186
3187                 if(!programObject)
3188                 {
3189                         if(context->getShader(program))
3190                         {
3191                                 return error(GL_INVALID_OPERATION);
3192                         }
3193                         else
3194                         {
3195                                 return error(GL_INVALID_VALUE);
3196                         }
3197                 }
3198
3199                 GLint clientVersion = egl::getClientVersion();
3200
3201                 switch(pname)
3202                 {
3203                 case GL_DELETE_STATUS:
3204                         *params = programObject->isFlaggedForDeletion();
3205                         return;
3206                 case GL_LINK_STATUS:
3207                         *params = programObject->isLinked();
3208                         return;
3209                 case GL_VALIDATE_STATUS:
3210                         *params = programObject->isValidated();
3211                         return;
3212                 case GL_INFO_LOG_LENGTH:
3213                         *params = (GLint)programObject->getInfoLogLength();
3214                         return;
3215                 case GL_ATTACHED_SHADERS:
3216                         *params = programObject->getAttachedShadersCount();
3217                         return;
3218                 case GL_ACTIVE_ATTRIBUTES:
3219                         *params = (GLint)programObject->getActiveAttributeCount();
3220                         return;
3221                 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
3222                         *params = programObject->getActiveAttributeMaxLength();
3223                         return;
3224                 case GL_ACTIVE_UNIFORMS:
3225                         *params = (GLint)programObject->getActiveUniformCount();
3226                         return;
3227                 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
3228                         *params = programObject->getActiveUniformMaxLength();
3229                         return;
3230                 case GL_ACTIVE_UNIFORM_BLOCKS:
3231                         if(clientVersion >= 3)
3232                         {
3233                                 *params = (GLint)programObject->getActiveUniformBlockCount();
3234                                 return;
3235                         }
3236                         else return error(GL_INVALID_ENUM);
3237                 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
3238                         if(clientVersion >= 3)
3239                         {
3240                                 *params = programObject->getActiveUniformBlockMaxLength();
3241                                 return;
3242                         }
3243                         else return error(GL_INVALID_ENUM);
3244                 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
3245                         if(clientVersion >= 3)
3246                         {
3247                                 *params = programObject->getTransformFeedbackBufferMode();
3248                                 return;
3249                         }
3250                         else return error(GL_INVALID_ENUM);
3251                 case GL_TRANSFORM_FEEDBACK_VARYINGS:
3252                         if(clientVersion >= 3)
3253                         {
3254                                 *params = programObject->getTransformFeedbackVaryingCount();
3255                                 return;
3256                         }
3257                         else return error(GL_INVALID_ENUM);
3258                 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
3259                         if(clientVersion >= 3)
3260                         {
3261                                 *params = programObject->getTransformFeedbackVaryingMaxLength();
3262                                 return;
3263                         }
3264                         else return error(GL_INVALID_ENUM);
3265                 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
3266                         if(clientVersion >= 3)
3267                         {
3268                                 *params = programObject->getBinaryRetrievableHint();
3269                                 return;
3270                         }
3271                         else return error(GL_INVALID_ENUM);
3272                 case GL_PROGRAM_BINARY_LENGTH:
3273                         if(clientVersion >= 3)
3274                         {
3275                                 *params = programObject->getBinaryLength();
3276                                 return;
3277                         }
3278                         else return error(GL_INVALID_ENUM);
3279                 default:
3280                         return error(GL_INVALID_ENUM);
3281                 }
3282         }
3283 }
3284
3285 void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3286 {
3287         TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3288               program, bufsize, length, infolog);
3289
3290         if(bufsize < 0)
3291         {
3292                 return error(GL_INVALID_VALUE);
3293         }
3294
3295         es2::Context *context = es2::getContext();
3296
3297         if(context)
3298         {
3299                 es2::Program *programObject = context->getProgram(program);
3300
3301                 if(!programObject)
3302                 {
3303                         if(context->getShader(program))
3304                         {
3305                                 return error(GL_INVALID_OPERATION);
3306                         }
3307                         else
3308                         {
3309                                 return error(GL_INVALID_VALUE);
3310                         }
3311                 }
3312
3313                 programObject->getInfoLog(bufsize, length, infolog);
3314         }
3315 }
3316
3317 void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3318 {
3319         TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
3320
3321         switch(pname)
3322         {
3323         case GL_CURRENT_QUERY_EXT:
3324                 break;
3325         default:
3326                 return error(GL_INVALID_ENUM);
3327         }
3328
3329         es2::Context *context = es2::getContext();
3330
3331         if(context)
3332         {
3333                 params[0] = context->getActiveQuery(target);
3334         }
3335 }
3336
3337 void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
3338 {
3339         TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
3340
3341         switch(pname)
3342         {
3343         case GL_QUERY_RESULT_EXT:
3344         case GL_QUERY_RESULT_AVAILABLE_EXT:
3345                 break;
3346         default:
3347                 return error(GL_INVALID_ENUM);
3348         }
3349
3350         es2::Context *context = es2::getContext();
3351
3352         if(context)
3353         {
3354                 es2::Query *queryObject = context->getQuery(name);
3355
3356                 if(!queryObject)
3357                 {
3358                         return error(GL_INVALID_OPERATION);
3359                 }
3360
3361                 if(context->getActiveQuery(queryObject->getType()) == name)
3362                 {
3363                         return error(GL_INVALID_OPERATION);
3364                 }
3365
3366                 switch(pname)
3367                 {
3368                 case GL_QUERY_RESULT_EXT:
3369                         params[0] = queryObject->getResult();
3370                         break;
3371                 case GL_QUERY_RESULT_AVAILABLE_EXT:
3372                         params[0] = queryObject->isResultAvailable();
3373                         break;
3374                 default:
3375                         ASSERT(false);
3376                 }
3377         }
3378 }
3379
3380 void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3381 {
3382         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3383
3384         es2::Context *context = es2::getContext();
3385
3386         if(context)
3387         {
3388                 if(target != GL_RENDERBUFFER)
3389                 {
3390                         return error(GL_INVALID_ENUM);
3391                 }
3392
3393                 if(context->getRenderbufferName() == 0)
3394                 {
3395                         return error(GL_INVALID_OPERATION);
3396                 }
3397
3398                 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
3399
3400                 switch(pname)
3401                 {
3402                 case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;
3403                 case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;
3404                 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;
3405                 case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;
3406                 case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;
3407                 case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;
3408                 case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;
3409                 case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;
3410                 case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;
3411                 case GL_RENDERBUFFER_SAMPLES_ANGLE:   *params = renderbuffer->getSamples();     break;
3412                 default:
3413                         return error(GL_INVALID_ENUM);
3414                 }
3415         }
3416 }
3417
3418 void GetShaderiv(GLuint shader, GLenum pname, GLint* params)
3419 {
3420         TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
3421
3422         es2::Context *context = es2::getContext();
3423
3424         if(context)
3425         {
3426                 es2::Shader *shaderObject = context->getShader(shader);
3427
3428                 if(!shaderObject)
3429                 {
3430                         if(context->getProgram(shader))
3431                         {
3432                                 return error(GL_INVALID_OPERATION);
3433                         }
3434                         else
3435                         {
3436                                 return error(GL_INVALID_VALUE);
3437                         }
3438                 }
3439
3440                 switch(pname)
3441                 {
3442                 case GL_SHADER_TYPE:
3443                         *params = shaderObject->getType();
3444                         return;
3445                 case GL_DELETE_STATUS:
3446                         *params = shaderObject->isFlaggedForDeletion();
3447                         return;
3448                 case GL_COMPILE_STATUS:
3449                         *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3450                         return;
3451                 case GL_INFO_LOG_LENGTH:
3452                         *params = (GLint)shaderObject->getInfoLogLength();
3453                         return;
3454                 case GL_SHADER_SOURCE_LENGTH:
3455                         *params = (GLint)shaderObject->getSourceLength();
3456                         return;
3457                 default:
3458                         return error(GL_INVALID_ENUM);
3459                 }
3460         }
3461 }
3462
3463 void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3464 {
3465         TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3466               shader, bufsize, length, infolog);
3467
3468         if(bufsize < 0)
3469         {
3470                 return error(GL_INVALID_VALUE);
3471         }
3472
3473         es2::Context *context = es2::getContext();
3474
3475         if(context)
3476         {
3477                 es2::Shader *shaderObject = context->getShader(shader);
3478
3479                 if(!shaderObject)
3480                 {
3481                         if(context->getProgram(shader))
3482                         {
3483                                 return error(GL_INVALID_OPERATION);
3484                         }
3485                         else
3486                         {
3487                                 return error(GL_INVALID_VALUE);
3488                         }
3489                 }
3490
3491                 shaderObject->getInfoLog(bufsize, length, infolog);
3492         }
3493 }
3494
3495 void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3496 {
3497         TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
3498               shadertype, precisiontype, range, precision);
3499
3500         switch(shadertype)
3501         {
3502         case GL_VERTEX_SHADER:
3503         case GL_FRAGMENT_SHADER:
3504                 break;
3505         default:
3506                 return error(GL_INVALID_ENUM);
3507         }
3508
3509         switch(precisiontype)
3510         {
3511         case GL_LOW_FLOAT:
3512         case GL_MEDIUM_FLOAT:
3513         case GL_HIGH_FLOAT:
3514                 // IEEE 754 single-precision
3515                 range[0] = 127;
3516                 range[1] = 127;
3517                 *precision = 23;
3518                 break;
3519         case GL_LOW_INT:
3520         case GL_MEDIUM_INT:
3521         case GL_HIGH_INT:
3522                 // Full integer precision is supported
3523                 range[0] = 31;
3524                 range[1] = 30;
3525                 *precision = 0;
3526                 break;
3527         default:
3528                 return error(GL_INVALID_ENUM);
3529         }
3530 }
3531
3532 void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3533 {
3534         TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
3535               shader, bufsize, length, source);
3536
3537         if(bufsize < 0)
3538         {
3539                 return error(GL_INVALID_VALUE);
3540         }
3541
3542         es2::Context *context = es2::getContext();
3543
3544         if(context)
3545         {
3546                 es2::Shader *shaderObject = context->getShader(shader);
3547
3548                 if(!shaderObject)
3549                 {
3550                         if(context->getProgram(shader))
3551                         {
3552                                 return error(GL_INVALID_OPERATION);
3553                         }
3554                         else
3555                         {
3556                                 return error(GL_INVALID_VALUE);
3557                         }
3558                 }
3559
3560                 shaderObject->getSource(bufsize, length, source);
3561         }
3562 }
3563
3564 const GLubyte* GetString(GLenum name)
3565 {
3566         TRACE("(GLenum name = 0x%X)", name);
3567
3568         switch(name)
3569         {
3570         case GL_VENDOR:
3571                 return (GLubyte*)"Google Inc.";
3572         case GL_RENDERER:
3573                 return (GLubyte*)"Google SwiftShader";
3574         case GL_VERSION:
3575         {
3576                 es2::Context *context = es2::getContext();
3577                 return (context && (context->getClientVersion() >= 3)) ?
3578                        (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :
3579                        (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3580         }
3581         case GL_SHADING_LANGUAGE_VERSION:
3582         {
3583                 es2::Context *context = es2::getContext();
3584                 return (context && (context->getClientVersion() >= 3)) ?
3585                        (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :
3586                        (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3587         }
3588         case GL_EXTENSIONS:
3589         {
3590                 es2::Context *context = es2::getContext();
3591                 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)nullptr;
3592         }
3593         default:
3594                 return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
3595         }
3596 }
3597
3598 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3599 {
3600         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
3601
3602         es2::Context *context = es2::getContext();
3603
3604         if(context)
3605         {
3606                 es2::Texture *texture;
3607
3608                 GLint clientVersion = context->getClientVersion();
3609
3610                 switch(target)
3611                 {
3612                 case GL_TEXTURE_2D:
3613                         texture = context->getTexture2D();
3614                         break;
3615                 case GL_TEXTURE_CUBE_MAP:
3616                         texture = context->getTextureCubeMap();
3617                         break;
3618                 case GL_TEXTURE_EXTERNAL_OES:
3619                         texture = context->getTextureExternal();
3620                         break;
3621                 case GL_TEXTURE_2D_ARRAY:
3622                         if(clientVersion < 3)
3623                         {
3624                                 return error(GL_INVALID_ENUM);
3625                         }
3626                         else
3627                         {
3628                                 texture = context->getTexture2DArray();
3629                         }
3630                         break;
3631                 case GL_TEXTURE_3D_OES:
3632                         texture = context->getTexture3D();
3633                         break;
3634                 default:
3635                         return error(GL_INVALID_ENUM);
3636                 }
3637
3638                 switch(pname)
3639                 {
3640                 case GL_TEXTURE_MAG_FILTER:
3641                         *params = (GLfloat)texture->getMagFilter();
3642                         break;
3643                 case GL_TEXTURE_MIN_FILTER:
3644                         *params = (GLfloat)texture->getMinFilter();
3645                         break;
3646                 case GL_TEXTURE_WRAP_S:
3647                         *params = (GLfloat)texture->getWrapS();
3648                         break;
3649                 case GL_TEXTURE_WRAP_T:
3650                         *params = (GLfloat)texture->getWrapT();
3651                         break;
3652                 case GL_TEXTURE_WRAP_R_OES:
3653                         *params = (GLfloat)texture->getWrapR();
3654                         break;
3655                 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3656                         *params = texture->getMaxAnisotropy();
3657                         break;
3658                 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3659                         *params = (GLfloat)1;
3660                         break;
3661                 case GL_TEXTURE_BASE_LEVEL:
3662                         if(clientVersion >= 3)
3663                         {
3664                                 *params = (GLfloat)texture->getBaseLevel();
3665                                 break;
3666                         }
3667                         else return error(GL_INVALID_ENUM);
3668                 case GL_TEXTURE_COMPARE_FUNC:
3669                         if(clientVersion >= 3)
3670                         {
3671                                 *params = (GLfloat)texture->getCompareFunc();
3672                                 break;
3673                         }
3674                         else return error(GL_INVALID_ENUM);
3675                 case GL_TEXTURE_COMPARE_MODE:
3676                         if(clientVersion >= 3)
3677                         {
3678                                 *params = (GLfloat)texture->getCompareMode();
3679                                 break;
3680                         }
3681                         else return error(GL_INVALID_ENUM);
3682                 case GL_TEXTURE_IMMUTABLE_FORMAT:
3683                         if(clientVersion >= 3)
3684                         {
3685                                 *params = (GLfloat)texture->getImmutableFormat();
3686                                 break;
3687                         }
3688                         else return error(GL_INVALID_ENUM);
3689                 case GL_TEXTURE_IMMUTABLE_LEVELS:
3690                         if(clientVersion >= 3)
3691                         {
3692                                 *params = (GLfloat)texture->getImmutableLevels();
3693                                 break;
3694                         }
3695                         else return error(GL_INVALID_ENUM);
3696                 case GL_TEXTURE_MAX_LEVEL:
3697                         if(clientVersion >= 3)
3698                         {
3699                                 *params = (GLfloat)texture->getMaxLevel();
3700                                 break;
3701                         }
3702                         else return error(GL_INVALID_ENUM);
3703                 case GL_TEXTURE_MAX_LOD:
3704                         if(clientVersion >= 3)
3705                         {
3706                                 *params = texture->getMaxLOD();
3707                                 break;
3708                         }
3709                         else return error(GL_INVALID_ENUM);
3710                 case GL_TEXTURE_MIN_LOD:
3711                         if(clientVersion >= 3)
3712                         {
3713                                 *params = texture->getMinLOD();
3714                                 break;
3715                         }
3716                         else return error(GL_INVALID_ENUM);
3717                 case GL_TEXTURE_SWIZZLE_R:
3718                         if(clientVersion >= 3)
3719                         {
3720                                 *params = (GLfloat)texture->getSwizzleR();
3721                                 break;
3722                         }
3723                         else return error(GL_INVALID_ENUM);
3724                 case GL_TEXTURE_SWIZZLE_G:
3725                         if(clientVersion >= 3)
3726                         {
3727                                 *params = (GLfloat)texture->getSwizzleG();
3728                                 break;
3729                         }
3730                         else return error(GL_INVALID_ENUM);
3731                 case GL_TEXTURE_SWIZZLE_B:
3732                         if(clientVersion >= 3)
3733                         {
3734                                 *params = (GLfloat)texture->getSwizzleB();
3735                                 break;
3736                         }
3737                         else return error(GL_INVALID_ENUM);
3738                 case GL_TEXTURE_SWIZZLE_A:
3739                         if(clientVersion >= 3)
3740                         {
3741                                 *params = (GLfloat)texture->getSwizzleA();
3742                                 break;
3743                         }
3744                         else return error(GL_INVALID_ENUM);
3745                 default:
3746                         return error(GL_INVALID_ENUM);
3747                 }
3748         }
3749 }
3750
3751 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3752 {
3753         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3754
3755         es2::Context *context = es2::getContext();
3756
3757         if(context)
3758         {
3759                 es2::Texture *texture;
3760
3761                 GLint clientVersion = context->getClientVersion();
3762
3763                 switch(target)
3764                 {
3765                 case GL_TEXTURE_2D:
3766                         texture = context->getTexture2D();
3767                         break;
3768                 case GL_TEXTURE_CUBE_MAP:
3769                         texture = context->getTextureCubeMap();
3770                         break;
3771                 case GL_TEXTURE_EXTERNAL_OES:
3772                         texture = context->getTextureExternal();
3773                         break;
3774                 case GL_TEXTURE_2D_ARRAY:
3775                         if(clientVersion < 3)
3776                         {
3777                                 return error(GL_INVALID_ENUM);
3778                         }
3779                         else
3780                         {
3781                                 texture = context->getTexture2DArray();
3782                         }
3783                         break;
3784                 case GL_TEXTURE_3D_OES:
3785                         texture = context->getTexture3D();
3786                         break;
3787                 default:
3788                         return error(GL_INVALID_ENUM);
3789                 }
3790
3791                 switch(pname)
3792                 {
3793                 case GL_TEXTURE_MAG_FILTER:
3794                         *params = texture->getMagFilter();
3795                         break;
3796                 case GL_TEXTURE_MIN_FILTER:
3797                         *params = texture->getMinFilter();
3798                         break;
3799                 case GL_TEXTURE_WRAP_S:
3800                         *params = texture->getWrapS();
3801                         break;
3802                 case GL_TEXTURE_WRAP_T:
3803                         *params = texture->getWrapT();
3804                         break;
3805                 case GL_TEXTURE_WRAP_R_OES:
3806                         *params = texture->getWrapR();
3807                         break;
3808                 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3809                         *params = (GLint)texture->getMaxAnisotropy();
3810                         break;
3811                 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3812                         *params = 1;
3813                         break;
3814                 case GL_TEXTURE_BASE_LEVEL:
3815                         if(clientVersion >= 3)
3816                         {
3817                                 *params = texture->getBaseLevel();
3818                                 break;
3819                         }
3820                         else return error(GL_INVALID_ENUM);
3821                 case GL_TEXTURE_COMPARE_FUNC:
3822                         if(clientVersion >= 3)
3823                         {
3824                                 *params = (GLint)texture->getCompareFunc();
3825                                 break;
3826                         }
3827                         else return error(GL_INVALID_ENUM);
3828                 case GL_TEXTURE_COMPARE_MODE:
3829                         if(clientVersion >= 3)
3830                         {
3831                                 *params = (GLint)texture->getCompareMode();
3832                                 break;
3833                         }
3834                         else return error(GL_INVALID_ENUM);
3835                 case GL_TEXTURE_IMMUTABLE_FORMAT:
3836                         if(clientVersion >= 3)
3837                         {
3838                                 *params = (GLint)texture->getImmutableFormat();
3839                                 break;
3840                         }
3841                         else return error(GL_INVALID_ENUM);
3842                 case GL_TEXTURE_IMMUTABLE_LEVELS:
3843                         if(clientVersion >= 3)
3844                         {
3845                                 *params = (GLint)texture->getImmutableLevels();
3846                                 break;
3847                         }
3848                         else return error(GL_INVALID_ENUM);
3849                 case GL_TEXTURE_MAX_LEVEL:
3850                         if(clientVersion >= 3)
3851                         {
3852                                 *params = texture->getMaxLevel();
3853                                 break;
3854                         }
3855                         else return error(GL_INVALID_ENUM);
3856                 case GL_TEXTURE_MAX_LOD:
3857                         if(clientVersion >= 3)
3858                         {
3859                                 *params = (GLint)roundf(texture->getMaxLOD());
3860                                 break;
3861                         }
3862                         else return error(GL_INVALID_ENUM);
3863                 case GL_TEXTURE_MIN_LOD:
3864                         if(clientVersion >= 3)
3865                         {
3866                                 *params = (GLint)roundf(texture->getMinLOD());
3867                                 break;
3868                         }
3869                         else return error(GL_INVALID_ENUM);
3870                 case GL_TEXTURE_SWIZZLE_R:
3871                         if(clientVersion >= 3)
3872                         {
3873                                 *params = (GLint)texture->getSwizzleR();
3874                                 break;
3875                         }
3876                         else return error(GL_INVALID_ENUM);
3877                 case GL_TEXTURE_SWIZZLE_G:
3878                         if(clientVersion >= 3)
3879                         {
3880                                 *params = (GLint)texture->getSwizzleG();
3881                                 break;
3882                         }
3883                         else return error(GL_INVALID_ENUM);
3884                 case GL_TEXTURE_SWIZZLE_B:
3885                         if(clientVersion >= 3)
3886                         {
3887                                 *params = (GLint)texture->getSwizzleB();
3888                                 break;
3889                         }
3890                         else return error(GL_INVALID_ENUM);
3891                 case GL_TEXTURE_SWIZZLE_A:
3892                         if(clientVersion >= 3)
3893                         {
3894                                 *params = (GLint)texture->getSwizzleA();
3895                                 break;
3896                         }
3897                         else return error(GL_INVALID_ENUM);
3898                 default:
3899                         return error(GL_INVALID_ENUM);
3900                 }
3901         }
3902 }
3903
3904 void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3905 {
3906         TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
3907               program, location, bufSize, params);
3908
3909         if(bufSize < 0)
3910         {
3911                 return error(GL_INVALID_VALUE);
3912         }
3913
3914         es2::Context *context = es2::getContext();
3915
3916         if(context)
3917         {
3918                 es2::Program *programObject = context->getProgram(program);
3919
3920                 if(!programObject)
3921                 {
3922                         if(context->getShader(program))
3923                         {
3924                                 return error(GL_INVALID_OPERATION);
3925                         }
3926                         else
3927                         {
3928                                 return error(GL_INVALID_VALUE);
3929                         }
3930                 }
3931
3932                 if(!programObject->isLinked())
3933                 {
3934                         return error(GL_INVALID_OPERATION);
3935                 }
3936
3937                 if(!programObject->getUniformfv(location, &bufSize, params))
3938                 {
3939                         return error(GL_INVALID_OPERATION);
3940                 }
3941         }
3942 }
3943
3944 void GetUniformfv(GLuint program, GLint location, GLfloat* params)
3945 {
3946         TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
3947
3948         es2::Context *context = es2::getContext();
3949
3950         if(context)
3951         {
3952                 es2::Program *programObject = context->getProgram(program);
3953
3954                 if(!programObject)
3955                 {
3956                         if(context->getShader(program))
3957                         {
3958                                 return error(GL_INVALID_OPERATION);
3959                         }
3960                         else
3961                         {
3962                                 return error(GL_INVALID_VALUE);
3963                         }
3964                 }
3965
3966                 if(!programObject->isLinked())
3967                 {
3968                         return error(GL_INVALID_OPERATION);
3969                 }
3970
3971                 if(!programObject->getUniformfv(location, nullptr, params))
3972                 {
3973                         return error(GL_INVALID_OPERATION);
3974                 }
3975         }
3976 }
3977
3978 void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3979 {
3980         TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
3981               program, location, bufSize, params);
3982
3983         if(bufSize < 0)
3984         {
3985                 return error(GL_INVALID_VALUE);
3986         }
3987
3988         es2::Context *context = es2::getContext();
3989
3990         if(context)
3991         {
3992                 es2::Program *programObject = context->getProgram(program);
3993
3994                 if(!programObject)
3995                 {
3996                         if(context->getShader(program))
3997                         {
3998                                 return error(GL_INVALID_OPERATION);
3999                         }
4000                         else
4001                         {
4002                                 return error(GL_INVALID_VALUE);
4003                         }
4004                 }
4005
4006                 if(!programObject->isLinked())
4007                 {
4008                         return error(GL_INVALID_OPERATION);
4009                 }
4010
4011                 if(!programObject->getUniformiv(location, &bufSize, params))
4012                 {
4013                         return error(GL_INVALID_OPERATION);
4014                 }
4015         }
4016 }
4017
4018 void GetUniformiv(GLuint program, GLint location, GLint* params)
4019 {
4020         TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
4021
4022         es2::Context *context = es2::getContext();
4023
4024         if(context)
4025         {
4026                 es2::Program *programObject = context->getProgram(program);
4027
4028                 if(!programObject)
4029                 {
4030                         if(context->getShader(program))
4031                         {
4032                                 return error(GL_INVALID_OPERATION);
4033                         }
4034                         else
4035                         {
4036                                 return error(GL_INVALID_VALUE);
4037                         }
4038                 }
4039
4040                 if(!programObject->isLinked())
4041                 {
4042                         return error(GL_INVALID_OPERATION);
4043                 }
4044
4045                 if(!programObject->getUniformiv(location, nullptr, params))
4046                 {
4047                         return error(GL_INVALID_OPERATION);
4048                 }
4049         }
4050 }
4051
4052 int GetUniformLocation(GLuint program, const GLchar* name)
4053 {
4054         TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
4055
4056         es2::Context *context = es2::getContext();
4057
4058         if(strstr(name, "gl_") == name)
4059         {
4060                 return -1;
4061         }
4062
4063         if(context)
4064         {
4065                 es2::Program *programObject = context->getProgram(program);
4066
4067                 if(!programObject)
4068                 {
4069                         if(context->getShader(program))
4070                         {
4071                                 return error(GL_INVALID_OPERATION, -1);
4072                         }
4073                         else
4074                         {
4075                                 return error(GL_INVALID_VALUE, -1);
4076                         }
4077                 }
4078
4079                 if(!programObject->isLinked())
4080                 {
4081                         return error(GL_INVALID_OPERATION, -1);
4082                 }
4083
4084                 return programObject->getUniformLocation(name);
4085         }
4086
4087         return -1;
4088 }
4089
4090 void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4091 {
4092         TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
4093
4094         es2::Context *context = es2::getContext();
4095
4096         if(context)
4097         {
4098                 if(index >= es2::MAX_VERTEX_ATTRIBS)
4099                 {
4100                         return error(GL_INVALID_VALUE);
4101                 }
4102
4103                 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4104
4105                 GLint clientVersion = context->getClientVersion();
4106
4107                 switch(pname)
4108                 {
4109                 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4110                         *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4111                         break;
4112                 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4113                         *params = (GLfloat)attribState.mSize;
4114                         break;
4115                 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4116                         *params = (GLfloat)attribState.mStride;
4117                         break;
4118                 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4119                         *params = (GLfloat)attribState.mType;
4120                         break;
4121                 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4122                         *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
4123                         break;
4124                 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4125                         *params = (GLfloat)attribState.mBoundBuffer.name();
4126                         break;
4127                 case GL_CURRENT_VERTEX_ATTRIB:
4128                         {
4129                                 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4130                                 for(int i = 0; i < 4; ++i)
4131                                 {
4132                                         params[i] = attrib.getCurrentValueF(i);
4133                                 }
4134                         }
4135                         break;
4136                 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4137                         if(clientVersion >= 3)
4138                         {
4139                                 switch(attribState.mType)
4140                                 {
4141                                 case GL_BYTE:
4142                                 case GL_UNSIGNED_BYTE:
4143                                 case GL_SHORT:
4144                                 case GL_UNSIGNED_SHORT:
4145                                 case GL_INT:
4146                                 case GL_INT_2_10_10_10_REV:
4147                                 case GL_UNSIGNED_INT:
4148                                 case GL_FIXED:
4149                                         *params = (GLfloat)GL_TRUE;
4150                                         break;
4151                                 default:
4152                                         *params = (GLfloat)GL_FALSE;
4153                                         break;
4154                                 }
4155                                 break;
4156                         }
4157                         else return error(GL_INVALID_ENUM);
4158                 default: return error(GL_INVALID_ENUM);
4159                 }
4160         }
4161 }
4162
4163 void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4164 {
4165         TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
4166
4167         es2::Context *context = es2::getContext();
4168
4169         if(context)
4170         {
4171                 if(index >= es2::MAX_VERTEX_ATTRIBS)
4172                 {
4173                         return error(GL_INVALID_VALUE);
4174                 }
4175
4176                 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4177
4178                 GLint clientVersion = context->getClientVersion();
4179
4180                 switch(pname)
4181                 {
4182                 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4183                         *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4184                         break;
4185                 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4186                         *params = attribState.mSize;
4187                         break;
4188                 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4189                         *params = attribState.mStride;
4190                         break;
4191                 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4192                         *params = attribState.mType;
4193                         break;
4194                 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4195                         *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
4196                         break;
4197                 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4198                         *params = attribState.mBoundBuffer.name();
4199                         break;
4200                 case GL_CURRENT_VERTEX_ATTRIB:
4201                         {
4202                                 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4203                                 for(int i = 0; i < 4; ++i)
4204                                 {
4205                                         float currentValue = attrib.getCurrentValueF(i);
4206                                         params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4207                                 }
4208                         }
4209                         break;
4210                 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4211                         if(clientVersion >= 3)
4212                         {
4213                                 switch(attribState.mType)
4214                                 {
4215                                 case GL_BYTE:
4216                                 case GL_UNSIGNED_BYTE:
4217                                 case GL_SHORT:
4218                                 case GL_UNSIGNED_SHORT:
4219                                 case GL_INT:
4220                                 case GL_INT_2_10_10_10_REV:
4221                                 case GL_UNSIGNED_INT:
4222                                 case GL_FIXED:
4223                                         *params = GL_TRUE;
4224                                         break;
4225                                 default:
4226                                         *params = GL_FALSE;
4227                                         break;
4228                                 }
4229                                 break;
4230                         }
4231                         else return error(GL_INVALID_ENUM);
4232                 default: return error(GL_INVALID_ENUM);
4233                 }
4234         }
4235 }
4236
4237 void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
4238 {
4239         TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
4240
4241         es2::Context *context = es2::getContext();
4242
4243         if(context)
4244         {
4245                 if(index >= es2::MAX_VERTEX_ATTRIBS)
4246                 {
4247                         return error(GL_INVALID_VALUE);
4248                 }
4249
4250                 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4251                 {
4252                         return error(GL_INVALID_ENUM);
4253                 }
4254
4255                 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
4256         }
4257 }
4258
4259 void Hint(GLenum target, GLenum mode)
4260 {
4261         TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
4262
4263         switch(mode)
4264         {
4265         case GL_FASTEST:
4266         case GL_NICEST:
4267         case GL_DONT_CARE:
4268                 break;
4269         default:
4270                 return error(GL_INVALID_ENUM);
4271         }
4272
4273         es2::Context *context = es2::getContext();
4274         switch(target)
4275         {
4276         case GL_GENERATE_MIPMAP_HINT:
4277                 if(context) context->setGenerateMipmapHint(mode);
4278                 break;
4279         case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4280                 if(context) context->setFragmentShaderDerivativeHint(mode);
4281                 break;
4282         case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
4283                 if(context) context->setTextureFilteringHint(mode);
4284                 break;
4285         default:
4286                 return error(GL_INVALID_ENUM);
4287         }
4288 }
4289
4290 GLboolean IsBuffer(GLuint buffer)
4291 {
4292         TRACE("(GLuint buffer = %d)", buffer);
4293
4294         es2::Context *context = es2::getContext();
4295
4296         if(context && buffer)
4297         {
4298                 es2::Buffer *bufferObject = context->getBuffer(buffer);
4299
4300                 if(bufferObject)
4301                 {
4302                         return GL_TRUE;
4303                 }
4304         }
4305
4306         return GL_FALSE;
4307 }
4308
4309 GLboolean IsEnabled(GLenum cap)
4310 {
4311         TRACE("(GLenum cap = 0x%X)", cap);
4312
4313         es2::Context *context = es2::getContext();
4314
4315         if(context)
4316         {
4317                 GLint clientVersion = context->getClientVersion();
4318
4319                 switch(cap)
4320                 {
4321                 case GL_CULL_FACE:                return context->isCullFaceEnabled();
4322                 case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
4323                 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4324                 case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
4325                 case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
4326                 case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
4327                 case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
4328                 case GL_BLEND:                    return context->isBlendEnabled();
4329                 case GL_DITHER:                   return context->isDitherEnabled();
4330                 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4331                         if(clientVersion >= 3)
4332                         {
4333                                 return context->isPrimitiveRestartFixedIndexEnabled();
4334                         }
4335                         else return error(GL_INVALID_ENUM, false);
4336                 case GL_RASTERIZER_DISCARD:
4337                         if(clientVersion >= 3)
4338                         {
4339                                 return context->isRasterizerDiscardEnabled();
4340                         }
4341                         else return error(GL_INVALID_ENUM, false);
4342                 default:
4343                         return error(GL_INVALID_ENUM, false);
4344                 }
4345         }
4346
4347         return false;
4348 }
4349
4350 GLboolean IsFenceNV(GLuint fence)
4351 {
4352         TRACE("(GLuint fence = %d)", fence);
4353
4354         es2::Context *context = es2::getContext();
4355
4356         if(context)
4357         {
4358                 es2::Fence *fenceObject = context->getFence(fence);
4359
4360                 if(!fenceObject)
4361                 {
4362                         return GL_FALSE;
4363                 }
4364
4365                 return fenceObject->isFence();
4366         }
4367
4368         return GL_FALSE;
4369 }
4370
4371 GLboolean IsFramebuffer(GLuint framebuffer)
4372 {
4373         TRACE("(GLuint framebuffer = %d)", framebuffer);
4374
4375         es2::Context *context = es2::getContext();
4376
4377         if(context && framebuffer)
4378         {
4379                 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4380
4381                 if(framebufferObject)
4382                 {
4383                         return GL_TRUE;
4384                 }
4385         }
4386
4387         return GL_FALSE;
4388 }
4389
4390 GLboolean IsProgram(GLuint program)
4391 {
4392         TRACE("(GLuint program = %d)", program);
4393
4394         es2::Context *context = es2::getContext();
4395
4396         if(context && program)
4397         {
4398                 es2::Program *programObject = context->getProgram(program);
4399
4400                 if(programObject)
4401                 {
4402                         return GL_TRUE;
4403                 }
4404         }
4405
4406         return GL_FALSE;
4407 }
4408
4409 GLboolean IsQueryEXT(GLuint name)
4410 {
4411         TRACE("(GLuint name = %d)", name);
4412
4413         if(name == 0)
4414         {
4415                 return GL_FALSE;
4416         }
4417
4418         es2::Context *context = es2::getContext();
4419
4420         if(context)
4421         {
4422                 es2::Query *queryObject = context->getQuery(name);
4423
4424                 if(queryObject)
4425                 {
4426                         return GL_TRUE;
4427                 }
4428         }
4429
4430         return GL_FALSE;
4431 }
4432
4433 GLboolean IsRenderbuffer(GLuint renderbuffer)
4434 {
4435         TRACE("(GLuint renderbuffer = %d)", renderbuffer);
4436
4437         es2::Context *context = es2::getContext();
4438
4439         if(context && renderbuffer)
4440         {
4441                 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4442
4443                 if(renderbufferObject)
4444                 {
4445                         return GL_TRUE;
4446                 }
4447         }
4448
4449         return GL_FALSE;
4450 }
4451
4452 GLboolean IsShader(GLuint shader)
4453 {
4454         TRACE("(GLuint shader = %d)", shader);
4455
4456         es2::Context *context = es2::getContext();
4457
4458         if(context && shader)
4459         {
4460                 es2::Shader *shaderObject = context->getShader(shader);
4461
4462                 if(shaderObject)
4463                 {
4464                         return GL_TRUE;
4465                 }
4466         }
4467
4468         return GL_FALSE;
4469 }
4470
4471 GLboolean IsTexture(GLuint texture)
4472 {
4473         TRACE("(GLuint texture = %d)", texture);
4474
4475         es2::Context *context = es2::getContext();
4476
4477         if(context && texture)
4478         {
4479                 es2::Texture *textureObject = context->getTexture(texture);
4480
4481                 if(textureObject)
4482                 {
4483                         return GL_TRUE;
4484                 }
4485         }
4486
4487         return GL_FALSE;
4488 }
4489
4490 void LineWidth(GLfloat width)
4491 {
4492         TRACE("(GLfloat width = %f)", width);
4493
4494         if(width <= 0.0f)
4495         {
4496                 return error(GL_INVALID_VALUE);
4497         }
4498
4499         es2::Context *context = es2::getContext();
4500
4501         if(context)
4502         {
4503                 context->setLineWidth(width);
4504         }
4505 }
4506
4507 void LinkProgram(GLuint program)
4508 {
4509         TRACE("(GLuint program = %d)", program);
4510
4511         es2::Context *context = es2::getContext();
4512
4513         if(context)
4514         {
4515                 es2::Program *programObject = context->getProgram(program);
4516
4517                 if(!programObject)
4518                 {
4519                         if(context->getShader(program))
4520                         {
4521                                 return error(GL_INVALID_OPERATION);
4522                         }
4523                         else
4524                         {
4525                                 return error(GL_INVALID_VALUE);
4526                         }
4527                 }
4528
4529                 programObject->link();
4530         }
4531 }
4532
4533 void PixelStorei(GLenum pname, GLint param)
4534 {
4535         TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
4536
4537         es2::Context *context = es2::getContext();
4538
4539         if(context)
4540         {
4541                 GLint clientVersion = context->getClientVersion();
4542
4543                 switch(pname)
4544                 {
4545                 case GL_UNPACK_ALIGNMENT:
4546                         if(param != 1 && param != 2 && param != 4 && param != 8)
4547                         {
4548                                 return error(GL_INVALID_VALUE);
4549                         }
4550                         context->setUnpackAlignment(param);
4551                         break;
4552                 case GL_PACK_ALIGNMENT:
4553                         if(param != 1 && param != 2 && param != 4 && param != 8)
4554                         {
4555                                 return error(GL_INVALID_VALUE);
4556                         }
4557                         context->setPackAlignment(param);
4558                         break;
4559                 case GL_PACK_ROW_LENGTH:
4560                         if(clientVersion >= 3)
4561                         {
4562                                 if(param < 0)
4563                                 {
4564                                         return error(GL_INVALID_VALUE);
4565                                 }
4566                                 context->setPackRowLength(param);
4567                                 break;
4568                         }
4569                         else return error(GL_INVALID_ENUM);
4570                 case GL_PACK_SKIP_PIXELS:
4571                         if(clientVersion >= 3)
4572                         {
4573                                 if(param < 0)
4574                                 {
4575                                         return error(GL_INVALID_VALUE);
4576                                 }
4577                                 context->setPackSkipPixels(param);
4578                                 break;
4579                         }
4580                         else return error(GL_INVALID_ENUM);
4581                 case GL_PACK_SKIP_ROWS:
4582                         if(clientVersion >= 3)
4583                         {
4584                                 if(param < 0)
4585                                 {
4586                                         return error(GL_INVALID_VALUE);
4587                                 }
4588                                 context->setPackSkipRows(param);
4589                                 break;
4590                         }
4591                         else return error(GL_INVALID_ENUM);
4592                 case GL_UNPACK_ROW_LENGTH:
4593                         if(clientVersion >= 3)
4594                         {
4595                                 if(param < 0)
4596                                 {
4597                                         return error(GL_INVALID_VALUE);
4598                                 }
4599                                 context->setUnpackRowLength(param);
4600                                 break;
4601                         }
4602                         else return error(GL_INVALID_ENUM);
4603                 case GL_UNPACK_IMAGE_HEIGHT:
4604                         if(clientVersion >= 3)
4605                         {
4606                                 if(param < 0)
4607                                 {
4608                                         return error(GL_INVALID_VALUE);
4609                                 }
4610                                 context->setUnpackImageHeight(param);
4611                                 break;
4612                         }
4613                         else return error(GL_INVALID_ENUM);
4614                 case GL_UNPACK_SKIP_PIXELS:
4615                         if(clientVersion >= 3)
4616                         {
4617                                 if(param < 0)
4618                                 {
4619                                         return error(GL_INVALID_VALUE);
4620                                 }
4621                                 context->setUnpackSkipPixels(param);
4622                                 break;
4623                         }
4624                         else return error(GL_INVALID_ENUM);
4625                 case GL_UNPACK_SKIP_ROWS:
4626                         if(clientVersion >= 3)
4627                         {
4628                                 if(param < 0)
4629                                 {
4630                                         return error(GL_INVALID_VALUE);
4631                                 }
4632                                 context->setUnpackSkipRows(param);
4633                                 break;
4634                         }
4635                         else return error(GL_INVALID_ENUM);
4636                 case GL_UNPACK_SKIP_IMAGES:
4637                         if(clientVersion >= 3) {
4638                                 if(param < 0)
4639                                 {
4640                                         return error(GL_INVALID_VALUE);
4641                                 }
4642                                 context->setUnpackSkipImages(param);
4643                                 break;
4644                         }
4645                         else return error(GL_INVALID_ENUM);
4646                 default:
4647                         return error(GL_INVALID_ENUM);
4648                 }
4649         }
4650 }
4651
4652 void PolygonOffset(GLfloat factor, GLfloat units)
4653 {
4654         TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
4655
4656         es2::Context *context = es2::getContext();
4657
4658         if(context)
4659         {
4660                 context->setPolygonOffsetParams(factor, units);
4661         }
4662 }
4663
4664 void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4665                     GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
4666 {
4667         TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4668               "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
4669               x, y, width, height, format, type, bufSize, data);
4670
4671         if(width < 0 || height < 0 || bufSize < 0)
4672         {
4673                 return error(GL_INVALID_VALUE);
4674         }
4675
4676         es2::Context *context = es2::getContext();
4677
4678         if(context)
4679         {
4680                 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4681         }
4682 }
4683
4684 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
4685 {
4686         TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4687               "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
4688               x, y, width, height, format, type,  pixels);
4689
4690         if(width < 0 || height < 0)
4691         {
4692                 return error(GL_INVALID_VALUE);
4693         }
4694
4695         es2::Context *context = es2::getContext();
4696
4697         if(context)
4698         {
4699                 context->readPixels(x, y, width, height, format, type, nullptr, pixels);
4700         }
4701 }
4702
4703 void ReleaseShaderCompiler(void)
4704 {
4705         TRACE("()");
4706
4707         es2::Shader::releaseCompiler();
4708 }
4709
4710 void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4711 {
4712         TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4713               target, samples, internalformat, width, height);
4714
4715         switch(target)
4716         {
4717         case GL_RENDERBUFFER:
4718                 break;
4719         default:
4720                 return error(GL_INVALID_ENUM);
4721         }
4722
4723         if(width < 0 || height < 0 || samples < 0)
4724         {
4725                 return error(GL_INVALID_VALUE);
4726         }
4727
4728         es2::Context *context = es2::getContext();
4729
4730         if(context)
4731         {
4732                 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4733                    height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4734                    samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4735                 {
4736                         return error(GL_INVALID_VALUE);
4737                 }
4738
4739                 GLuint handle = context->getRenderbufferName();
4740                 if(handle == 0)
4741                 {
4742                         return error(GL_INVALID_OPERATION);
4743                 }
4744
4745                 GLint clientVersion = context->getClientVersion();
4746
4747                 if(IsColorRenderable(internalformat, clientVersion, false))
4748                 {
4749                         context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4750                 }
4751                 else if(IsDepthRenderable(internalformat, clientVersion) && IsStencilRenderable(internalformat, clientVersion))
4752                 {
4753                         context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));
4754                 }
4755                 else if(IsDepthRenderable(internalformat, clientVersion))
4756                 {
4757                         context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));
4758                 }
4759                 else if(IsStencilRenderable(internalformat, clientVersion))
4760                 {
4761                         context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4762                 }
4763                 else error(GL_INVALID_ENUM);
4764         }
4765 }
4766
4767 void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4768 {
4769         RenderbufferStorageMultisample(target, samples, internalformat, width, height);
4770 }
4771
4772 void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4773 {
4774         RenderbufferStorageMultisample(target, 0, internalformat, width, height);
4775 }
4776
4777 void SampleCoverage(GLclampf value, GLboolean invert)
4778 {
4779         TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
4780
4781         es2::Context* context = es2::getContext();
4782
4783         if(context)
4784         {
4785                 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4786         }
4787 }
4788
4789 void SetFenceNV(GLuint fence, GLenum condition)
4790 {
4791         TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4792
4793         if(condition != GL_ALL_COMPLETED_NV)
4794         {
4795                 return error(GL_INVALID_ENUM);
4796         }
4797
4798         es2::Context *context = es2::getContext();
4799
4800         if(context)
4801         {
4802                 es2::Fence *fenceObject = context->getFence(fence);
4803
4804                 if(!fenceObject)
4805                 {
4806                         return error(GL_INVALID_OPERATION);
4807                 }
4808
4809                 fenceObject->setFence(condition);
4810         }
4811 }
4812
4813 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
4814 {
4815         TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4816
4817         if(width < 0 || height < 0)
4818         {
4819                 return error(GL_INVALID_VALUE);
4820         }
4821
4822         es2::Context* context = es2::getContext();
4823
4824         if(context)
4825         {
4826                 context->setScissorParams(x, y, width, height);
4827         }
4828 }
4829
4830 void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4831 {
4832         TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4833               "const GLvoid* binary = %p, GLsizei length = %d)",
4834               n, shaders, binaryformat, binary, length);
4835
4836         // No binary shader formats are supported.
4837         return error(GL_INVALID_ENUM);
4838 }
4839
4840 void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
4841 {
4842         TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
4843               shader, count, string, length);
4844
4845         if(count < 0)
4846         {
4847                 return error(GL_INVALID_VALUE);
4848         }
4849
4850         es2::Context *context = es2::getContext();
4851
4852         if(context)
4853         {
4854                 es2::Shader *shaderObject = context->getShader(shader);
4855
4856                 if(!shaderObject)
4857                 {
4858                         if(context->getProgram(shader))
4859                         {
4860                                 return error(GL_INVALID_OPERATION);
4861                         }
4862                         else
4863                         {
4864                                 return error(GL_INVALID_VALUE);
4865                         }
4866                 }
4867
4868                 shaderObject->setSource(count, string, length);
4869         }
4870 }
4871
4872 void StencilFunc(GLenum func, GLint ref, GLuint mask)
4873 {
4874         glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4875 }
4876
4877 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4878 {
4879         TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4880
4881         switch(face)
4882         {
4883         case GL_FRONT:
4884         case GL_BACK:
4885         case GL_FRONT_AND_BACK:
4886                 break;
4887         default:
4888                 return error(GL_INVALID_ENUM);
4889         }
4890
4891         switch(func)
4892         {
4893         case GL_NEVER:
4894         case GL_ALWAYS:
4895         case GL_LESS:
4896         case GL_LEQUAL:
4897         case GL_EQUAL:
4898         case GL_GEQUAL:
4899         case GL_GREATER:
4900         case GL_NOTEQUAL:
4901                 break;
4902         default:
4903                 return error(GL_INVALID_ENUM);
4904         }
4905
4906         es2::Context *context = es2::getContext();
4907
4908         if(context)
4909         {
4910                 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4911                 {
4912                         context->setStencilParams(func, ref, mask);
4913                 }
4914
4915                 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4916                 {
4917                         context->setStencilBackParams(func, ref, mask);
4918                 }
4919         }
4920 }
4921
4922 void StencilMask(GLuint mask)
4923 {
4924         glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4925 }
4926
4927 void StencilMaskSeparate(GLenum face, GLuint mask)
4928 {
4929         TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4930
4931         switch(face)
4932         {
4933         case GL_FRONT:
4934         case GL_BACK:
4935         case GL_FRONT_AND_BACK:
4936                 break;
4937         default:
4938                 return error(GL_INVALID_ENUM);
4939         }
4940
4941         es2::Context *context = es2::getContext();
4942
4943         if(context)
4944         {
4945                 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4946                 {
4947                         context->setStencilWritemask(mask);
4948                 }
4949
4950                 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4951                 {
4952                         context->setStencilBackWritemask(mask);
4953                 }
4954         }
4955 }
4956
4957 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4958 {
4959         glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4960 }
4961
4962 void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4963 {
4964         TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4965               face, fail, zfail, zpass);
4966
4967         switch(face)
4968         {
4969         case GL_FRONT:
4970         case GL_BACK:
4971         case GL_FRONT_AND_BACK:
4972                 break;
4973         default:
4974                 return error(GL_INVALID_ENUM);
4975         }
4976
4977         switch(fail)
4978         {
4979         case GL_ZERO:
4980         case GL_KEEP:
4981         case GL_REPLACE:
4982         case GL_INCR:
4983         case GL_DECR:
4984         case GL_INVERT:
4985         case GL_INCR_WRAP:
4986         case GL_DECR_WRAP:
4987                 break;
4988         default:
4989                 return error(GL_INVALID_ENUM);
4990         }
4991
4992         switch(zfail)
4993         {
4994         case GL_ZERO:
4995         case GL_KEEP:
4996         case GL_REPLACE:
4997         case GL_INCR:
4998         case GL_DECR:
4999         case GL_INVERT:
5000         case GL_INCR_WRAP:
5001         case GL_DECR_WRAP:
5002                 break;
5003         default:
5004                 return error(GL_INVALID_ENUM);
5005         }
5006
5007         switch(zpass)
5008         {
5009         case GL_ZERO:
5010         case GL_KEEP:
5011         case GL_REPLACE:
5012         case GL_INCR:
5013         case GL_DECR:
5014         case GL_INVERT:
5015         case GL_INCR_WRAP:
5016         case GL_DECR_WRAP:
5017                 break;
5018         default:
5019                 return error(GL_INVALID_ENUM);
5020         }
5021
5022         es2::Context *context = es2::getContext();
5023
5024         if(context)
5025         {
5026                 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
5027                 {
5028                         context->setStencilOperations(fail, zfail, zpass);
5029                 }
5030
5031                 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
5032                 {
5033                         context->setStencilBackOperations(fail, zfail, zpass);
5034                 }
5035         }
5036 }
5037
5038 GLboolean TestFenceNV(GLuint fence)
5039 {
5040         TRACE("(GLuint fence = %d)", fence);
5041
5042         es2::Context *context = es2::getContext();
5043
5044         if(context)
5045         {
5046                 es2::Fence *fenceObject = context->getFence(fence);
5047
5048                 if(!fenceObject)
5049                 {
5050                         return error(GL_INVALID_OPERATION, GL_TRUE);
5051                 }
5052
5053                 return fenceObject->testFence();
5054         }
5055
5056         return GL_TRUE;
5057 }
5058
5059 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5060                 GLint border, GLenum format, GLenum type, const GLvoid* data)
5061 {
5062         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
5063               "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* data =  %p)",
5064               target, level, internalformat, width, height, border, format, type, data);
5065
5066         if(!validImageSize(level, width, height))
5067         {
5068                 return error(GL_INVALID_VALUE);
5069         }
5070
5071         es2::Context *context = es2::getContext();
5072
5073         if(context)
5074         {
5075                 GLint clientVersion = context->getClientVersion();
5076                 if(clientVersion < 3)
5077                 {
5078                         if(internalformat != (GLint)format)
5079                         {
5080                                 return error(GL_INVALID_OPERATION);
5081                         }
5082                 }
5083
5084                 GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);
5085                 if(validationError != GL_NONE)
5086                 {
5087                         return error(validationError);
5088                 }
5089
5090                 if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
5091                 {
5092                         return;
5093                 }
5094
5095                 if(border != 0)
5096                 {
5097                         return error(GL_INVALID_VALUE);
5098                 }
5099
5100                 switch(target)
5101                 {
5102                 case GL_TEXTURE_2D:
5103                         if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5104                            height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
5105                         {
5106                                 return error(GL_INVALID_VALUE);
5107                         }
5108                         break;
5109                 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5110                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5111                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5112                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5113                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5114                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5115                         if(width != height)
5116                         {
5117                                 return error(GL_INVALID_VALUE);
5118                         }
5119
5120                         if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5121                            height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5122                         {
5123                                 return error(GL_INVALID_VALUE);
5124                         }
5125                         break;
5126                 default:
5127                         return error(GL_INVALID_ENUM);
5128                 }
5129
5130                 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
5131
5132                 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
5133                 if(validationError != GL_NONE)
5134                 {
5135                         return error(validationError);
5136                 }
5137
5138                 if(target == GL_TEXTURE_2D)
5139                 {
5140                         es2::Texture2D *texture = context->getTexture2D();
5141
5142                         if(!texture)
5143                         {
5144                                 return error(GL_INVALID_OPERATION);
5145                         }
5146
5147                         texture->setImage(context, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
5148                 }
5149                 else
5150                 {
5151                         es2::TextureCubeMap *texture = context->getTextureCubeMap();
5152
5153                         if(!texture)
5154                         {
5155                                 return error(GL_INVALID_OPERATION);
5156                         }
5157
5158                         texture->setImage(context, target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
5159                 }
5160         }
5161 }
5162
5163 void TexParameterf(GLenum target, GLenum pname, GLfloat param)
5164 {
5165         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
5166
5167         es2::Context *context = es2::getContext();
5168
5169         if(context)
5170         {
5171                 es2::Texture *texture;
5172
5173                 GLint clientVersion = context->getClientVersion();
5174
5175                 switch(target)
5176                 {
5177                 case GL_TEXTURE_2D:
5178                         texture = context->getTexture2D();
5179                         break;
5180                 case GL_TEXTURE_2D_ARRAY:
5181                         if(clientVersion < 3)
5182                         {
5183                                 return error(GL_INVALID_ENUM);
5184                         }
5185                         else
5186                         {
5187                                 texture = context->getTexture2DArray();
5188                         }
5189                         break;
5190                 case GL_TEXTURE_3D_OES:
5191                         texture = context->getTexture3D();
5192                         break;
5193                 case GL_TEXTURE_CUBE_MAP:
5194                         texture = context->getTextureCubeMap();
5195                         break;
5196                 case GL_TEXTURE_EXTERNAL_OES:
5197                         texture = context->getTextureExternal();
5198                         break;
5199                 default:
5200                         return error(GL_INVALID_ENUM);
5201                 }
5202
5203                 switch(pname)
5204                 {
5205                 case GL_TEXTURE_WRAP_S:
5206                         if(!texture->setWrapS((GLenum)param))
5207                         {
5208                                 return error(GL_INVALID_ENUM);
5209                         }
5210                         break;
5211                 case GL_TEXTURE_WRAP_T:
5212                         if(!texture->setWrapT((GLenum)param))
5213                         {
5214                                 return error(GL_INVALID_ENUM);
5215                         }
5216                         break;
5217                 case GL_TEXTURE_WRAP_R_OES:
5218                         if(!texture->setWrapR((GLenum)param))
5219                         {
5220                                 return error(GL_INVALID_ENUM);
5221                         }
5222                         break;
5223                 case GL_TEXTURE_MIN_FILTER:
5224                         if(!texture->setMinFilter((GLenum)param))
5225                         {
5226                                 return error(GL_INVALID_ENUM);
5227                         }
5228                         break;
5229                 case GL_TEXTURE_MAG_FILTER:
5230                         if(!texture->setMagFilter((GLenum)param))
5231                         {
5232                                 return error(GL_INVALID_ENUM);
5233                         }
5234                         break;
5235                 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5236                         if(!texture->setMaxAnisotropy(param))
5237                         {
5238                                 return error(GL_INVALID_VALUE);
5239                         }
5240                         break;
5241                 case GL_TEXTURE_BASE_LEVEL:
5242                         if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))
5243                         {
5244                                 return error(GL_INVALID_VALUE);
5245                         }
5246                         break;
5247                 case GL_TEXTURE_COMPARE_FUNC:
5248                         if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5249                         {
5250                                 return error(GL_INVALID_VALUE);
5251                         }
5252                         break;
5253                 case GL_TEXTURE_COMPARE_MODE:
5254                         if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5255                         {
5256                                 return error(GL_INVALID_VALUE);
5257                         }
5258                         break;
5259                 case GL_TEXTURE_MAX_LEVEL:
5260                         if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))
5261                         {
5262                                 return error(GL_INVALID_VALUE);
5263                         }
5264                         break;
5265                 case GL_TEXTURE_MAX_LOD:
5266                         if(clientVersion < 3 || !texture->setMaxLOD(param))
5267                         {
5268                                 return error(GL_INVALID_VALUE);
5269                         }
5270                         break;
5271                 case GL_TEXTURE_MIN_LOD:
5272                         if(clientVersion < 3 || !texture->setMinLOD(param))
5273                         {
5274                                 return error(GL_INVALID_VALUE);
5275                         }
5276                         break;
5277                 case GL_TEXTURE_SWIZZLE_R:
5278                         if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5279                         {
5280                                 return error(GL_INVALID_VALUE);
5281                         }
5282                         break;
5283                 case GL_TEXTURE_SWIZZLE_G:
5284                         if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5285                         {
5286                                 return error(GL_INVALID_VALUE);
5287                         }
5288                         break;
5289                 case GL_TEXTURE_SWIZZLE_B:
5290                         if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5291                         {
5292                                 return error(GL_INVALID_VALUE);
5293                         }
5294                         break;
5295                 case GL_TEXTURE_SWIZZLE_A:
5296                         if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5297                         {
5298                                 return error(GL_INVALID_VALUE);
5299                         }
5300                         break;
5301                 default:
5302                         return error(GL_INVALID_ENUM);
5303                 }
5304         }
5305 }
5306
5307 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5308 {
5309         glTexParameterf(target, pname, *params);
5310 }
5311
5312 void TexParameteri(GLenum target, GLenum pname, GLint param)
5313 {
5314         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
5315
5316         es2::Context *context = es2::getContext();
5317
5318         if(context)
5319         {
5320                 es2::Texture *texture;
5321
5322                 GLint clientVersion = context->getClientVersion();
5323
5324                 switch(target)
5325                 {
5326                 case GL_TEXTURE_2D:
5327                         texture = context->getTexture2D();
5328                         break;
5329                 case GL_TEXTURE_2D_ARRAY:
5330                         if(clientVersion < 3)
5331                         {
5332                                 return error(GL_INVALID_ENUM);
5333                         }
5334                         else
5335                         {
5336                                 texture = context->getTexture2DArray();
5337                         }
5338                         break;
5339                 case GL_TEXTURE_3D_OES:
5340                         texture = context->getTexture3D();
5341                         break;
5342                 case GL_TEXTURE_CUBE_MAP:
5343                         texture = context->getTextureCubeMap();
5344                         break;
5345                 case GL_TEXTURE_EXTERNAL_OES:
5346                         texture = context->getTextureExternal();
5347                         break;
5348                 default:
5349                         return error(GL_INVALID_ENUM);
5350                 }
5351
5352                 switch(pname)
5353                 {
5354                 case GL_TEXTURE_WRAP_S:
5355                         if(!texture->setWrapS((GLenum)param))
5356                         {
5357                                 return error(GL_INVALID_ENUM);
5358                         }
5359                         break;
5360                 case GL_TEXTURE_WRAP_T:
5361                         if(!texture->setWrapT((GLenum)param))
5362                         {
5363                                 return error(GL_INVALID_ENUM);
5364                         }
5365                         break;
5366                 case GL_TEXTURE_WRAP_R_OES:
5367                         if(!texture->setWrapR((GLenum)param))
5368                         {
5369                                 return error(GL_INVALID_ENUM);
5370                         }
5371                         break;
5372                 case GL_TEXTURE_MIN_FILTER:
5373                         if(!texture->setMinFilter((GLenum)param))
5374                         {
5375                                 return error(GL_INVALID_ENUM);
5376                         }
5377                         break;
5378                 case GL_TEXTURE_MAG_FILTER:
5379                         if(!texture->setMagFilter((GLenum)param))
5380                         {
5381                                 return error(GL_INVALID_ENUM);
5382                         }
5383                         break;
5384                 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5385                         if(!texture->setMaxAnisotropy((GLfloat)param))
5386                         {
5387                                 return error(GL_INVALID_VALUE);
5388                         }
5389                         break;
5390                 case GL_TEXTURE_BASE_LEVEL:
5391                         if(clientVersion < 3 || !texture->setBaseLevel(param))
5392                         {
5393                                 return error(GL_INVALID_VALUE);
5394                         }
5395                         break;
5396                 case GL_TEXTURE_COMPARE_FUNC:
5397                         if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5398                         {
5399                                 return error(GL_INVALID_VALUE);
5400                         }
5401                         break;
5402                 case GL_TEXTURE_COMPARE_MODE:
5403                         if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5404                         {
5405                                 return error(GL_INVALID_VALUE);
5406                         }
5407                         break;
5408                 case GL_TEXTURE_MAX_LEVEL:
5409                         if(clientVersion < 3 || !texture->setMaxLevel(param))
5410                         {
5411                                 return error(GL_INVALID_VALUE);
5412                         }
5413                         break;
5414                 case GL_TEXTURE_MAX_LOD:
5415                         if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5416                         {
5417                                 return error(GL_INVALID_VALUE);
5418                         }
5419                         break;
5420                 case GL_TEXTURE_MIN_LOD:
5421                         if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5422                         {
5423                                 return error(GL_INVALID_VALUE);
5424                         }
5425                         break;
5426                 case GL_TEXTURE_SWIZZLE_R:
5427                         if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5428                         {
5429                                 return error(GL_INVALID_VALUE);
5430                         }
5431                         break;
5432                 case GL_TEXTURE_SWIZZLE_G:
5433                         if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5434                         {
5435                                 return error(GL_INVALID_VALUE);
5436                         }
5437                         break;
5438                 case GL_TEXTURE_SWIZZLE_B:
5439                         if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5440                         {
5441                                 return error(GL_INVALID_VALUE);
5442                         }
5443                         break;
5444                 case GL_TEXTURE_SWIZZLE_A:
5445                         if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5446                         {
5447                                 return error(GL_INVALID_VALUE);
5448                         }
5449                         break;
5450                 default:
5451                         return error(GL_INVALID_ENUM);
5452                 }
5453         }
5454 }
5455
5456 void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
5457 {
5458         glTexParameteri(target, pname, *params);
5459 }
5460
5461 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5462                    GLenum format, GLenum type, const GLvoid* data)
5463 {
5464         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5465               "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
5466               "const GLvoid* data = %p)",
5467               target, level, xoffset, yoffset, width, height, format, type, data);
5468
5469         if(!es2::IsTextureTarget(target))
5470         {
5471                 return error(GL_INVALID_ENUM);
5472         }
5473
5474         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5475         {
5476                 return error(GL_INVALID_VALUE);
5477         }
5478
5479         if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5480         {
5481                 return error(GL_INVALID_VALUE);
5482         }
5483
5484         if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5485         {
5486                 return error(GL_INVALID_VALUE);
5487         }
5488
5489         if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
5490         {
5491                 return;
5492         }
5493
5494         if(width == 0 || height == 0)
5495         {
5496                 return;
5497         }
5498
5499         es2::Context *context = es2::getContext();
5500
5501         if(context)
5502         {
5503                 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
5504
5505                 GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
5506                 if(validationError != GL_NONE)
5507                 {
5508                         return error(validationError);
5509                 }
5510
5511                 if(target == GL_TEXTURE_2D)
5512                 {
5513                         es2::Texture2D *texture = context->getTexture2D();
5514
5515                         validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
5516
5517                         if(validationError == GL_NONE)
5518                         {
5519                                 texture->subImage(context, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
5520                         }
5521                         else
5522                         {
5523                                 return error(validationError);
5524                         }
5525                 }
5526                 else if(es2::IsCubemapTextureTarget(target))
5527                 {
5528                         es2::TextureCubeMap *texture = context->getTextureCubeMap();
5529
5530                         validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
5531
5532                         if(validationError == GL_NONE)
5533                         {
5534                                 texture->subImage(context, target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
5535                         }
5536                         else
5537                         {
5538                                 return error(validationError);
5539                         }
5540                 }
5541                 else UNREACHABLE(target);
5542         }
5543 }
5544
5545 void Uniform1f(GLint location, GLfloat x)
5546 {
5547         glUniform1fv(location, 1, &x);
5548 }
5549
5550 void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
5551 {
5552         TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5553
5554         if(count < 0)
5555         {
5556                 return error(GL_INVALID_VALUE);
5557         }
5558
5559         if(location == -1)
5560         {
5561                 return;
5562         }
5563
5564         es2::Context *context = es2::getContext();
5565
5566         if(context)
5567         {
5568                 es2::Program *program = context->getCurrentProgram();
5569
5570                 if(!program)
5571                 {
5572                         return error(GL_INVALID_OPERATION);
5573                 }
5574
5575                 if(!program->setUniform1fv(location, count, v))
5576                 {
5577                         return error(GL_INVALID_OPERATION);
5578                 }
5579         }
5580 }
5581
5582 void Uniform1i(GLint location, GLint x)
5583 {
5584         glUniform1iv(location, 1, &x);
5585 }
5586
5587 void Uniform1iv(GLint location, GLsizei count, const GLint* v)
5588 {
5589         TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5590
5591         if(count < 0)
5592         {
5593                 return error(GL_INVALID_VALUE);
5594         }
5595
5596         if(location == -1)
5597         {
5598                 return;
5599         }
5600
5601         es2::Context *context = es2::getContext();
5602
5603         if(context)
5604         {
5605                 es2::Program *program = context->getCurrentProgram();
5606
5607                 if(!program)
5608                 {
5609                         return error(GL_INVALID_OPERATION);
5610                 }
5611
5612                 if(!program->setUniform1iv(location, count, v))
5613                 {
5614                         return error(GL_INVALID_OPERATION);
5615                 }
5616         }
5617 }
5618
5619 void Uniform2f(GLint location, GLfloat x, GLfloat y)
5620 {
5621         GLfloat xy[2] = {x, y};
5622
5623         glUniform2fv(location, 1, (GLfloat*)&xy);
5624 }
5625
5626 void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
5627 {
5628         TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5629
5630         if(count < 0)
5631         {
5632                 return error(GL_INVALID_VALUE);
5633         }
5634
5635         if(location == -1)
5636         {
5637                 return;
5638         }
5639
5640         es2::Context *context = es2::getContext();
5641
5642         if(context)
5643         {
5644                 es2::Program *program = context->getCurrentProgram();
5645
5646                 if(!program)
5647                 {
5648                         return error(GL_INVALID_OPERATION);
5649                 }
5650
5651                 if(!program->setUniform2fv(location, count, v))
5652                 {
5653                         return error(GL_INVALID_OPERATION);
5654                 }
5655         }
5656 }
5657
5658 void Uniform2i(GLint location, GLint x, GLint y)
5659 {
5660         GLint xy[4] = {x, y};
5661
5662         glUniform2iv(location, 1, (GLint*)&xy);
5663 }
5664
5665 void Uniform2iv(GLint location, GLsizei count, const GLint* v)
5666 {
5667         TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5668
5669         if(count < 0)
5670         {
5671                 return error(GL_INVALID_VALUE);
5672         }
5673
5674         if(location == -1)
5675         {
5676                 return;
5677         }
5678
5679         es2::Context *context = es2::getContext();
5680
5681         if(context)
5682         {
5683                 es2::Program *program = context->getCurrentProgram();
5684
5685                 if(!program)
5686                 {
5687                         return error(GL_INVALID_OPERATION);
5688                 }
5689
5690                 if(!program->setUniform2iv(location, count, v))
5691                 {
5692                         return error(GL_INVALID_OPERATION);
5693                 }
5694         }
5695 }
5696
5697 void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5698 {
5699         GLfloat xyz[3] = {x, y, z};
5700
5701         glUniform3fv(location, 1, (GLfloat*)&xyz);
5702 }
5703
5704 void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
5705 {
5706         TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5707
5708         if(count < 0)
5709         {
5710                 return error(GL_INVALID_VALUE);
5711         }
5712
5713         if(location == -1)
5714         {
5715                 return;
5716         }
5717
5718         es2::Context *context = es2::getContext();
5719
5720         if(context)
5721         {
5722                 es2::Program *program = context->getCurrentProgram();
5723
5724                 if(!program)
5725                 {
5726                         return error(GL_INVALID_OPERATION);
5727                 }
5728
5729                 if(!program->setUniform3fv(location, count, v))
5730                 {
5731                         return error(GL_INVALID_OPERATION);
5732                 }
5733         }
5734 }
5735
5736 void Uniform3i(GLint location, GLint x, GLint y, GLint z)
5737 {
5738         GLint xyz[3] = {x, y, z};
5739
5740         glUniform3iv(location, 1, (GLint*)&xyz);
5741 }
5742
5743 void Uniform3iv(GLint location, GLsizei count, const GLint* v)
5744 {
5745         TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5746
5747         if(count < 0)
5748         {
5749                 return error(GL_INVALID_VALUE);
5750         }
5751
5752         if(location == -1)
5753         {
5754                 return;
5755         }
5756
5757         es2::Context *context = es2::getContext();
5758
5759         if(context)
5760         {
5761                 es2::Program *program = context->getCurrentProgram();
5762
5763                 if(!program)
5764                 {
5765                         return error(GL_INVALID_OPERATION);
5766                 }
5767
5768                 if(!program->setUniform3iv(location, count, v))
5769                 {
5770                         return error(GL_INVALID_OPERATION);
5771                 }
5772         }
5773 }
5774
5775 void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5776 {
5777         GLfloat xyzw[4] = {x, y, z, w};
5778
5779         glUniform4fv(location, 1, (GLfloat*)&xyzw);
5780 }
5781
5782 void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
5783 {
5784         TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5785
5786         if(count < 0)
5787         {
5788                 return error(GL_INVALID_VALUE);
5789         }
5790
5791         if(location == -1)
5792         {
5793                 return;
5794         }
5795
5796         es2::Context *context = es2::getContext();
5797
5798         if(context)
5799         {
5800                 es2::Program *program = context->getCurrentProgram();
5801
5802                 if(!program)
5803                 {
5804                         return error(GL_INVALID_OPERATION);
5805                 }
5806
5807                 if(!program->setUniform4fv(location, count, v))
5808                 {
5809                         return error(GL_INVALID_OPERATION);
5810                 }
5811         }
5812 }
5813
5814 void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5815 {
5816         GLint xyzw[4] = {x, y, z, w};
5817
5818         glUniform4iv(location, 1, (GLint*)&xyzw);
5819 }
5820
5821 void Uniform4iv(GLint location, GLsizei count, const GLint* v)
5822 {
5823         TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5824
5825         if(count < 0)
5826         {
5827                 return error(GL_INVALID_VALUE);
5828         }
5829
5830         if(location == -1)
5831         {
5832                 return;
5833         }
5834
5835         es2::Context *context = es2::getContext();
5836
5837         if(context)
5838         {
5839                 es2::Program *program = context->getCurrentProgram();
5840
5841                 if(!program)
5842                 {
5843                         return error(GL_INVALID_OPERATION);
5844                 }
5845
5846                 if(!program->setUniform4iv(location, count, v))
5847                 {
5848                         return error(GL_INVALID_OPERATION);
5849                 }
5850         }
5851 }
5852
5853 void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5854 {
5855         TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5856               location, count, transpose, value);
5857
5858         if(count < 0)
5859         {
5860                 return error(GL_INVALID_VALUE);
5861         }
5862
5863         if(location == -1)
5864         {
5865                 return;
5866         }
5867
5868         es2::Context *context = es2::getContext();
5869
5870         if(context)
5871         {
5872                 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5873                 {
5874                         return error(GL_INVALID_VALUE);
5875                 }
5876
5877                 es2::Program *program = context->getCurrentProgram();
5878
5879                 if(!program)
5880                 {
5881                         return error(GL_INVALID_OPERATION);
5882                 }
5883
5884                 if(!program->setUniformMatrix2fv(location, count, transpose, value))
5885                 {
5886                         return error(GL_INVALID_OPERATION);
5887                 }
5888         }
5889 }
5890
5891 void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5892 {
5893         TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5894               location, count, transpose, value);
5895
5896         if(count < 0)
5897         {
5898                 return error(GL_INVALID_VALUE);
5899         }
5900
5901         if(location == -1)
5902         {
5903                 return;
5904         }
5905
5906         es2::Context *context = es2::getContext();
5907
5908         if(context)
5909         {
5910                 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5911                 {
5912                         return error(GL_INVALID_VALUE);
5913                 }
5914
5915                 es2::Program *program = context->getCurrentProgram();
5916
5917                 if(!program)
5918                 {
5919                         return error(GL_INVALID_OPERATION);
5920                 }
5921
5922                 if(!program->setUniformMatrix3fv(location, count, transpose, value))
5923                 {
5924                         return error(GL_INVALID_OPERATION);
5925                 }
5926         }
5927 }
5928
5929 void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5930 {
5931         TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5932               location, count, transpose, value);
5933
5934         if(count < 0)
5935         {
5936                 return error(GL_INVALID_VALUE);
5937         }
5938
5939         if(location == -1)
5940         {
5941                 return;
5942         }
5943
5944         es2::Context *context = es2::getContext();
5945
5946         if(context)
5947         {
5948                 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5949                 {
5950                         return error(GL_INVALID_VALUE);
5951                 }
5952
5953                 es2::Program *program = context->getCurrentProgram();
5954
5955                 if(!program)
5956                 {
5957                         return error(GL_INVALID_OPERATION);
5958                 }
5959
5960                 if(!program->setUniformMatrix4fv(location, count, transpose, value))
5961                 {
5962                         return error(GL_INVALID_OPERATION);
5963                 }
5964         }
5965 }
5966
5967 void UseProgram(GLuint program)
5968 {
5969         TRACE("(GLuint program = %d)", program);
5970
5971         es2::Context *context = es2::getContext();
5972
5973         if(context)
5974         {
5975                 es2::Program *programObject = context->getProgram(program);
5976
5977                 if(!programObject && program != 0)
5978                 {
5979                         if(context->getShader(program))
5980                         {
5981                                 return error(GL_INVALID_OPERATION);
5982                         }
5983                         else
5984                         {
5985                                 return error(GL_INVALID_VALUE);
5986                         }
5987                 }
5988
5989                 if(program != 0 && !programObject->isLinked())
5990                 {
5991                         return error(GL_INVALID_OPERATION);
5992                 }
5993
5994                 context->useProgram(program);
5995         }
5996 }
5997
5998 void ValidateProgram(GLuint program)
5999 {
6000         TRACE("(GLuint program = %d)", program);
6001
6002         es2::Context *context = es2::getContext();
6003
6004         if(context)
6005         {
6006                 es2::Program *programObject = context->getProgram(program);
6007
6008                 if(!programObject)
6009                 {
6010                         if(context->getShader(program))
6011                         {
6012                                 return error(GL_INVALID_OPERATION);
6013                         }
6014                         else
6015                         {
6016                                 return error(GL_INVALID_VALUE);
6017                         }
6018                 }
6019
6020                 programObject->validate(context->getDevice());
6021         }
6022 }
6023
6024 void VertexAttrib1f(GLuint index, GLfloat x)
6025 {
6026         TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
6027
6028         if(index >= es2::MAX_VERTEX_ATTRIBS)
6029         {
6030                 return error(GL_INVALID_VALUE);
6031         }
6032
6033         es2::Context *context = es2::getContext();
6034
6035         if(context)
6036         {
6037                 GLfloat vals[4] = { x, 0, 0, 1 };
6038                 context->setVertexAttrib(index, vals);
6039         }
6040 }
6041
6042 void VertexAttrib1fv(GLuint index, const GLfloat* values)
6043 {
6044         TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6045
6046         if(index >= es2::MAX_VERTEX_ATTRIBS)
6047         {
6048                 return error(GL_INVALID_VALUE);
6049         }
6050
6051         es2::Context *context = es2::getContext();
6052
6053         if(context)
6054         {
6055                 GLfloat vals[4] = { values[0], 0, 0, 1 };
6056                 context->setVertexAttrib(index, vals);
6057         }
6058 }
6059
6060 void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6061 {
6062         TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
6063
6064         if(index >= es2::MAX_VERTEX_ATTRIBS)
6065         {
6066                 return error(GL_INVALID_VALUE);
6067         }
6068
6069         es2::Context *context = es2::getContext();
6070
6071         if(context)
6072         {
6073                 GLfloat vals[4] = { x, y, 0, 1 };
6074                 context->setVertexAttrib(index, vals);
6075         }
6076 }
6077
6078 void VertexAttrib2fv(GLuint index, const GLfloat* values)
6079 {
6080         TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6081
6082         if(index >= es2::MAX_VERTEX_ATTRIBS)
6083         {
6084                 return error(GL_INVALID_VALUE);
6085         }
6086
6087         es2::Context *context = es2::getContext();
6088
6089         if(context)
6090         {
6091                 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6092                 context->setVertexAttrib(index, vals);
6093         }
6094 }
6095
6096 void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6097 {
6098         TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
6099
6100         if(index >= es2::MAX_VERTEX_ATTRIBS)
6101         {
6102                 return error(GL_INVALID_VALUE);
6103         }
6104
6105         es2::Context *context = es2::getContext();
6106
6107         if(context)
6108         {
6109                 GLfloat vals[4] = { x, y, z, 1 };
6110                 context->setVertexAttrib(index, vals);
6111         }
6112 }
6113
6114 void VertexAttrib3fv(GLuint index, const GLfloat* values)
6115 {
6116         TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6117
6118         if(index >= es2::MAX_VERTEX_ATTRIBS)
6119         {
6120                 return error(GL_INVALID_VALUE);
6121         }
6122
6123         es2::Context *context = es2::getContext();
6124
6125         if(context)
6126         {
6127                 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6128                 context->setVertexAttrib(index, vals);
6129         }
6130 }
6131
6132 void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6133 {
6134         TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
6135
6136         if(index >= es2::MAX_VERTEX_ATTRIBS)
6137         {
6138                 return error(GL_INVALID_VALUE);
6139         }
6140
6141         es2::Context *context = es2::getContext();
6142
6143         if(context)
6144         {
6145                 GLfloat vals[4] = { x, y, z, w };
6146                 context->setVertexAttrib(index, vals);
6147         }
6148 }
6149
6150 void VertexAttrib4fv(GLuint index, const GLfloat* values)
6151 {
6152         TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6153
6154         if(index >= es2::MAX_VERTEX_ATTRIBS)
6155         {
6156                 return error(GL_INVALID_VALUE);
6157         }
6158
6159         es2::Context *context = es2::getContext();
6160
6161         if(context)
6162         {
6163                 context->setVertexAttrib(index, values);
6164         }
6165 }
6166
6167 void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
6168 {
6169         TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
6170               "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
6171               index, size, type, normalized, stride, ptr);
6172
6173         if(index >= es2::MAX_VERTEX_ATTRIBS)
6174         {
6175                 return error(GL_INVALID_VALUE);
6176         }
6177
6178         if(size < 1 || size > 4)
6179         {
6180                 return error(GL_INVALID_VALUE);
6181         }
6182
6183         GLint clientVersion = egl::getClientVersion();
6184
6185         switch(type)
6186         {
6187         case GL_BYTE:
6188         case GL_UNSIGNED_BYTE:
6189         case GL_SHORT:
6190         case GL_UNSIGNED_SHORT:
6191         case GL_FIXED:
6192         case GL_FLOAT:
6193         case GL_HALF_FLOAT_OES:   // GL_OES_vertex_half_float
6194                 break;
6195         case GL_INT_2_10_10_10_REV:
6196         case GL_UNSIGNED_INT_2_10_10_10_REV:
6197                 if(clientVersion >= 3)
6198                 {
6199                         if(size != 4)
6200                         {
6201                                 return error(GL_INVALID_OPERATION);
6202                         }
6203                         break;
6204                 }
6205                 else return error(GL_INVALID_ENUM);
6206         case GL_INT:
6207         case GL_UNSIGNED_INT:
6208         case GL_HALF_FLOAT:
6209                 if(clientVersion >= 3)
6210                 {
6211                         break;
6212                 }
6213                 else return error(GL_INVALID_ENUM);
6214         default:
6215                 return error(GL_INVALID_ENUM);
6216         }
6217
6218         if(stride < 0)
6219         {
6220                 return error(GL_INVALID_VALUE);
6221         }
6222
6223         es2::Context *context = es2::getContext();
6224
6225         if(context)
6226         {
6227                 es2::VertexArray* vertexArray = context->getCurrentVertexArray();
6228                 if((context->getArrayBufferName() == 0) && vertexArray && (vertexArray->name != 0) && ptr)
6229                 {
6230                         // GL_INVALID_OPERATION is generated if a non-zero vertex array object is bound, zero is bound
6231                         // to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.
6232                         return error(GL_INVALID_OPERATION);
6233                 }
6234
6235                 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6236         }
6237 }
6238
6239 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
6240 {
6241         TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
6242
6243         if(width < 0 || height < 0)
6244         {
6245                 return error(GL_INVALID_VALUE);
6246         }
6247
6248         es2::Context *context = es2::getContext();
6249
6250         if(context)
6251         {
6252                 context->setViewportParams(x, y, width, height);
6253         }
6254 }
6255
6256 static void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter, bool allowPartialDepthStencilBlit)
6257 {
6258         TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6259               "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6260               "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6261               srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6262
6263         switch(filter)
6264         {
6265         case GL_NEAREST:
6266                 break;
6267         default:
6268                 return error(GL_INVALID_ENUM);
6269         }
6270
6271         if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6272         {
6273                 return error(GL_INVALID_VALUE);
6274         }
6275
6276         es2::Context *context = es2::getContext();
6277
6278         if(context)
6279         {
6280                 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
6281                 {
6282                         ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6283                         return error(GL_INVALID_OPERATION);
6284                 }
6285
6286                 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, false, allowPartialDepthStencilBlit);
6287         }
6288 }
6289
6290 void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
6291 {
6292         BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, true);
6293 }
6294
6295 void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6296                           GLbitfield mask, GLenum filter)
6297 {
6298         if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6299         {
6300                 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6301                 return error(GL_INVALID_OPERATION);
6302         }
6303
6304         BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, false);
6305 }
6306
6307 void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6308                    GLint border, GLenum format, GLenum type, const GLvoid* data)
6309 {
6310         TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6311               "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
6312               "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
6313               target, level, internalformat, width, height, depth, border, format, type, data);
6314
6315         switch(target)
6316         {
6317         case GL_TEXTURE_3D_OES:
6318                 switch(format)
6319                 {
6320                 case GL_DEPTH_COMPONENT:
6321                 case GL_DEPTH_STENCIL_OES:
6322                         return error(GL_INVALID_OPERATION);
6323                 default:
6324                         break;
6325                 }
6326                 break;
6327         default:
6328                 return error(GL_INVALID_ENUM);
6329         }
6330
6331         if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
6332         {
6333                 return;
6334         }
6335
6336         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6337         {
6338                 return error(GL_INVALID_VALUE);
6339         }
6340
6341         const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6342         if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6343         {
6344                 return error(GL_INVALID_VALUE);
6345         }
6346
6347         if(border != 0)
6348         {
6349                 return error(GL_INVALID_VALUE);
6350         }
6351
6352         es2::Context *context = es2::getContext();
6353
6354         if(context)
6355         {
6356                 es2::Texture3D *texture = context->getTexture3D();
6357
6358                 if(!texture)
6359                 {
6360                         return error(GL_INVALID_OPERATION);
6361                 }
6362
6363                 GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
6364                 GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
6365                 if(validationError != GL_NONE)
6366                 {
6367                         return error(validationError);
6368                 }
6369
6370                 texture->setImage(context, level, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
6371         }
6372 }
6373
6374 void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data)
6375 {
6376         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6377               "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6378               "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
6379               target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
6380
6381         switch(target)
6382         {
6383         case GL_TEXTURE_3D_OES:
6384                 break;
6385         default:
6386                 return error(GL_INVALID_ENUM);
6387         }
6388
6389         if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
6390         {
6391                 return;
6392         }
6393
6394         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6395         {
6396                 return error(GL_INVALID_VALUE);
6397         }
6398
6399         if((width < 0) || (height < 0) || (depth < 0))
6400         {
6401                 return error(GL_INVALID_VALUE);
6402         }
6403
6404         es2::Context *context = es2::getContext();
6405
6406         if(context)
6407         {
6408                 es2::Texture3D *texture = context->getTexture3D();
6409
6410                 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
6411
6412                 GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
6413
6414                 if(validationError == GL_NONE)
6415                 {
6416                         validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
6417                 }
6418
6419                 if(validationError == GL_NONE)
6420                 {
6421                         texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
6422                 }
6423                 else
6424                 {
6425                         return error(validationError);
6426                 }
6427         }
6428 }
6429
6430 void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
6431 {
6432         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6433               "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
6434               target, level, xoffset, yoffset, zoffset, x, y, width, height);
6435
6436         switch(target)
6437         {
6438         case GL_TEXTURE_3D_OES:
6439                 break;
6440         default:
6441                 return error(GL_INVALID_ENUM);
6442         }
6443
6444         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6445         {
6446                 return error(GL_INVALID_VALUE);
6447         }
6448
6449         es2::Context *context = es2::getContext();
6450
6451         if(context)
6452         {
6453                 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6454
6455                 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
6456                 {
6457                         return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6458                 }
6459
6460                 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
6461
6462                 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
6463                 {
6464                         return error(GL_INVALID_OPERATION);
6465                 }
6466
6467                 es2::Texture3D *texture = context->getTexture3D();
6468
6469                 GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
6470
6471                 if(validationError != GL_NONE)
6472                 {
6473                         return error(validationError);
6474                 }
6475
6476                 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
6477         }
6478 }
6479
6480 void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
6481 {
6482         TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
6483               "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
6484               target, level, internalformat, width, height, depth, border, imageSize, data);
6485
6486         switch(target)
6487         {
6488         case GL_TEXTURE_3D_OES:
6489                 break;
6490         default:
6491                 return error(GL_INVALID_ENUM);
6492         }
6493
6494         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6495         {
6496                 return error(GL_INVALID_VALUE);
6497         }
6498
6499         const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6500         if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6501         {
6502                 return error(GL_INVALID_VALUE);
6503         }
6504
6505         switch(internalformat)
6506         {
6507         case GL_DEPTH_COMPONENT:
6508         case GL_DEPTH_COMPONENT16:
6509         case GL_DEPTH_COMPONENT32_OES:
6510         case GL_DEPTH_STENCIL_OES:
6511         case GL_DEPTH24_STENCIL8_OES:
6512                 return error(GL_INVALID_OPERATION);
6513         default:
6514                 {
6515                         GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
6516                         if(validationError != GL_NONE)
6517                         {
6518                                 return error(validationError);
6519                         }
6520                 }
6521         }
6522
6523         if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
6524         {
6525                 return error(GL_INVALID_VALUE);
6526         }
6527
6528         es2::Context *context = es2::getContext();
6529
6530         if(context)
6531         {
6532                 es2::Texture3D *texture = context->getTexture3D();
6533
6534                 if(!texture)
6535                 {
6536                         return error(GL_INVALID_OPERATION);
6537                 }
6538
6539                 GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
6540
6541                 if(validationError != GL_NONE)
6542                 {
6543                         return error(validationError);
6544                 }
6545
6546                 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
6547         }
6548 }
6549
6550 void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
6551 {
6552         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6553               "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6554               "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
6555               target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6556
6557         switch(target)
6558         {
6559         case GL_TEXTURE_3D_OES:
6560                 break;
6561         default:
6562                 return error(GL_INVALID_ENUM);
6563         }
6564
6565         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6566         {
6567                 return error(GL_INVALID_VALUE);
6568         }
6569
6570         if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6571         {
6572                 return error(GL_INVALID_VALUE);
6573         }
6574
6575         GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
6576         if(validationError != GL_NONE)
6577         {
6578                 return error(validationError);
6579         }
6580
6581         if(width == 0 || height == 0 || depth == 0)
6582         {
6583                 return;
6584         }
6585
6586         es2::Context *context = es2::getContext();
6587
6588         if(context)
6589         {
6590                 es2::Texture3D *texture = context->getTexture3D();
6591
6592                 if(!texture)
6593                 {
6594                         return error(GL_INVALID_OPERATION);
6595                 }
6596
6597                 GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
6598
6599                 if(validationError != GL_NONE)
6600                 {
6601                         return error(validationError);
6602                 }
6603
6604                 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6605         }
6606 }
6607
6608 void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
6609 {
6610         TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6611               "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6612
6613         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
6614         {
6615                 return error(GL_INVALID_ENUM);
6616         }
6617
6618         es2::Context *context = es2::getContext();
6619
6620         if(context)
6621         {
6622                 if(texture == 0)
6623                 {
6624                         textarget = GL_NONE;
6625                 }
6626                 else
6627                 {
6628                         es2::Texture *tex = context->getTexture(texture);
6629
6630                         if(!tex)
6631                         {
6632                                 return error(GL_INVALID_OPERATION);
6633                         }
6634
6635                         if(tex->isCompressed(textarget, level))
6636                         {
6637                                 return error(GL_INVALID_OPERATION);
6638                         }
6639
6640                         switch(textarget)
6641                         {
6642                         case GL_TEXTURE_3D_OES:
6643                                 if(tex->getTarget() != GL_TEXTURE_3D_OES)
6644                                 {
6645                                         return error(GL_INVALID_OPERATION);
6646                                 }
6647                                 break;
6648                         default:
6649                                 return error(GL_INVALID_ENUM);
6650                         }
6651
6652                         if(level != 0)
6653                         {
6654                                 return error(GL_INVALID_VALUE);
6655                         }
6656                 }
6657
6658                 es2::Framebuffer *framebuffer = nullptr;
6659                 GLuint framebufferName = 0;
6660                 if(target == GL_READ_FRAMEBUFFER_ANGLE)
6661                 {
6662                         framebuffer = context->getReadFramebuffer();
6663                         framebufferName = context->getReadFramebufferName();
6664                 }
6665                 else
6666                 {
6667                         framebuffer = context->getDrawFramebuffer();
6668                         framebufferName = context->getDrawFramebufferName();
6669                 }
6670
6671                 if(framebufferName == 0 || !framebuffer)
6672                 {
6673                         return error(GL_INVALID_OPERATION);
6674                 }
6675
6676                 GLint clientVersion = context->getClientVersion();
6677
6678                 switch(attachment)
6679                 {
6680                 case GL_COLOR_ATTACHMENT1:
6681                 case GL_COLOR_ATTACHMENT2:
6682                 case GL_COLOR_ATTACHMENT3:
6683                 case GL_COLOR_ATTACHMENT4:
6684                 case GL_COLOR_ATTACHMENT5:
6685                 case GL_COLOR_ATTACHMENT6:
6686                 case GL_COLOR_ATTACHMENT7:
6687                 case GL_COLOR_ATTACHMENT8:
6688                 case GL_COLOR_ATTACHMENT9:
6689                 case GL_COLOR_ATTACHMENT10:
6690                 case GL_COLOR_ATTACHMENT11:
6691                 case GL_COLOR_ATTACHMENT12:
6692                 case GL_COLOR_ATTACHMENT13:
6693                 case GL_COLOR_ATTACHMENT14:
6694                 case GL_COLOR_ATTACHMENT15:
6695                 case GL_COLOR_ATTACHMENT16:
6696                 case GL_COLOR_ATTACHMENT17:
6697                 case GL_COLOR_ATTACHMENT18:
6698                 case GL_COLOR_ATTACHMENT19:
6699                 case GL_COLOR_ATTACHMENT20:
6700                 case GL_COLOR_ATTACHMENT21:
6701                 case GL_COLOR_ATTACHMENT22:
6702                 case GL_COLOR_ATTACHMENT23:
6703                 case GL_COLOR_ATTACHMENT24:
6704                 case GL_COLOR_ATTACHMENT25:
6705                 case GL_COLOR_ATTACHMENT26:
6706                 case GL_COLOR_ATTACHMENT27:
6707                 case GL_COLOR_ATTACHMENT28:
6708                 case GL_COLOR_ATTACHMENT29:
6709                 case GL_COLOR_ATTACHMENT30:
6710                 case GL_COLOR_ATTACHMENT31:
6711                         if(clientVersion < 3)
6712                         {
6713                                 return error(GL_INVALID_ENUM);
6714                         }
6715                         // fall through
6716                 case GL_COLOR_ATTACHMENT0:
6717                         if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
6718                         {
6719                                 return error(GL_INVALID_ENUM);
6720                         }
6721                         framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
6722                         break;
6723                 case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
6724                 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6725                 default:
6726                         return error(GL_INVALID_ENUM);
6727                 }
6728         }
6729 }
6730
6731 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
6732 {
6733         if(egl::getClientVersion() == 1)
6734         {
6735                 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
6736         }
6737
6738         TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6739
6740         switch(target)
6741         {
6742         case GL_TEXTURE_2D:
6743         case GL_TEXTURE_EXTERNAL_OES:
6744                 break;
6745         default:
6746                 return error(GL_INVALID_ENUM);
6747         }
6748
6749         es2::Context *context = es2::getContext();
6750
6751         if(context)
6752         {
6753                 es2::Texture2D *texture = nullptr;
6754
6755                 switch(target)
6756                 {
6757                 case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;
6758                 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
6759                 default:                      UNREACHABLE(target);
6760                 }
6761
6762                 if(!texture)
6763                 {
6764                         return error(GL_INVALID_OPERATION);
6765                 }
6766
6767                 egl::Image *eglImage = context->getSharedImage(image);
6768
6769                 if(!eglImage)
6770                 {
6771                         return error(GL_INVALID_OPERATION);
6772                 }
6773
6774                 texture->setSharedImage(eglImage);
6775         }
6776 }
6777
6778 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
6779 {
6780         TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6781
6782         UNIMPLEMENTED();
6783 }
6784
6785 GLboolean IsRenderbufferOES(GLuint renderbuffer)
6786 {
6787         return IsRenderbuffer(renderbuffer);
6788 }
6789
6790 void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
6791 {
6792         BindRenderbuffer(target, renderbuffer);
6793 }
6794
6795 void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
6796 {
6797         DeleteRenderbuffers(n, renderbuffers);
6798 }
6799
6800 void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
6801 {
6802         GenRenderbuffers(n, renderbuffers);
6803 }
6804
6805 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
6806 {
6807         RenderbufferStorage(target, internalformat, width, height);
6808 }
6809
6810 void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
6811 {
6812         GetRenderbufferParameteriv(target, pname, params);
6813 }
6814
6815 GLboolean IsFramebufferOES(GLuint framebuffer)
6816 {
6817         return IsFramebuffer(framebuffer);
6818 }
6819
6820 void BindFramebufferOES(GLenum target, GLuint framebuffer)
6821 {
6822         BindFramebuffer(target, framebuffer);
6823 }
6824
6825 void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
6826 {
6827         DeleteFramebuffers(n, framebuffers);
6828 }
6829
6830 void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
6831 {
6832         GenFramebuffers(n, framebuffers);
6833 }
6834
6835 GLenum CheckFramebufferStatusOES(GLenum target)
6836 {
6837         return CheckFramebufferStatus(target);
6838 }
6839
6840 void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
6841 {
6842         FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
6843 }
6844
6845 void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
6846 {
6847         FramebufferTexture2D(target, attachment, textarget, texture, level);
6848 }
6849
6850 void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
6851 {
6852         GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
6853 }
6854
6855 void GenerateMipmapOES(GLenum target)
6856 {
6857         GenerateMipmap(target);
6858 }
6859
6860 void DrawBuffersEXT(GLsizei n, const GLenum *bufs)
6861 {
6862         TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);
6863
6864         if(n < 0 || n > MAX_DRAW_BUFFERS)
6865         {
6866                 return error(GL_INVALID_VALUE);
6867         }
6868
6869         es2::Context *context = es2::getContext();
6870
6871         if(context)
6872         {
6873                 GLuint drawFramebufferName = context->getDrawFramebufferName();
6874
6875                 if((drawFramebufferName == 0) && (n != 1))
6876                 {
6877                         return error(GL_INVALID_OPERATION);
6878                 }
6879
6880                 for(unsigned int i = 0; i < (unsigned)n; i++)
6881                 {
6882                         switch(bufs[i])
6883                         {
6884                         case GL_BACK:
6885                                 if(drawFramebufferName != 0)
6886                                 {
6887                                         return error(GL_INVALID_OPERATION);
6888                                 }
6889                                 break;
6890                         case GL_NONE:
6891                                 break;
6892                         case GL_COLOR_ATTACHMENT0_EXT:
6893                         case GL_COLOR_ATTACHMENT1_EXT:
6894                         case GL_COLOR_ATTACHMENT2_EXT:
6895                         case GL_COLOR_ATTACHMENT3_EXT:
6896                         case GL_COLOR_ATTACHMENT4_EXT:
6897                         case GL_COLOR_ATTACHMENT5_EXT:
6898                         case GL_COLOR_ATTACHMENT6_EXT:
6899                         case GL_COLOR_ATTACHMENT7_EXT:
6900                         case GL_COLOR_ATTACHMENT8_EXT:
6901                         case GL_COLOR_ATTACHMENT9_EXT:
6902                         case GL_COLOR_ATTACHMENT10_EXT:
6903                         case GL_COLOR_ATTACHMENT11_EXT:
6904                         case GL_COLOR_ATTACHMENT12_EXT:
6905                         case GL_COLOR_ATTACHMENT13_EXT:
6906                         case GL_COLOR_ATTACHMENT14_EXT:
6907                         case GL_COLOR_ATTACHMENT15_EXT:
6908                                 {
6909                                         GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0_EXT);
6910
6911                                         if(index >= MAX_COLOR_ATTACHMENTS)
6912                                         {
6913                                                 return error(GL_INVALID_OPERATION);
6914                                         }
6915
6916                                         if(index != i)
6917                                         {
6918                                                 return error(GL_INVALID_OPERATION);
6919                                         }
6920
6921                                         if(drawFramebufferName == 0)
6922                                         {
6923                                                 return error(GL_INVALID_OPERATION);
6924                                         }
6925                                 }
6926                                 break;
6927                         default:
6928                                 return error(GL_INVALID_ENUM);
6929                         }
6930                 }
6931
6932                 context->setFramebufferDrawBuffers(n, bufs);
6933         }
6934 }
6935
6936 }
6937
6938 extern "C" NO_SANITIZE_FUNCTION __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
6939 {
6940         struct Extension
6941         {
6942                 const char *name;
6943                 __eglMustCastToProperFunctionPointerType address;
6944         };
6945
6946         static const Extension glExtensions[] =
6947         {
6948                 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6949
6950                 EXTENSION(glTexImage3DOES),
6951                 EXTENSION(glBlitFramebufferANGLE),
6952                 EXTENSION(glBlitFramebufferNV),
6953                 EXTENSION(glRenderbufferStorageMultisampleANGLE),
6954                 EXTENSION(glDeleteFencesNV),
6955                 EXTENSION(glGenFencesNV),
6956                 EXTENSION(glIsFenceNV),
6957                 EXTENSION(glTestFenceNV),
6958                 EXTENSION(glGetFenceivNV),
6959                 EXTENSION(glFinishFenceNV),
6960                 EXTENSION(glSetFenceNV),
6961                 EXTENSION(glGetGraphicsResetStatusEXT),
6962                 EXTENSION(glReadnPixelsEXT),
6963                 EXTENSION(glGetnUniformfvEXT),
6964                 EXTENSION(glGetnUniformivEXT),
6965                 EXTENSION(glGenQueriesEXT),
6966                 EXTENSION(glDeleteQueriesEXT),
6967                 EXTENSION(glIsQueryEXT),
6968                 EXTENSION(glBeginQueryEXT),
6969                 EXTENSION(glEndQueryEXT),
6970                 EXTENSION(glGetQueryivEXT),
6971                 EXTENSION(glGetQueryObjectuivEXT),
6972                 EXTENSION(glEGLImageTargetTexture2DOES),
6973                 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
6974                 EXTENSION(glDrawElementsInstancedEXT),
6975                 EXTENSION(glDrawArraysInstancedEXT),
6976                 EXTENSION(glVertexAttribDivisorEXT),
6977                 EXTENSION(glDrawArraysInstancedANGLE),
6978                 EXTENSION(glDrawElementsInstancedANGLE),
6979                 EXTENSION(glVertexAttribDivisorANGLE),
6980                 EXTENSION(glIsRenderbufferOES),
6981                 EXTENSION(glBindRenderbufferOES),
6982                 EXTENSION(glDeleteRenderbuffersOES),
6983                 EXTENSION(glGenRenderbuffersOES),
6984                 EXTENSION(glRenderbufferStorageOES),
6985                 EXTENSION(glGetRenderbufferParameterivOES),
6986                 EXTENSION(glIsFramebufferOES),
6987                 EXTENSION(glBindFramebufferOES),
6988                 EXTENSION(glDeleteFramebuffersOES),
6989                 EXTENSION(glGenFramebuffersOES),
6990                 EXTENSION(glCheckFramebufferStatusOES),
6991                 EXTENSION(glFramebufferRenderbufferOES),
6992                 EXTENSION(glFramebufferTexture2DOES),
6993                 EXTENSION(glGetFramebufferAttachmentParameterivOES),
6994                 EXTENSION(glGenerateMipmapOES),
6995                 EXTENSION(glDrawBuffersEXT),
6996
6997                 #undef EXTENSION
6998         };
6999
7000         for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
7001         {
7002                 if(strcmp(procname, glExtensions[ext].name) == 0)
7003                 {
7004                         return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
7005                 }
7006         }
7007
7008         return nullptr;
7009 }