OSDN Git Service

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