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