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