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