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