blob: 447d800b7fb444faba0e2afb86f871011511c5ca [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 {
Alexis Hetu53f48092016-06-17 14:08:06 -0400958 texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, context->getPixels(data));
Nicolas Capens0bac2852016-05-07 06:09:58 -0400959 }
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 {
Alexis Hetu53f48092016-06-17 14:08:06 -0400973 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, context->getPixels(data));
Nicolas Capens0bac2852016-05-07 06:09:58 -0400974 }
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:
Nicolas Capens505b7712016-06-14 01:08:12 -04002990 // case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: // GL_EXT_color_buffer_half_float
2991 if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
Nicolas Capens0bac2852016-05-07 06:09:58 -04002992 {
Nicolas Capens505b7712016-06-14 01:08:12 -04002993 return error(GL_INVALID_OPERATION);
Nicolas Capens0bac2852016-05-07 06:09:58 -04002994 }
Nicolas Capens505b7712016-06-14 01:08:12 -04002995
2996 *params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);
Nicolas Capens0bac2852016-05-07 06:09:58 -04002997 break;
2998 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
2999 if(clientVersion >= 3)
3000 {
3001 *params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added
3002 }
3003 else return error(GL_INVALID_ENUM);
3004 break;
3005 default:
3006 return error(GL_INVALID_ENUM);
3007 }
3008 }
3009 else
3010 {
3011 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
3012 // is NONE, then querying any other pname will generate INVALID_ENUM.
3013
3014 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
3015 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
3016 // INVALID_OPERATION for all other pnames
3017
3018 switch(pname)
3019 {
3020 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3021 *params = GL_NONE;
3022 break;
3023
3024 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3025 if(clientVersion < 3)
3026 {
3027 return error(GL_INVALID_ENUM);
3028 }
3029 *params = 0;
3030 break;
3031
3032 default:
3033 if(clientVersion < 3)
3034 {
3035 return error(GL_INVALID_ENUM);
3036 }
3037 else
3038 {
3039 return error(GL_INVALID_OPERATION);
3040 }
3041 }
3042 }
3043 }
3044}
3045
3046GLenum GetGraphicsResetStatusEXT(void)
3047{
3048 TRACE("()");
3049
3050 return GL_NO_ERROR;
3051}
3052
3053void GetIntegerv(GLenum pname, GLint* params)
3054{
3055 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
3056
3057 es2::Context *context = es2::getContext();
3058
3059 if(!context)
3060 {
3061 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
3062 #ifdef __ANDROID__
3063 ALOGI("expected_badness glGetIntegerv() called without current context.");
3064 #else
3065 ERR("glGetIntegerv() called without current context.");
3066 #endif
3067
3068 // This is not spec compliant! When there is no current GL context, functions should
3069 // have no side effects. Google Maps queries these values before creating a context,
3070 // so we need this as a bug-compatible workaround.
3071 switch(pname)
3072 {
3073 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return;
3074 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return;
3075 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
3076 case GL_STENCIL_BITS: *params = 8; return;
3077 case GL_ALIASED_LINE_WIDTH_RANGE:
3078 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
3079 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
3080 return;
3081 }
3082 }
3083
3084 if(context)
3085 {
3086 if(!(context->getIntegerv(pname, params)))
3087 {
3088 GLenum nativeType;
3089 unsigned int numParams = 0;
3090 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3091 return error(GL_INVALID_ENUM);
3092
3093 if(numParams == 0)
3094 return; // it is known that pname is valid, but there are no parameters to return
3095
3096 if(nativeType == GL_BOOL)
3097 {
3098 GLboolean *boolParams = nullptr;
3099 boolParams = new GLboolean[numParams];
3100
3101 context->getBooleanv(pname, boolParams);
3102
3103 for(unsigned int i = 0; i < numParams; ++i)
3104 {
3105 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
3106 }
3107
3108 delete [] boolParams;
3109 }
3110 else if(nativeType == GL_FLOAT)
3111 {
3112 GLfloat *floatParams = nullptr;
3113 floatParams = new GLfloat[numParams];
3114
3115 context->getFloatv(pname, floatParams);
3116
3117 for(unsigned int i = 0; i < numParams; ++i)
3118 {
3119 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3120 {
Nicolas Capens53318fa2016-04-11 17:41:39 -04003121 params[i] = convert_float_int(floatParams[i]);
Nicolas Capens0bac2852016-05-07 06:09:58 -04003122 }
3123 else
3124 {
3125 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3126 }
3127 }
3128
3129 delete [] floatParams;
3130 }
3131 }
3132 }
3133}
3134
3135void GetProgramiv(GLuint program, GLenum pname, GLint* params)
3136{
3137 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
3138
3139 es2::Context *context = es2::getContext();
3140
3141 if(context)
3142 {
3143 es2::Program *programObject = context->getProgram(program);
3144
3145 if(!programObject)
3146 {
3147 if(context->getShader(program))
3148 {
3149 return error(GL_INVALID_OPERATION);
3150 }
3151 else
3152 {
3153 return error(GL_INVALID_VALUE);
3154 }
3155 }
3156
3157 GLint clientVersion = egl::getClientVersion();
3158
3159 switch(pname)
3160 {
3161 case GL_DELETE_STATUS:
3162 *params = programObject->isFlaggedForDeletion();
3163 return;
3164 case GL_LINK_STATUS:
3165 *params = programObject->isLinked();
3166 return;
3167 case GL_VALIDATE_STATUS:
3168 *params = programObject->isValidated();
3169 return;
3170 case GL_INFO_LOG_LENGTH:
3171 *params = (GLint)programObject->getInfoLogLength();
3172 return;
3173 case GL_ATTACHED_SHADERS:
3174 *params = programObject->getAttachedShadersCount();
3175 return;
3176 case GL_ACTIVE_ATTRIBUTES:
3177 *params = (GLint)programObject->getActiveAttributeCount();
3178 return;
3179 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
3180 *params = programObject->getActiveAttributeMaxLength();
3181 return;
3182 case GL_ACTIVE_UNIFORMS:
3183 *params = (GLint)programObject->getActiveUniformCount();
3184 return;
3185 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
3186 *params = programObject->getActiveUniformMaxLength();
3187 return;
3188 case GL_ACTIVE_UNIFORM_BLOCKS:
3189 if(clientVersion >= 3)
3190 {
3191 *params = (GLint)programObject->getActiveUniformBlockCount();
3192 return;
3193 }
3194 else return error(GL_INVALID_ENUM);
3195 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
3196 if(clientVersion >= 3)
3197 {
3198 *params = programObject->getActiveUniformBlockMaxLength();
3199 return;
3200 }
3201 else return error(GL_INVALID_ENUM);
3202 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
3203 if(clientVersion >= 3)
3204 {
3205 *params = programObject->getTransformFeedbackBufferMode();
3206 return;
3207 }
3208 else return error(GL_INVALID_ENUM);
3209 case GL_TRANSFORM_FEEDBACK_VARYINGS:
3210 if(clientVersion >= 3)
3211 {
3212 *params = programObject->getTransformFeedbackVaryingCount();
3213 return;
3214 }
3215 else return error(GL_INVALID_ENUM);
3216 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
3217 if(clientVersion >= 3)
3218 {
3219 *params = programObject->getTransformFeedbackVaryingMaxLength();
3220 return;
3221 }
3222 else return error(GL_INVALID_ENUM);
3223 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
3224 if(clientVersion >= 3)
3225 {
3226 *params = programObject->getBinaryRetrievableHint();
3227 return;
3228 }
3229 else return error(GL_INVALID_ENUM);
3230 case GL_PROGRAM_BINARY_LENGTH:
3231 if(clientVersion >= 3)
3232 {
3233 *params = programObject->getBinaryLength();
3234 return;
3235 }
3236 else return error(GL_INVALID_ENUM);
3237 default:
3238 return error(GL_INVALID_ENUM);
3239 }
3240 }
3241}
3242
3243void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3244{
3245 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3246 program, bufsize, length, infolog);
3247
3248 if(bufsize < 0)
3249 {
3250 return error(GL_INVALID_VALUE);
3251 }
3252
3253 es2::Context *context = es2::getContext();
3254
3255 if(context)
3256 {
3257 es2::Program *programObject = context->getProgram(program);
3258
3259 if(!programObject)
3260 {
3261 if(context->getShader(program))
3262 {
3263 return error(GL_INVALID_OPERATION);
3264 }
3265 else
3266 {
3267 return error(GL_INVALID_VALUE);
3268 }
3269 }
3270
3271 programObject->getInfoLog(bufsize, length, infolog);
3272 }
3273}
3274
3275void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3276{
3277 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
3278
3279 switch(pname)
3280 {
3281 case GL_CURRENT_QUERY_EXT:
3282 break;
3283 default:
3284 return error(GL_INVALID_ENUM);
3285 }
3286
3287 es2::Context *context = es2::getContext();
3288
3289 if(context)
3290 {
3291 params[0] = context->getActiveQuery(target);
3292 }
3293}
3294
3295void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
3296{
3297 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
3298
3299 switch(pname)
3300 {
3301 case GL_QUERY_RESULT_EXT:
3302 case GL_QUERY_RESULT_AVAILABLE_EXT:
3303 break;
3304 default:
3305 return error(GL_INVALID_ENUM);
3306 }
3307
3308 es2::Context *context = es2::getContext();
3309
3310 if(context)
3311 {
3312 es2::Query *queryObject = context->getQuery(name);
3313
3314 if(!queryObject)
3315 {
3316 return error(GL_INVALID_OPERATION);
3317 }
3318
3319 if(context->getActiveQuery(queryObject->getType()) == name)
3320 {
3321 return error(GL_INVALID_OPERATION);
3322 }
3323
3324 switch(pname)
3325 {
3326 case GL_QUERY_RESULT_EXT:
3327 params[0] = queryObject->getResult();
3328 break;
3329 case GL_QUERY_RESULT_AVAILABLE_EXT:
3330 params[0] = queryObject->isResultAvailable();
3331 break;
3332 default:
3333 ASSERT(false);
3334 }
3335 }
3336}
3337
3338void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3339{
3340 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3341
3342 es2::Context *context = es2::getContext();
3343
3344 if(context)
3345 {
3346 if(target != GL_RENDERBUFFER)
3347 {
3348 return error(GL_INVALID_ENUM);
3349 }
3350
3351 if(context->getRenderbufferName() == 0)
3352 {
3353 return error(GL_INVALID_OPERATION);
3354 }
3355
3356 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
3357
3358 switch(pname)
3359 {
3360 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3361 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3362 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
3363 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3364 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3365 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3366 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3367 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3368 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
3369 case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break;
3370 default:
3371 return error(GL_INVALID_ENUM);
3372 }
3373 }
3374}
3375
3376void GetShaderiv(GLuint shader, GLenum pname, GLint* params)
3377{
3378 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
3379
3380 es2::Context *context = es2::getContext();
3381
3382 if(context)
3383 {
3384 es2::Shader *shaderObject = context->getShader(shader);
3385
3386 if(!shaderObject)
3387 {
3388 if(context->getProgram(shader))
3389 {
3390 return error(GL_INVALID_OPERATION);
3391 }
3392 else
3393 {
3394 return error(GL_INVALID_VALUE);
3395 }
3396 }
3397
3398 switch(pname)
3399 {
3400 case GL_SHADER_TYPE:
3401 *params = shaderObject->getType();
3402 return;
3403 case GL_DELETE_STATUS:
3404 *params = shaderObject->isFlaggedForDeletion();
3405 return;
3406 case GL_COMPILE_STATUS:
3407 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3408 return;
3409 case GL_INFO_LOG_LENGTH:
3410 *params = (GLint)shaderObject->getInfoLogLength();
3411 return;
3412 case GL_SHADER_SOURCE_LENGTH:
3413 *params = (GLint)shaderObject->getSourceLength();
3414 return;
3415 default:
3416 return error(GL_INVALID_ENUM);
3417 }
3418 }
3419}
3420
3421void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3422{
3423 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3424 shader, bufsize, length, infolog);
3425
3426 if(bufsize < 0)
3427 {
3428 return error(GL_INVALID_VALUE);
3429 }
3430
3431 es2::Context *context = es2::getContext();
3432
3433 if(context)
3434 {
3435 es2::Shader *shaderObject = context->getShader(shader);
3436
3437 if(!shaderObject)
3438 {
3439 if(context->getProgram(shader))
3440 {
3441 return error(GL_INVALID_OPERATION);
3442 }
3443 else
3444 {
3445 return error(GL_INVALID_VALUE);
3446 }
3447 }
3448
3449 shaderObject->getInfoLog(bufsize, length, infolog);
3450 }
3451}
3452
3453void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3454{
3455 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
3456 shadertype, precisiontype, range, precision);
3457
3458 switch(shadertype)
3459 {
3460 case GL_VERTEX_SHADER:
3461 case GL_FRAGMENT_SHADER:
3462 break;
3463 default:
3464 return error(GL_INVALID_ENUM);
3465 }
3466
3467 switch(precisiontype)
3468 {
3469 case GL_LOW_FLOAT:
3470 case GL_MEDIUM_FLOAT:
3471 case GL_HIGH_FLOAT:
3472 // IEEE 754 single-precision
3473 range[0] = 127;
3474 range[1] = 127;
3475 *precision = 23;
3476 break;
3477 case GL_LOW_INT:
3478 case GL_MEDIUM_INT:
3479 case GL_HIGH_INT:
3480 // Full integer precision is supported
3481 range[0] = 31;
3482 range[1] = 30;
3483 *precision = 0;
3484 break;
3485 default:
3486 return error(GL_INVALID_ENUM);
3487 }
3488}
3489
3490void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3491{
3492 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
3493 shader, bufsize, length, source);
3494
3495 if(bufsize < 0)
3496 {
3497 return error(GL_INVALID_VALUE);
3498 }
3499
3500 es2::Context *context = es2::getContext();
3501
3502 if(context)
3503 {
3504 es2::Shader *shaderObject = context->getShader(shader);
3505
3506 if(!shaderObject)
3507 {
3508 if(context->getProgram(shader))
3509 {
3510 return error(GL_INVALID_OPERATION);
3511 }
3512 else
3513 {
3514 return error(GL_INVALID_VALUE);
3515 }
3516 }
3517
3518 shaderObject->getSource(bufsize, length, source);
3519 }
3520}
3521
3522const GLubyte* GetString(GLenum name)
3523{
3524 TRACE("(GLenum name = 0x%X)", name);
3525
3526 switch(name)
3527 {
3528 case GL_VENDOR:
3529 return (GLubyte*)"Google Inc.";
3530 case GL_RENDERER:
3531 return (GLubyte*)"Google SwiftShader";
3532 case GL_VERSION:
3533 {
3534 es2::Context *context = es2::getContext();
3535 return (context && (context->getClientVersion() >= 3)) ?
3536 (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :
3537 (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3538 }
3539 case GL_SHADING_LANGUAGE_VERSION:
3540 {
3541 es2::Context *context = es2::getContext();
3542 return (context && (context->getClientVersion() >= 3)) ?
3543 (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :
3544 (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3545 }
3546 case GL_EXTENSIONS:
3547 {
3548 es2::Context *context = es2::getContext();
3549 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)nullptr;
3550 }
3551 default:
3552 return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
3553 }
3554}
3555
3556void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3557{
3558 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
3559
3560 es2::Context *context = es2::getContext();
3561
3562 if(context)
3563 {
3564 es2::Texture *texture;
3565
3566 GLint clientVersion = context->getClientVersion();
3567
3568 switch(target)
3569 {
3570 case GL_TEXTURE_2D:
3571 texture = context->getTexture2D();
3572 break;
3573 case GL_TEXTURE_CUBE_MAP:
3574 texture = context->getTextureCubeMap();
3575 break;
3576 case GL_TEXTURE_EXTERNAL_OES:
3577 texture = context->getTextureExternal();
3578 break;
3579 case GL_TEXTURE_2D_ARRAY:
3580 if(clientVersion < 3)
3581 {
3582 return error(GL_INVALID_ENUM);
3583 }
3584 else
3585 {
3586 texture = context->getTexture2DArray();
3587 }
3588 break;
3589 case GL_TEXTURE_3D_OES:
3590 texture = context->getTexture3D();
3591 break;
3592 default:
3593 return error(GL_INVALID_ENUM);
3594 }
3595
3596 switch(pname)
3597 {
3598 case GL_TEXTURE_MAG_FILTER:
3599 *params = (GLfloat)texture->getMagFilter();
3600 break;
3601 case GL_TEXTURE_MIN_FILTER:
3602 *params = (GLfloat)texture->getMinFilter();
3603 break;
3604 case GL_TEXTURE_WRAP_S:
3605 *params = (GLfloat)texture->getWrapS();
3606 break;
3607 case GL_TEXTURE_WRAP_T:
3608 *params = (GLfloat)texture->getWrapT();
3609 break;
3610 case GL_TEXTURE_WRAP_R_OES:
3611 *params = (GLfloat)texture->getWrapR();
3612 break;
3613 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3614 *params = texture->getMaxAnisotropy();
3615 break;
3616 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3617 *params = (GLfloat)1;
3618 break;
3619 case GL_TEXTURE_BASE_LEVEL:
3620 if(clientVersion >= 3)
3621 {
3622 *params = (GLfloat)texture->getBaseLevel();
3623 break;
3624 }
3625 else return error(GL_INVALID_ENUM);
3626 case GL_TEXTURE_COMPARE_FUNC:
3627 if(clientVersion >= 3)
3628 {
3629 *params = (GLfloat)texture->getCompareFunc();
3630 break;
3631 }
3632 else return error(GL_INVALID_ENUM);
3633 case GL_TEXTURE_COMPARE_MODE:
3634 if(clientVersion >= 3)
3635 {
3636 *params = (GLfloat)texture->getCompareMode();
3637 break;
3638 }
3639 else return error(GL_INVALID_ENUM);
3640 case GL_TEXTURE_IMMUTABLE_FORMAT:
3641 if(clientVersion >= 3)
3642 {
3643 *params = (GLfloat)texture->getImmutableFormat();
3644 break;
3645 }
3646 else return error(GL_INVALID_ENUM);
3647 case GL_TEXTURE_IMMUTABLE_LEVELS:
3648 if(clientVersion >= 3)
3649 {
3650 *params = (GLfloat)texture->getImmutableLevels();
3651 break;
3652 }
3653 else return error(GL_INVALID_ENUM);
3654 case GL_TEXTURE_MAX_LEVEL:
3655 if(clientVersion >= 3)
3656 {
3657 *params = (GLfloat)texture->getMaxLevel();
3658 break;
3659 }
3660 else return error(GL_INVALID_ENUM);
3661 case GL_TEXTURE_MAX_LOD:
3662 if(clientVersion >= 3)
3663 {
3664 *params = texture->getMaxLOD();
3665 break;
3666 }
3667 else return error(GL_INVALID_ENUM);
3668 case GL_TEXTURE_MIN_LOD:
3669 if(clientVersion >= 3)
3670 {
3671 *params = texture->getMinLOD();
3672 break;
3673 }
3674 else return error(GL_INVALID_ENUM);
3675 case GL_TEXTURE_SWIZZLE_R:
3676 if(clientVersion >= 3)
3677 {
3678 *params = (GLfloat)texture->getSwizzleR();
3679 break;
3680 }
3681 else return error(GL_INVALID_ENUM);
3682 case GL_TEXTURE_SWIZZLE_G:
3683 if(clientVersion >= 3)
3684 {
3685 *params = (GLfloat)texture->getSwizzleG();
3686 break;
3687 }
3688 else return error(GL_INVALID_ENUM);
3689 case GL_TEXTURE_SWIZZLE_B:
3690 if(clientVersion >= 3)
3691 {
3692 *params = (GLfloat)texture->getSwizzleB();
3693 break;
3694 }
3695 else return error(GL_INVALID_ENUM);
3696 case GL_TEXTURE_SWIZZLE_A:
3697 if(clientVersion >= 3)
3698 {
3699 *params = (GLfloat)texture->getSwizzleA();
3700 break;
3701 }
3702 else return error(GL_INVALID_ENUM);
3703 default:
3704 return error(GL_INVALID_ENUM);
3705 }
3706 }
3707}
3708
3709void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3710{
3711 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3712
3713 es2::Context *context = es2::getContext();
3714
3715 if(context)
3716 {
3717 es2::Texture *texture;
3718
3719 GLint clientVersion = context->getClientVersion();
3720
3721 switch(target)
3722 {
3723 case GL_TEXTURE_2D:
3724 texture = context->getTexture2D();
3725 break;
3726 case GL_TEXTURE_CUBE_MAP:
3727 texture = context->getTextureCubeMap();
3728 break;
3729 case GL_TEXTURE_EXTERNAL_OES:
3730 texture = context->getTextureExternal();
3731 break;
3732 case GL_TEXTURE_2D_ARRAY:
3733 if(clientVersion < 3)
3734 {
3735 return error(GL_INVALID_ENUM);
3736 }
3737 else
3738 {
3739 texture = context->getTexture2DArray();
3740 }
3741 break;
3742 case GL_TEXTURE_3D_OES:
3743 texture = context->getTexture3D();
3744 break;
3745 default:
3746 return error(GL_INVALID_ENUM);
3747 }
3748
3749 switch(pname)
3750 {
3751 case GL_TEXTURE_MAG_FILTER:
3752 *params = texture->getMagFilter();
3753 break;
3754 case GL_TEXTURE_MIN_FILTER:
3755 *params = texture->getMinFilter();
3756 break;
3757 case GL_TEXTURE_WRAP_S:
3758 *params = texture->getWrapS();
3759 break;
3760 case GL_TEXTURE_WRAP_T:
3761 *params = texture->getWrapT();
3762 break;
3763 case GL_TEXTURE_WRAP_R_OES:
3764 *params = texture->getWrapR();
3765 break;
3766 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3767 *params = (GLint)texture->getMaxAnisotropy();
3768 break;
3769 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3770 *params = 1;
3771 break;
3772 case GL_TEXTURE_BASE_LEVEL:
3773 if(clientVersion >= 3)
3774 {
3775 *params = texture->getBaseLevel();
3776 break;
3777 }
3778 else return error(GL_INVALID_ENUM);
3779 case GL_TEXTURE_COMPARE_FUNC:
3780 if(clientVersion >= 3)
3781 {
3782 *params = (GLint)texture->getCompareFunc();
3783 break;
3784 }
3785 else return error(GL_INVALID_ENUM);
3786 case GL_TEXTURE_COMPARE_MODE:
3787 if(clientVersion >= 3)
3788 {
3789 *params = (GLint)texture->getCompareMode();
3790 break;
3791 }
3792 else return error(GL_INVALID_ENUM);
3793 case GL_TEXTURE_IMMUTABLE_FORMAT:
3794 if(clientVersion >= 3)
3795 {
3796 *params = (GLint)texture->getImmutableFormat();
3797 break;
3798 }
3799 else return error(GL_INVALID_ENUM);
3800 case GL_TEXTURE_IMMUTABLE_LEVELS:
3801 if(clientVersion >= 3)
3802 {
3803 *params = (GLint)texture->getImmutableLevels();
3804 break;
3805 }
3806 else return error(GL_INVALID_ENUM);
3807 case GL_TEXTURE_MAX_LEVEL:
3808 if(clientVersion >= 3)
3809 {
3810 *params = texture->getMaxLevel();
3811 break;
3812 }
3813 else return error(GL_INVALID_ENUM);
3814 case GL_TEXTURE_MAX_LOD:
3815 if(clientVersion >= 3)
3816 {
3817 *params = (GLint)roundf(texture->getMaxLOD());
3818 break;
3819 }
3820 else return error(GL_INVALID_ENUM);
3821 case GL_TEXTURE_MIN_LOD:
3822 if(clientVersion >= 3)
3823 {
3824 *params = (GLint)roundf(texture->getMinLOD());
3825 break;
3826 }
3827 else return error(GL_INVALID_ENUM);
3828 case GL_TEXTURE_SWIZZLE_R:
3829 if(clientVersion >= 3)
3830 {
3831 *params = (GLint)texture->getSwizzleR();
3832 break;
3833 }
3834 else return error(GL_INVALID_ENUM);
3835 case GL_TEXTURE_SWIZZLE_G:
3836 if(clientVersion >= 3)
3837 {
3838 *params = (GLint)texture->getSwizzleG();
3839 break;
3840 }
3841 else return error(GL_INVALID_ENUM);
3842 case GL_TEXTURE_SWIZZLE_B:
3843 if(clientVersion >= 3)
3844 {
3845 *params = (GLint)texture->getSwizzleB();
3846 break;
3847 }
3848 else return error(GL_INVALID_ENUM);
3849 case GL_TEXTURE_SWIZZLE_A:
3850 if(clientVersion >= 3)
3851 {
3852 *params = (GLint)texture->getSwizzleA();
3853 break;
3854 }
3855 else return error(GL_INVALID_ENUM);
3856 default:
3857 return error(GL_INVALID_ENUM);
3858 }
3859 }
3860}
3861
3862void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3863{
3864 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
3865 program, location, bufSize, params);
3866
3867 if(bufSize < 0)
3868 {
3869 return error(GL_INVALID_VALUE);
3870 }
3871
3872 es2::Context *context = es2::getContext();
3873
3874 if(context)
3875 {
Nicolas Capens0bac2852016-05-07 06:09:58 -04003876 es2::Program *programObject = context->getProgram(program);
3877
Nicolas Capens7eaa10a2016-06-09 10:01:58 -04003878 if(!programObject)
3879 {
3880 if(context->getShader(program))
3881 {
3882 return error(GL_INVALID_OPERATION);
3883 }
3884 else
3885 {
3886 return error(GL_INVALID_VALUE);
3887 }
3888 }
3889
3890 if(!programObject->isLinked())
Nicolas Capens0bac2852016-05-07 06:09:58 -04003891 {
3892 return error(GL_INVALID_OPERATION);
3893 }
3894
3895 if(!programObject->getUniformfv(location, &bufSize, params))
3896 {
3897 return error(GL_INVALID_OPERATION);
3898 }
3899 }
3900}
3901
3902void GetUniformfv(GLuint program, GLint location, GLfloat* params)
3903{
3904 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
3905
3906 es2::Context *context = es2::getContext();
3907
3908 if(context)
3909 {
Nicolas Capens0bac2852016-05-07 06:09:58 -04003910 es2::Program *programObject = context->getProgram(program);
3911
Nicolas Capens7eaa10a2016-06-09 10:01:58 -04003912 if(!programObject)
3913 {
3914 if(context->getShader(program))
3915 {
3916 return error(GL_INVALID_OPERATION);
3917 }
3918 else
3919 {
3920 return error(GL_INVALID_VALUE);
3921 }
3922 }
3923
3924 if(!programObject->isLinked())
Nicolas Capens0bac2852016-05-07 06:09:58 -04003925 {
3926 return error(GL_INVALID_OPERATION);
3927 }
3928
3929 if(!programObject->getUniformfv(location, nullptr, params))
3930 {
3931 return error(GL_INVALID_OPERATION);
3932 }
3933 }
3934}
3935
3936void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3937{
3938 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
3939 program, location, bufSize, params);
3940
3941 if(bufSize < 0)
3942 {
3943 return error(GL_INVALID_VALUE);
3944 }
3945
3946 es2::Context *context = es2::getContext();
3947
3948 if(context)
3949 {
Nicolas Capens0bac2852016-05-07 06:09:58 -04003950 es2::Program *programObject = context->getProgram(program);
3951
Nicolas Capens7eaa10a2016-06-09 10:01:58 -04003952 if(!programObject)
Nicolas Capens0bac2852016-05-07 06:09:58 -04003953 {
Nicolas Capens7eaa10a2016-06-09 10:01:58 -04003954 if(context->getShader(program))
3955 {
3956 return error(GL_INVALID_OPERATION);
3957 }
3958 else
3959 {
3960 return error(GL_INVALID_VALUE);
3961 }
Nicolas Capens0bac2852016-05-07 06:09:58 -04003962 }
3963
Nicolas Capens7eaa10a2016-06-09 10:01:58 -04003964 if(!programObject->isLinked())
Nicolas Capens0bac2852016-05-07 06:09:58 -04003965 {
3966 return error(GL_INVALID_OPERATION);
3967 }
3968
3969 if(!programObject->getUniformiv(location, &bufSize, params))
3970 {
3971 return error(GL_INVALID_OPERATION);
3972 }
3973 }
3974}
3975
3976void GetUniformiv(GLuint program, GLint location, GLint* params)
3977{
3978 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
3979
3980 es2::Context *context = es2::getContext();
3981
3982 if(context)
3983 {
Nicolas Capens0bac2852016-05-07 06:09:58 -04003984 es2::Program *programObject = context->getProgram(program);
3985
Nicolas Capens7eaa10a2016-06-09 10:01:58 -04003986 if(!programObject)
Nicolas Capens0bac2852016-05-07 06:09:58 -04003987 {
Nicolas Capens7eaa10a2016-06-09 10:01:58 -04003988 if(context->getShader(program))
3989 {
3990 return error(GL_INVALID_OPERATION);
3991 }
3992 else
3993 {
3994 return error(GL_INVALID_VALUE);
3995 }
Nicolas Capens0bac2852016-05-07 06:09:58 -04003996 }
3997
Nicolas Capens7eaa10a2016-06-09 10:01:58 -04003998 if(!programObject->isLinked())
Nicolas Capens0bac2852016-05-07 06:09:58 -04003999 {
4000 return error(GL_INVALID_OPERATION);
4001 }
4002
4003 if(!programObject->getUniformiv(location, nullptr, params))
4004 {
4005 return error(GL_INVALID_OPERATION);
4006 }
4007 }
4008}
4009
4010int GetUniformLocation(GLuint program, const GLchar* name)
4011{
4012 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
4013
4014 es2::Context *context = es2::getContext();
4015
4016 if(strstr(name, "gl_") == name)
4017 {
4018 return -1;
4019 }
4020
4021 if(context)
4022 {
4023 es2::Program *programObject = context->getProgram(program);
4024
4025 if(!programObject)
4026 {
4027 if(context->getShader(program))
4028 {
4029 return error(GL_INVALID_OPERATION, -1);
4030 }
4031 else
4032 {
4033 return error(GL_INVALID_VALUE, -1);
4034 }
4035 }
4036
4037 if(!programObject->isLinked())
4038 {
4039 return error(GL_INVALID_OPERATION, -1);
4040 }
4041
4042 return programObject->getUniformLocation(name);
4043 }
4044
4045 return -1;
4046}
4047
4048void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4049{
4050 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
4051
4052 es2::Context *context = es2::getContext();
4053
4054 if(context)
4055 {
4056 if(index >= es2::MAX_VERTEX_ATTRIBS)
4057 {
4058 return error(GL_INVALID_VALUE);
4059 }
4060
4061 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4062
4063 GLint clientVersion = context->getClientVersion();
4064
4065 switch(pname)
4066 {
4067 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4068 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4069 break;
4070 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4071 *params = (GLfloat)attribState.mSize;
4072 break;
4073 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4074 *params = (GLfloat)attribState.mStride;
4075 break;
4076 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4077 *params = (GLfloat)attribState.mType;
4078 break;
4079 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4080 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
4081 break;
4082 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4083 *params = (GLfloat)attribState.mBoundBuffer.name();
4084 break;
4085 case GL_CURRENT_VERTEX_ATTRIB:
4086 {
4087 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4088 for(int i = 0; i < 4; ++i)
4089 {
4090 params[i] = attrib.getCurrentValueF(i);
4091 }
4092 }
4093 break;
4094 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4095 if(clientVersion >= 3)
4096 {
4097 switch(attribState.mType)
4098 {
4099 case GL_BYTE:
4100 case GL_UNSIGNED_BYTE:
4101 case GL_SHORT:
4102 case GL_UNSIGNED_SHORT:
4103 case GL_INT:
4104 case GL_INT_2_10_10_10_REV:
4105 case GL_UNSIGNED_INT:
4106 case GL_FIXED:
4107 *params = (GLfloat)GL_TRUE;
4108 break;
4109 default:
4110 *params = (GLfloat)GL_FALSE;
4111 break;
4112 }
4113 break;
4114 }
4115 else return error(GL_INVALID_ENUM);
4116 default: return error(GL_INVALID_ENUM);
4117 }
4118 }
4119}
4120
4121void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4122{
4123 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
4124
4125 es2::Context *context = es2::getContext();
4126
4127 if(context)
4128 {
4129 if(index >= es2::MAX_VERTEX_ATTRIBS)
4130 {
4131 return error(GL_INVALID_VALUE);
4132 }
4133
4134 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4135
4136 GLint clientVersion = context->getClientVersion();
4137
4138 switch(pname)
4139 {
4140 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4141 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4142 break;
4143 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4144 *params = attribState.mSize;
4145 break;
4146 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4147 *params = attribState.mStride;
4148 break;
4149 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4150 *params = attribState.mType;
4151 break;
4152 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4153 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
4154 break;
4155 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4156 *params = attribState.mBoundBuffer.name();
4157 break;
4158 case GL_CURRENT_VERTEX_ATTRIB:
4159 {
4160 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4161 for(int i = 0; i < 4; ++i)
4162 {
4163 float currentValue = attrib.getCurrentValueF(i);
4164 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4165 }
4166 }
4167 break;
4168 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4169 if(clientVersion >= 3)
4170 {
4171 switch(attribState.mType)
4172 {
4173 case GL_BYTE:
4174 case GL_UNSIGNED_BYTE:
4175 case GL_SHORT:
4176 case GL_UNSIGNED_SHORT:
4177 case GL_INT:
4178 case GL_INT_2_10_10_10_REV:
4179 case GL_UNSIGNED_INT:
4180 case GL_FIXED:
4181 *params = GL_TRUE;
4182 break;
4183 default:
4184 *params = GL_FALSE;
4185 break;
4186 }
4187 break;
4188 }
4189 else return error(GL_INVALID_ENUM);
4190 default: return error(GL_INVALID_ENUM);
4191 }
4192 }
4193}
4194
4195void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
4196{
4197 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
4198
4199 es2::Context *context = es2::getContext();
4200
4201 if(context)
4202 {
4203 if(index >= es2::MAX_VERTEX_ATTRIBS)
4204 {
4205 return error(GL_INVALID_VALUE);
4206 }
4207
4208 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4209 {
4210 return error(GL_INVALID_ENUM);
4211 }
4212
4213 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
4214 }
4215}
4216
4217void Hint(GLenum target, GLenum mode)
4218{
4219 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
4220
4221 switch(mode)
4222 {
4223 case GL_FASTEST:
4224 case GL_NICEST:
4225 case GL_DONT_CARE:
4226 break;
4227 default:
4228 return error(GL_INVALID_ENUM);
4229 }
4230
4231 es2::Context *context = es2::getContext();
4232 switch(target)
4233 {
4234 case GL_GENERATE_MIPMAP_HINT:
4235 if(context) context->setGenerateMipmapHint(mode);
4236 break;
4237 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4238 if(context) context->setFragmentShaderDerivativeHint(mode);
4239 break;
4240 default:
4241 return error(GL_INVALID_ENUM);
4242 }
4243}
4244
4245GLboolean IsBuffer(GLuint buffer)
4246{
4247 TRACE("(GLuint buffer = %d)", buffer);
4248
4249 es2::Context *context = es2::getContext();
4250
4251 if(context && buffer)
4252 {
4253 es2::Buffer *bufferObject = context->getBuffer(buffer);
4254
4255 if(bufferObject)
4256 {
4257 return GL_TRUE;
4258 }
4259 }
4260
4261 return GL_FALSE;
4262}
4263
4264GLboolean IsEnabled(GLenum cap)
4265{
4266 TRACE("(GLenum cap = 0x%X)", cap);
4267
4268 es2::Context *context = es2::getContext();
4269
4270 if(context)
4271 {
4272 GLint clientVersion = context->getClientVersion();
4273
4274 switch(cap)
4275 {
4276 case GL_CULL_FACE: return context->isCullFaceEnabled();
4277 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4278 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4279 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4280 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4281 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4282 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4283 case GL_BLEND: return context->isBlendEnabled();
4284 case GL_DITHER: return context->isDitherEnabled();
4285 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4286 if(clientVersion >= 3)
4287 {
4288 return context->isPrimitiveRestartFixedIndexEnabled();
4289 }
4290 else return error(GL_INVALID_ENUM, false);
4291 case GL_RASTERIZER_DISCARD:
4292 if(clientVersion >= 3)
4293 {
4294 return context->isRasterizerDiscardEnabled();
4295 }
4296 else return error(GL_INVALID_ENUM, false);
4297 default:
4298 return error(GL_INVALID_ENUM, false);
4299 }
4300 }
4301
4302 return false;
4303}
4304
4305GLboolean IsFenceNV(GLuint fence)
4306{
4307 TRACE("(GLuint fence = %d)", fence);
4308
4309 es2::Context *context = es2::getContext();
4310
4311 if(context)
4312 {
4313 es2::Fence *fenceObject = context->getFence(fence);
4314
4315 if(!fenceObject)
4316 {
4317 return GL_FALSE;
4318 }
4319
4320 return fenceObject->isFence();
4321 }
4322
4323 return GL_FALSE;
4324}
4325
4326GLboolean IsFramebuffer(GLuint framebuffer)
4327{
4328 TRACE("(GLuint framebuffer = %d)", framebuffer);
4329
4330 es2::Context *context = es2::getContext();
4331
4332 if(context && framebuffer)
4333 {
4334 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4335
4336 if(framebufferObject)
4337 {
4338 return GL_TRUE;
4339 }
4340 }
4341
4342 return GL_FALSE;
4343}
4344
4345GLboolean IsProgram(GLuint program)
4346{
4347 TRACE("(GLuint program = %d)", program);
4348
4349 es2::Context *context = es2::getContext();
4350
4351 if(context && program)
4352 {
4353 es2::Program *programObject = context->getProgram(program);
4354
4355 if(programObject)
4356 {
4357 return GL_TRUE;
4358 }
4359 }
4360
4361 return GL_FALSE;
4362}
4363
4364GLboolean IsQueryEXT(GLuint name)
4365{
4366 TRACE("(GLuint name = %d)", name);
4367
4368 if(name == 0)
4369 {
4370 return GL_FALSE;
4371 }
4372
4373 es2::Context *context = es2::getContext();
4374
4375 if(context)
4376 {
4377 es2::Query *queryObject = context->getQuery(name);
4378
4379 if(queryObject)
4380 {
4381 return GL_TRUE;
4382 }
4383 }
4384
4385 return GL_FALSE;
4386}
4387
4388GLboolean IsRenderbuffer(GLuint renderbuffer)
4389{
4390 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
4391
4392 es2::Context *context = es2::getContext();
4393
4394 if(context && renderbuffer)
4395 {
4396 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4397
4398 if(renderbufferObject)
4399 {
4400 return GL_TRUE;
4401 }
4402 }
4403
4404 return GL_FALSE;
4405}
4406
4407GLboolean IsShader(GLuint shader)
4408{
4409 TRACE("(GLuint shader = %d)", shader);
4410
4411 es2::Context *context = es2::getContext();
4412
4413 if(context && shader)
4414 {
4415 es2::Shader *shaderObject = context->getShader(shader);
4416
4417 if(shaderObject)
4418 {
4419 return GL_TRUE;
4420 }
4421 }
4422
4423 return GL_FALSE;
4424}
4425
4426GLboolean IsTexture(GLuint texture)
4427{
4428 TRACE("(GLuint texture = %d)", texture);
4429
4430 es2::Context *context = es2::getContext();
4431
4432 if(context && texture)
4433 {
4434 es2::Texture *textureObject = context->getTexture(texture);
4435
4436 if(textureObject)
4437 {
4438 return GL_TRUE;
4439 }
4440 }
4441
4442 return GL_FALSE;
4443}
4444
4445void LineWidth(GLfloat width)
4446{
4447 TRACE("(GLfloat width = %f)", width);
4448
4449 if(width <= 0.0f)
4450 {
4451 return error(GL_INVALID_VALUE);
4452 }
4453
4454 es2::Context *context = es2::getContext();
4455
4456 if(context)
4457 {
4458 context->setLineWidth(width);
4459 }
4460}
4461
4462void LinkProgram(GLuint program)
4463{
4464 TRACE("(GLuint program = %d)", program);
4465
4466 es2::Context *context = es2::getContext();
4467
4468 if(context)
4469 {
4470 es2::Program *programObject = context->getProgram(program);
4471
4472 if(!programObject)
4473 {
4474 if(context->getShader(program))
4475 {
4476 return error(GL_INVALID_OPERATION);
4477 }
4478 else
4479 {
4480 return error(GL_INVALID_VALUE);
4481 }
4482 }
4483
4484 programObject->link();
4485 }
4486}
4487
4488void PixelStorei(GLenum pname, GLint param)
4489{
4490 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
4491
4492 es2::Context *context = es2::getContext();
4493
4494 if(context)
4495 {
4496 GLint clientVersion = context->getClientVersion();
4497
4498 switch(pname)
4499 {
4500 case GL_UNPACK_ALIGNMENT:
4501 if(param != 1 && param != 2 && param != 4 && param != 8)
4502 {
4503 return error(GL_INVALID_VALUE);
4504 }
4505 context->setUnpackAlignment(param);
4506 break;
4507 case GL_PACK_ALIGNMENT:
4508 if(param != 1 && param != 2 && param != 4 && param != 8)
4509 {
4510 return error(GL_INVALID_VALUE);
4511 }
4512 context->setPackAlignment(param);
4513 break;
4514 case GL_PACK_ROW_LENGTH:
4515 if(clientVersion >= 3)
4516 {
4517 if(param < 0)
4518 {
4519 return error(GL_INVALID_VALUE);
4520 }
4521 context->setPackRowLength(param);
4522 break;
4523 }
4524 else return error(GL_INVALID_ENUM);
4525 case GL_PACK_SKIP_PIXELS:
4526 if(clientVersion >= 3)
4527 {
4528 if(param < 0)
4529 {
4530 return error(GL_INVALID_VALUE);
4531 }
4532 context->setPackSkipPixels(param);
4533 break;
4534 }
4535 else return error(GL_INVALID_ENUM);
4536 case GL_PACK_SKIP_ROWS:
4537 if(clientVersion >= 3)
4538 {
4539 if(param < 0)
4540 {
4541 return error(GL_INVALID_VALUE);
4542 }
4543 context->setPackSkipRows(param);
4544 break;
4545 }
4546 else return error(GL_INVALID_ENUM);
4547 case GL_UNPACK_ROW_LENGTH:
4548 if(clientVersion >= 3)
4549 {
4550 if(param < 0)
4551 {
4552 return error(GL_INVALID_VALUE);
4553 }
4554 context->setUnpackRowLength(param);
4555 break;
4556 }
4557 else return error(GL_INVALID_ENUM);
4558 case GL_UNPACK_IMAGE_HEIGHT:
4559 if(clientVersion >= 3)
4560 {
4561 if(param < 0)
4562 {
4563 return error(GL_INVALID_VALUE);
4564 }
4565 context->setUnpackImageHeight(param);
4566 break;
4567 }
4568 else return error(GL_INVALID_ENUM);
4569 case GL_UNPACK_SKIP_PIXELS:
4570 if(clientVersion >= 3)
4571 {
4572 if(param < 0)
4573 {
4574 return error(GL_INVALID_VALUE);
4575 }
4576 context->setUnpackSkipPixels(param);
4577 break;
4578 }
4579 else return error(GL_INVALID_ENUM);
4580 case GL_UNPACK_SKIP_ROWS:
4581 if(clientVersion >= 3)
4582 {
4583 if(param < 0)
4584 {
4585 return error(GL_INVALID_VALUE);
4586 }
4587 context->setUnpackSkipRows(param);
4588 break;
4589 }
4590 else return error(GL_INVALID_ENUM);
4591 case GL_UNPACK_SKIP_IMAGES:
4592 if(clientVersion >= 3) {
4593 if(param < 0)
4594 {
4595 return error(GL_INVALID_VALUE);
4596 }
4597 context->setUnpackSkipImages(param);
4598 break;
4599 }
4600 else return error(GL_INVALID_ENUM);
4601 default:
4602 return error(GL_INVALID_ENUM);
4603 }
4604 }
4605}
4606
4607void PolygonOffset(GLfloat factor, GLfloat units)
4608{
4609 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
4610
4611 es2::Context *context = es2::getContext();
4612
4613 if(context)
4614 {
4615 context->setPolygonOffsetParams(factor, units);
4616 }
4617}
4618
4619void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4620 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
4621{
4622 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4623 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
4624 x, y, width, height, format, type, bufSize, data);
4625
4626 if(width < 0 || height < 0 || bufSize < 0)
4627 {
4628 return error(GL_INVALID_VALUE);
4629 }
4630
4631 es2::Context *context = es2::getContext();
4632
4633 if(context)
4634 {
4635 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4636 }
4637}
4638
4639void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
4640{
4641 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4642 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
4643 x, y, width, height, format, type, pixels);
4644
4645 if(width < 0 || height < 0)
4646 {
4647 return error(GL_INVALID_VALUE);
4648 }
4649
4650 es2::Context *context = es2::getContext();
4651
4652 if(context)
4653 {
4654 context->readPixels(x, y, width, height, format, type, nullptr, pixels);
4655 }
4656}
4657
4658void ReleaseShaderCompiler(void)
4659{
4660 TRACE("()");
4661
4662 es2::Shader::releaseCompiler();
4663}
4664
4665void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4666{
4667 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4668 target, samples, internalformat, width, height);
4669
4670 switch(target)
4671 {
4672 case GL_RENDERBUFFER:
4673 break;
4674 default:
4675 return error(GL_INVALID_ENUM);
4676 }
4677
4678 if(width < 0 || height < 0 || samples < 0)
4679 {
4680 return error(GL_INVALID_VALUE);
4681 }
4682
4683 es2::Context *context = es2::getContext();
4684
4685 if(context)
4686 {
4687 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4688 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4689 samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4690 {
4691 return error(GL_INVALID_VALUE);
4692 }
4693
4694 GLuint handle = context->getRenderbufferName();
4695 if(handle == 0)
4696 {
4697 return error(GL_INVALID_OPERATION);
4698 }
4699
4700 GLint clientVersion = context->getClientVersion();
4701 switch(internalformat)
4702 {
4703 case GL_DEPTH_COMPONENT32F:
4704 if(clientVersion < 3)
4705 {
4706 return error(GL_INVALID_ENUM);
4707 }
4708 // fall through
4709 case GL_DEPTH_COMPONENT16:
4710 case GL_DEPTH_COMPONENT24:
4711 case GL_DEPTH_COMPONENT32_OES:
4712 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));
4713 break;
4714 case GL_R8:
4715 case GL_R8UI:
4716 case GL_R8I:
4717 case GL_R16UI:
4718 case GL_R16I:
4719 case GL_R32UI:
4720 case GL_R32I:
4721 case GL_RG8:
4722 case GL_RG8UI:
4723 case GL_RG8I:
4724 case GL_RG16UI:
4725 case GL_RG16I:
4726 case GL_RG32UI:
4727 case GL_RG32I:
4728 case GL_SRGB8_ALPHA8:
4729 case GL_RGB10_A2:
4730 case GL_RGBA8UI:
4731 case GL_RGBA8I:
4732 case GL_RGB10_A2UI:
4733 case GL_RGBA16UI:
4734 case GL_RGBA16I:
4735 case GL_RGBA32I:
4736 case GL_RGBA32UI:
4737 case GL_R11F_G11F_B10F:
4738 case GL_R32F:
4739 case GL_RG32F:
4740 case GL_RGB32F:
4741 case GL_RGBA32F:
4742 if(clientVersion < 3)
4743 {
4744 return error(GL_INVALID_ENUM);
4745 }
4746 // fall through
4747 case GL_RGBA4:
4748 case GL_RGB5_A1:
4749 case GL_RGB565:
4750 case GL_RGB8_OES:
4751 case GL_RGBA8_OES:
4752 case GL_R16F:
4753 case GL_RG16F:
4754 case GL_RGB16F:
4755 case GL_RGBA16F:
4756 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4757 break;
4758 case GL_STENCIL_INDEX8:
4759 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4760 break;
4761 case GL_DEPTH32F_STENCIL8:
4762 if(clientVersion < 3)
4763 {
4764 return error(GL_INVALID_ENUM);
4765 }
4766 // fall through
4767 case GL_DEPTH24_STENCIL8_OES:
4768 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));
4769 break;
4770 default:
4771 return error(GL_INVALID_ENUM);
4772 }
4773 }
4774}
4775
4776void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4777{
4778 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4779}
4780
4781void SampleCoverage(GLclampf value, GLboolean invert)
4782{
4783 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
4784
4785 es2::Context* context = es2::getContext();
4786
4787 if(context)
4788 {
4789 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4790 }
4791}
4792
4793void SetFenceNV(GLuint fence, GLenum condition)
4794{
4795 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4796
4797 if(condition != GL_ALL_COMPLETED_NV)
4798 {
4799 return error(GL_INVALID_ENUM);
4800 }
4801
4802 es2::Context *context = es2::getContext();
4803
4804 if(context)
4805 {
4806 es2::Fence *fenceObject = context->getFence(fence);
4807
4808 if(!fenceObject)
4809 {
4810 return error(GL_INVALID_OPERATION);
4811 }
4812
4813 fenceObject->setFence(condition);
4814 }
4815}
4816
4817void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
4818{
4819 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4820
4821 if(width < 0 || height < 0)
4822 {
4823 return error(GL_INVALID_VALUE);
4824 }
4825
4826 es2::Context* context = es2::getContext();
4827
4828 if(context)
4829 {
4830 context->setScissorParams(x, y, width, height);
4831 }
4832}
4833
4834void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4835{
4836 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4837 "const GLvoid* binary = %p, GLsizei length = %d)",
4838 n, shaders, binaryformat, binary, length);
4839
4840 // No binary shader formats are supported.
4841 return error(GL_INVALID_ENUM);
4842}
4843
4844void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
4845{
4846 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
4847 shader, count, string, length);
4848
4849 if(count < 0)
4850 {
4851 return error(GL_INVALID_VALUE);
4852 }
4853
4854 es2::Context *context = es2::getContext();
4855
4856 if(context)
4857 {
4858 es2::Shader *shaderObject = context->getShader(shader);
4859
4860 if(!shaderObject)
4861 {
4862 if(context->getProgram(shader))
4863 {
4864 return error(GL_INVALID_OPERATION);
4865 }
4866 else
4867 {
4868 return error(GL_INVALID_VALUE);
4869 }
4870 }
4871
4872 shaderObject->setSource(count, string, length);
4873 }
4874}
4875
4876void StencilFunc(GLenum func, GLint ref, GLuint mask)
4877{
4878 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4879}
4880
4881void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4882{
4883 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4884
4885 switch(face)
4886 {
4887 case GL_FRONT:
4888 case GL_BACK:
4889 case GL_FRONT_AND_BACK:
4890 break;
4891 default:
4892 return error(GL_INVALID_ENUM);
4893 }
4894
4895 switch(func)
4896 {
4897 case GL_NEVER:
4898 case GL_ALWAYS:
4899 case GL_LESS:
4900 case GL_LEQUAL:
4901 case GL_EQUAL:
4902 case GL_GEQUAL:
4903 case GL_GREATER:
4904 case GL_NOTEQUAL:
4905 break;
4906 default:
4907 return error(GL_INVALID_ENUM);
4908 }
4909
4910 es2::Context *context = es2::getContext();
4911
4912 if(context)
4913 {
4914 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4915 {
4916 context->setStencilParams(func, ref, mask);
4917 }
4918
4919 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4920 {
4921 context->setStencilBackParams(func, ref, mask);
4922 }
4923 }
4924}
4925
4926void StencilMask(GLuint mask)
4927{
4928 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4929}
4930
4931void StencilMaskSeparate(GLenum face, GLuint mask)
4932{
4933 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4934
4935 switch(face)
4936 {
4937 case GL_FRONT:
4938 case GL_BACK:
4939 case GL_FRONT_AND_BACK:
4940 break;
4941 default:
4942 return error(GL_INVALID_ENUM);
4943 }
4944
4945 es2::Context *context = es2::getContext();
4946
4947 if(context)
4948 {
4949 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4950 {
4951 context->setStencilWritemask(mask);
4952 }
4953
4954 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4955 {
4956 context->setStencilBackWritemask(mask);
4957 }
4958 }
4959}
4960
4961void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4962{
4963 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4964}
4965
4966void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4967{
4968 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4969 face, fail, zfail, zpass);
4970
4971 switch(face)
4972 {
4973 case GL_FRONT:
4974 case GL_BACK:
4975 case GL_FRONT_AND_BACK:
4976 break;
4977 default:
4978 return error(GL_INVALID_ENUM);
4979 }
4980
4981 switch(fail)
4982 {
4983 case GL_ZERO:
4984 case GL_KEEP:
4985 case GL_REPLACE:
4986 case GL_INCR:
4987 case GL_DECR:
4988 case GL_INVERT:
4989 case GL_INCR_WRAP:
4990 case GL_DECR_WRAP:
4991 break;
4992 default:
4993 return error(GL_INVALID_ENUM);
4994 }
4995
4996 switch(zfail)
4997 {
4998 case GL_ZERO:
4999 case GL_KEEP:
5000 case GL_REPLACE:
5001 case GL_INCR:
5002 case GL_DECR:
5003 case GL_INVERT:
5004 case GL_INCR_WRAP:
5005 case GL_DECR_WRAP:
5006 break;
5007 default:
5008 return error(GL_INVALID_ENUM);
5009 }
5010
5011 switch(zpass)
5012 {
5013 case GL_ZERO:
5014 case GL_KEEP:
5015 case GL_REPLACE:
5016 case GL_INCR:
5017 case GL_DECR:
5018 case GL_INVERT:
5019 case GL_INCR_WRAP:
5020 case GL_DECR_WRAP:
5021 break;
5022 default:
5023 return error(GL_INVALID_ENUM);
5024 }
5025
5026 es2::Context *context = es2::getContext();
5027
5028 if(context)
5029 {
5030 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
5031 {
5032 context->setStencilOperations(fail, zfail, zpass);
5033 }
5034
5035 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
5036 {
5037 context->setStencilBackOperations(fail, zfail, zpass);
5038 }
5039 }
5040}
5041
5042GLboolean TestFenceNV(GLuint fence)
5043{
5044 TRACE("(GLuint fence = %d)", fence);
5045
5046 es2::Context *context = es2::getContext();
5047
5048 if(context)
5049 {
5050 es2::Fence *fenceObject = context->getFence(fence);
5051
5052 if(!fenceObject)
5053 {
5054 return error(GL_INVALID_OPERATION, GL_TRUE);
5055 }
5056
5057 return fenceObject->testFence();
5058 }
5059
5060 return GL_TRUE;
5061}
5062
5063void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
Alexis Hetu53f48092016-06-17 14:08:06 -04005064 GLint border, GLenum format, GLenum type, const GLvoid* data)
Nicolas Capens0bac2852016-05-07 06:09:58 -04005065{
5066 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
Alexis Hetu53f48092016-06-17 14:08:06 -04005067 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* data = %p)",
5068 target, level, internalformat, width, height, border, format, type, data);
Nicolas Capens0bac2852016-05-07 06:09:58 -04005069
5070 if(!validImageSize(level, width, height))
5071 {
5072 return error(GL_INVALID_VALUE);
5073 }
5074
5075 es2::Context *context = es2::getContext();
5076
5077 if(context)
5078 {
5079 GLint clientVersion = context->getClientVersion();
5080 if(clientVersion < 3)
5081 {
5082 if(internalformat != (GLint)format)
5083 {
5084 return error(GL_INVALID_OPERATION);
5085 }
5086 }
5087
5088 GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);
5089 if(validationError != GL_NONE)
5090 {
5091 return error(validationError);
5092 }
5093
5094 if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
5095 {
5096 return;
5097 }
5098
5099 if(border != 0)
5100 {
5101 return error(GL_INVALID_VALUE);
5102 }
5103
5104 switch(target)
5105 {
5106 case GL_TEXTURE_2D:
5107 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5108 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
5109 {
5110 return error(GL_INVALID_VALUE);
5111 }
5112 break;
5113 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5114 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5115 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5116 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5117 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5118 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5119 if(width != height)
5120 {
5121 return error(GL_INVALID_VALUE);
5122 }
5123
5124 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5125 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5126 {
5127 return error(GL_INVALID_VALUE);
5128 }
5129 break;
5130 default:
5131 return error(GL_INVALID_ENUM);
5132 }
5133
5134 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
5135
5136 if(target == GL_TEXTURE_2D)
5137 {
5138 es2::Texture2D *texture = context->getTexture2D();
5139
5140 if(!texture)
5141 {
5142 return error(GL_INVALID_OPERATION);
5143 }
5144
Alexis Hetu53f48092016-06-17 14:08:06 -04005145 texture->setImage(level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
Nicolas Capens0bac2852016-05-07 06:09:58 -04005146 }
5147 else
5148 {
5149 es2::TextureCubeMap *texture = context->getTextureCubeMap();
5150
5151 if(!texture)
5152 {
5153 return error(GL_INVALID_OPERATION);
5154 }
5155
Alexis Hetu53f48092016-06-17 14:08:06 -04005156 texture->setImage(target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
Nicolas Capens0bac2852016-05-07 06:09:58 -04005157 }
5158 }
5159}
5160
5161void TexParameterf(GLenum target, GLenum pname, GLfloat param)
5162{
5163 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
5164
5165 es2::Context *context = es2::getContext();
5166
5167 if(context)
5168 {
5169 es2::Texture *texture;
5170
5171 GLint clientVersion = context->getClientVersion();
5172
5173 switch(target)
5174 {
5175 case GL_TEXTURE_2D:
5176 texture = context->getTexture2D();
5177 break;
5178 case GL_TEXTURE_2D_ARRAY:
5179 if(clientVersion < 3)
5180 {
5181 return error(GL_INVALID_ENUM);
5182 }
5183 else
5184 {
5185 texture = context->getTexture2DArray();
5186 }
5187 break;
5188 case GL_TEXTURE_3D_OES:
5189 texture = context->getTexture3D();
5190 break;
5191 case GL_TEXTURE_CUBE_MAP:
5192 texture = context->getTextureCubeMap();
5193 break;
5194 case GL_TEXTURE_EXTERNAL_OES:
5195 texture = context->getTextureExternal();
5196 break;
5197 default:
5198 return error(GL_INVALID_ENUM);
5199 }
5200
5201 switch(pname)
5202 {
5203 case GL_TEXTURE_WRAP_S:
5204 if(!texture->setWrapS((GLenum)param))
5205 {
5206 return error(GL_INVALID_ENUM);
5207 }
5208 break;
5209 case GL_TEXTURE_WRAP_T:
5210 if(!texture->setWrapT((GLenum)param))
5211 {
5212 return error(GL_INVALID_ENUM);
5213 }
5214 break;
5215 case GL_TEXTURE_WRAP_R_OES:
5216 if(!texture->setWrapR((GLenum)param))
5217 {
5218 return error(GL_INVALID_ENUM);
5219 }
5220 break;
5221 case GL_TEXTURE_MIN_FILTER:
5222 if(!texture->setMinFilter((GLenum)param))
5223 {
5224 return error(GL_INVALID_ENUM);
5225 }
5226 break;
5227 case GL_TEXTURE_MAG_FILTER:
5228 if(!texture->setMagFilter((GLenum)param))
5229 {
5230 return error(GL_INVALID_ENUM);
5231 }
5232 break;
5233 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5234 if(!texture->setMaxAnisotropy(param))
5235 {
5236 return error(GL_INVALID_VALUE);
5237 }
5238 break;
5239 case GL_TEXTURE_BASE_LEVEL:
5240 if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))
5241 {
5242 return error(GL_INVALID_VALUE);
5243 }
5244 break;
5245 case GL_TEXTURE_COMPARE_FUNC:
5246 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5247 {
5248 return error(GL_INVALID_VALUE);
5249 }
5250 break;
5251 case GL_TEXTURE_COMPARE_MODE:
5252 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5253 {
5254 return error(GL_INVALID_VALUE);
5255 }
5256 break;
5257 case GL_TEXTURE_MAX_LEVEL:
5258 if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))
5259 {
5260 return error(GL_INVALID_VALUE);
5261 }
5262 break;
5263 case GL_TEXTURE_MAX_LOD:
5264 if(clientVersion < 3 || !texture->setMaxLOD(param))
5265 {
5266 return error(GL_INVALID_VALUE);
5267 }
5268 break;
5269 case GL_TEXTURE_MIN_LOD:
5270 if(clientVersion < 3 || !texture->setMinLOD(param))
5271 {
5272 return error(GL_INVALID_VALUE);
5273 }
5274 break;
5275 case GL_TEXTURE_SWIZZLE_R:
5276 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5277 {
5278 return error(GL_INVALID_VALUE);
5279 }
5280 break;
5281 case GL_TEXTURE_SWIZZLE_G:
5282 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5283 {
5284 return error(GL_INVALID_VALUE);
5285 }
5286 break;
5287 case GL_TEXTURE_SWIZZLE_B:
5288 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5289 {
5290 return error(GL_INVALID_VALUE);
5291 }
5292 break;
5293 case GL_TEXTURE_SWIZZLE_A:
5294 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5295 {
5296 return error(GL_INVALID_VALUE);
5297 }
5298 break;
5299 default:
5300 return error(GL_INVALID_ENUM);
5301 }
5302 }
5303}
5304
5305void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5306{
5307 glTexParameterf(target, pname, *params);
5308}
5309
5310void TexParameteri(GLenum target, GLenum pname, GLint param)
5311{
5312 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
5313
5314 es2::Context *context = es2::getContext();
5315
5316 if(context)
5317 {
5318 es2::Texture *texture;
5319
5320 GLint clientVersion = context->getClientVersion();
5321
5322 switch(target)
5323 {
5324 case GL_TEXTURE_2D:
5325 texture = context->getTexture2D();
5326 break;
5327 case GL_TEXTURE_2D_ARRAY:
5328 if(clientVersion < 3)
5329 {
5330 return error(GL_INVALID_ENUM);
5331 }
5332 else
5333 {
5334 texture = context->getTexture2DArray();
5335 }
5336 break;
5337 case GL_TEXTURE_3D_OES:
5338 texture = context->getTexture3D();
5339 break;
5340 case GL_TEXTURE_CUBE_MAP:
5341 texture = context->getTextureCubeMap();
5342 break;
5343 case GL_TEXTURE_EXTERNAL_OES:
5344 texture = context->getTextureExternal();
5345 break;
5346 default:
5347 return error(GL_INVALID_ENUM);
5348 }
5349
5350 switch(pname)
5351 {
5352 case GL_TEXTURE_WRAP_S:
5353 if(!texture->setWrapS((GLenum)param))
5354 {
5355 return error(GL_INVALID_ENUM);
5356 }
5357 break;
5358 case GL_TEXTURE_WRAP_T:
5359 if(!texture->setWrapT((GLenum)param))
5360 {
5361 return error(GL_INVALID_ENUM);
5362 }
5363 break;
5364 case GL_TEXTURE_WRAP_R_OES:
5365 if(!texture->setWrapR((GLenum)param))
5366 {
5367 return error(GL_INVALID_ENUM);
5368 }
5369 break;
5370 case GL_TEXTURE_MIN_FILTER:
5371 if(!texture->setMinFilter((GLenum)param))
5372 {
5373 return error(GL_INVALID_ENUM);
5374 }
5375 break;
5376 case GL_TEXTURE_MAG_FILTER:
5377 if(!texture->setMagFilter((GLenum)param))
5378 {
5379 return error(GL_INVALID_ENUM);
5380 }
5381 break;
5382 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5383 if(!texture->setMaxAnisotropy((GLfloat)param))
5384 {
5385 return error(GL_INVALID_VALUE);
5386 }
5387 break;
5388 case GL_TEXTURE_BASE_LEVEL:
5389 if(clientVersion < 3 || !texture->setBaseLevel(param))
5390 {
5391 return error(GL_INVALID_VALUE);
5392 }
5393 break;
5394 case GL_TEXTURE_COMPARE_FUNC:
5395 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5396 {
5397 return error(GL_INVALID_VALUE);
5398 }
5399 break;
5400 case GL_TEXTURE_COMPARE_MODE:
5401 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5402 {
5403 return error(GL_INVALID_VALUE);
5404 }
5405 break;
5406 case GL_TEXTURE_MAX_LEVEL:
5407 if(clientVersion < 3 || !texture->setMaxLevel(param))
5408 {
5409 return error(GL_INVALID_VALUE);
5410 }
5411 break;
5412 case GL_TEXTURE_MAX_LOD:
5413 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5414 {
5415 return error(GL_INVALID_VALUE);
5416 }
5417 break;
5418 case GL_TEXTURE_MIN_LOD:
5419 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5420 {
5421 return error(GL_INVALID_VALUE);
5422 }
5423 break;
5424 case GL_TEXTURE_SWIZZLE_R:
5425 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5426 {
5427 return error(GL_INVALID_VALUE);
5428 }
5429 break;
5430 case GL_TEXTURE_SWIZZLE_G:
5431 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5432 {
5433 return error(GL_INVALID_VALUE);
5434 }
5435 break;
5436 case GL_TEXTURE_SWIZZLE_B:
5437 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5438 {
5439 return error(GL_INVALID_VALUE);
5440 }
5441 break;
5442 case GL_TEXTURE_SWIZZLE_A:
5443 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5444 {
5445 return error(GL_INVALID_VALUE);
5446 }
5447 break;
5448 default:
5449 return error(GL_INVALID_ENUM);
5450 }
5451 }
5452}
5453
5454void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
5455{
5456 glTexParameteri(target, pname, *params);
5457}
5458
5459void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Alexis Hetu53f48092016-06-17 14:08:06 -04005460 GLenum format, GLenum type, const GLvoid* data)
Nicolas Capens0bac2852016-05-07 06:09:58 -04005461{
5462 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5463 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
Alexis Hetu53f48092016-06-17 14:08:06 -04005464 "const GLvoid* data = %p)",
5465 target, level, xoffset, yoffset, width, height, format, type, data);
Nicolas Capens0bac2852016-05-07 06:09:58 -04005466
5467 if(!es2::IsTextureTarget(target))
5468 {
5469 return error(GL_INVALID_ENUM);
5470 }
5471
5472 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5473 {
5474 return error(GL_INVALID_VALUE);
5475 }
5476
5477 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5478 {
5479 return error(GL_INVALID_VALUE);
5480 }
5481
5482 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5483 {
5484 return error(GL_INVALID_VALUE);
5485 }
5486
5487 if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
5488 {
5489 return;
5490 }
5491
Alexis Hetu53f48092016-06-17 14:08:06 -04005492 if(width == 0 || height == 0)
Nicolas Capens0bac2852016-05-07 06:09:58 -04005493 {
5494 return;
5495 }
5496
5497 es2::Context *context = es2::getContext();
5498
5499 if(context)
5500 {
5501 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
5502
5503 if(target == GL_TEXTURE_2D)
5504 {
5505 es2::Texture2D *texture = context->getTexture2D();
5506
5507 GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
5508
5509 if(validationError == GL_NONE)
5510 {
Alexis Hetu53f48092016-06-17 14:08:06 -04005511 texture->subImage(level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
Nicolas Capens0bac2852016-05-07 06:09:58 -04005512 }
5513 else
5514 {
5515 return error(validationError);
5516 }
5517 }
5518 else if(es2::IsCubemapTextureTarget(target))
5519 {
5520 es2::TextureCubeMap *texture = context->getTextureCubeMap();
5521
5522 GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
5523
5524 if(validationError == GL_NONE)
5525 {
Alexis Hetu53f48092016-06-17 14:08:06 -04005526 texture->subImage(target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
Nicolas Capens0bac2852016-05-07 06:09:58 -04005527 }
5528 else
5529 {
5530 return error(validationError);
5531 }
5532 }
5533 else UNREACHABLE(target);
5534 }
5535}
5536
5537void Uniform1f(GLint location, GLfloat x)
5538{
5539 glUniform1fv(location, 1, &x);
5540}
5541
5542void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
5543{
5544 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5545
5546 if(count < 0)
5547 {
5548 return error(GL_INVALID_VALUE);
5549 }
5550
5551 if(location == -1)
5552 {
5553 return;
5554 }
5555
5556 es2::Context *context = es2::getContext();
5557
5558 if(context)
5559 {
5560 es2::Program *program = context->getCurrentProgram();
5561
5562 if(!program)
5563 {
5564 return error(GL_INVALID_OPERATION);
5565 }
5566
5567 if(!program->setUniform1fv(location, count, v))
5568 {
5569 return error(GL_INVALID_OPERATION);
5570 }
5571 }
5572}
5573
5574void Uniform1i(GLint location, GLint x)
5575{
5576 glUniform1iv(location, 1, &x);
5577}
5578
5579void Uniform1iv(GLint location, GLsizei count, const GLint* v)
5580{
5581 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5582
5583 if(count < 0)
5584 {
5585 return error(GL_INVALID_VALUE);
5586 }
5587
5588 if(location == -1)
5589 {
5590 return;
5591 }
5592
5593 es2::Context *context = es2::getContext();
5594
5595 if(context)
5596 {
5597 es2::Program *program = context->getCurrentProgram();
5598
5599 if(!program)
5600 {
5601 return error(GL_INVALID_OPERATION);
5602 }
5603
5604 if(!program->setUniform1iv(location, count, v))
5605 {
5606 return error(GL_INVALID_OPERATION);
5607 }
5608 }
5609}
5610
5611void Uniform2f(GLint location, GLfloat x, GLfloat y)
5612{
5613 GLfloat xy[2] = {x, y};
5614
5615 glUniform2fv(location, 1, (GLfloat*)&xy);
5616}
5617
5618void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
5619{
5620 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5621
5622 if(count < 0)
5623 {
5624 return error(GL_INVALID_VALUE);
5625 }
5626
5627 if(location == -1)
5628 {
5629 return;
5630 }
5631
5632 es2::Context *context = es2::getContext();
5633
5634 if(context)
5635 {
5636 es2::Program *program = context->getCurrentProgram();
5637
5638 if(!program)
5639 {
5640 return error(GL_INVALID_OPERATION);
5641 }
5642
5643 if(!program->setUniform2fv(location, count, v))
5644 {
5645 return error(GL_INVALID_OPERATION);
5646 }
5647 }
5648}
5649
5650void Uniform2i(GLint location, GLint x, GLint y)
5651{
5652 GLint xy[4] = {x, y};
5653
5654 glUniform2iv(location, 1, (GLint*)&xy);
5655}
5656
5657void Uniform2iv(GLint location, GLsizei count, const GLint* v)
5658{
5659 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5660
5661 if(count < 0)
5662 {
5663 return error(GL_INVALID_VALUE);
5664 }
5665
5666 if(location == -1)
5667 {
5668 return;
5669 }
5670
5671 es2::Context *context = es2::getContext();
5672
5673 if(context)
5674 {
5675 es2::Program *program = context->getCurrentProgram();
5676
5677 if(!program)
5678 {
5679 return error(GL_INVALID_OPERATION);
5680 }
5681
5682 if(!program->setUniform2iv(location, count, v))
5683 {
5684 return error(GL_INVALID_OPERATION);
5685 }
5686 }
5687}
5688
5689void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5690{
5691 GLfloat xyz[3] = {x, y, z};
5692
5693 glUniform3fv(location, 1, (GLfloat*)&xyz);
5694}
5695
5696void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
5697{
5698 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5699
5700 if(count < 0)
5701 {
5702 return error(GL_INVALID_VALUE);
5703 }
5704
5705 if(location == -1)
5706 {
5707 return;
5708 }
5709
5710 es2::Context *context = es2::getContext();
5711
5712 if(context)
5713 {
5714 es2::Program *program = context->getCurrentProgram();
5715
5716 if(!program)
5717 {
5718 return error(GL_INVALID_OPERATION);
5719 }
5720
5721 if(!program->setUniform3fv(location, count, v))
5722 {
5723 return error(GL_INVALID_OPERATION);
5724 }
5725 }
5726}
5727
5728void Uniform3i(GLint location, GLint x, GLint y, GLint z)
5729{
5730 GLint xyz[3] = {x, y, z};
5731
5732 glUniform3iv(location, 1, (GLint*)&xyz);
5733}
5734
5735void Uniform3iv(GLint location, GLsizei count, const GLint* v)
5736{
5737 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5738
5739 if(count < 0)
5740 {
5741 return error(GL_INVALID_VALUE);
5742 }
5743
5744 if(location == -1)
5745 {
5746 return;
5747 }
5748
5749 es2::Context *context = es2::getContext();
5750
5751 if(context)
5752 {
5753 es2::Program *program = context->getCurrentProgram();
5754
5755 if(!program)
5756 {
5757 return error(GL_INVALID_OPERATION);
5758 }
5759
5760 if(!program->setUniform3iv(location, count, v))
5761 {
5762 return error(GL_INVALID_OPERATION);
5763 }
5764 }
5765}
5766
5767void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5768{
5769 GLfloat xyzw[4] = {x, y, z, w};
5770
5771 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5772}
5773
5774void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
5775{
5776 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5777
5778 if(count < 0)
5779 {
5780 return error(GL_INVALID_VALUE);
5781 }
5782
5783 if(location == -1)
5784 {
5785 return;
5786 }
5787
5788 es2::Context *context = es2::getContext();
5789
5790 if(context)
5791 {
5792 es2::Program *program = context->getCurrentProgram();
5793
5794 if(!program)
5795 {
5796 return error(GL_INVALID_OPERATION);
5797 }
5798
5799 if(!program->setUniform4fv(location, count, v))
5800 {
5801 return error(GL_INVALID_OPERATION);
5802 }
5803 }
5804}
5805
5806void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5807{
5808 GLint xyzw[4] = {x, y, z, w};
5809
5810 glUniform4iv(location, 1, (GLint*)&xyzw);
5811}
5812
5813void Uniform4iv(GLint location, GLsizei count, const GLint* v)
5814{
5815 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5816
5817 if(count < 0)
5818 {
5819 return error(GL_INVALID_VALUE);
5820 }
5821
5822 if(location == -1)
5823 {
5824 return;
5825 }
5826
5827 es2::Context *context = es2::getContext();
5828
5829 if(context)
5830 {
5831 es2::Program *program = context->getCurrentProgram();
5832
5833 if(!program)
5834 {
5835 return error(GL_INVALID_OPERATION);
5836 }
5837
5838 if(!program->setUniform4iv(location, count, v))
5839 {
5840 return error(GL_INVALID_OPERATION);
5841 }
5842 }
5843}
5844
5845void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5846{
5847 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5848 location, count, transpose, value);
5849
5850 if(count < 0)
5851 {
5852 return error(GL_INVALID_VALUE);
5853 }
5854
5855 if(location == -1)
5856 {
5857 return;
5858 }
5859
5860 es2::Context *context = es2::getContext();
5861
5862 if(context)
5863 {
5864 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5865 {
5866 return error(GL_INVALID_VALUE);
5867 }
5868
5869 es2::Program *program = context->getCurrentProgram();
5870
5871 if(!program)
5872 {
5873 return error(GL_INVALID_OPERATION);
5874 }
5875
5876 if(!program->setUniformMatrix2fv(location, count, transpose, value))
5877 {
5878 return error(GL_INVALID_OPERATION);
5879 }
5880 }
5881}
5882
5883void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5884{
5885 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5886 location, count, transpose, value);
5887
5888 if(count < 0)
5889 {
5890 return error(GL_INVALID_VALUE);
5891 }
5892
5893 if(location == -1)
5894 {
5895 return;
5896 }
5897
5898 es2::Context *context = es2::getContext();
5899
5900 if(context)
5901 {
5902 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5903 {
5904 return error(GL_INVALID_VALUE);
5905 }
5906
5907 es2::Program *program = context->getCurrentProgram();
5908
5909 if(!program)
5910 {
5911 return error(GL_INVALID_OPERATION);
5912 }
5913
5914 if(!program->setUniformMatrix3fv(location, count, transpose, value))
5915 {
5916 return error(GL_INVALID_OPERATION);
5917 }
5918 }
5919}
5920
5921void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5922{
5923 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5924 location, count, transpose, value);
5925
5926 if(count < 0)
5927 {
5928 return error(GL_INVALID_VALUE);
5929 }
5930
5931 if(location == -1)
5932 {
5933 return;
5934 }
5935
5936 es2::Context *context = es2::getContext();
5937
5938 if(context)
5939 {
5940 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5941 {
5942 return error(GL_INVALID_VALUE);
5943 }
5944
5945 es2::Program *program = context->getCurrentProgram();
5946
5947 if(!program)
5948 {
5949 return error(GL_INVALID_OPERATION);
5950 }
5951
5952 if(!program->setUniformMatrix4fv(location, count, transpose, value))
5953 {
5954 return error(GL_INVALID_OPERATION);
5955 }
5956 }
5957}
5958
5959void UseProgram(GLuint program)
5960{
5961 TRACE("(GLuint program = %d)", program);
5962
5963 es2::Context *context = es2::getContext();
5964
5965 if(context)
5966 {
5967 es2::Program *programObject = context->getProgram(program);
5968
5969 if(!programObject && program != 0)
5970 {
5971 if(context->getShader(program))
5972 {
5973 return error(GL_INVALID_OPERATION);
5974 }
5975 else
5976 {
5977 return error(GL_INVALID_VALUE);
5978 }
5979 }
5980
5981 if(program != 0 && !programObject->isLinked())
5982 {
5983 return error(GL_INVALID_OPERATION);
5984 }
5985
5986 context->useProgram(program);
5987 }
5988}
5989
5990void ValidateProgram(GLuint program)
5991{
5992 TRACE("(GLuint program = %d)", program);
5993
5994 es2::Context *context = es2::getContext();
5995
5996 if(context)
5997 {
5998 es2::Program *programObject = context->getProgram(program);
5999
6000 if(!programObject)
6001 {
6002 if(context->getShader(program))
6003 {
6004 return error(GL_INVALID_OPERATION);
6005 }
6006 else
6007 {
6008 return error(GL_INVALID_VALUE);
6009 }
6010 }
6011
6012 programObject->validate();
6013 }
6014}
6015
6016void VertexAttrib1f(GLuint index, GLfloat x)
6017{
6018 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
6019
6020 if(index >= es2::MAX_VERTEX_ATTRIBS)
6021 {
6022 return error(GL_INVALID_VALUE);
6023 }
6024
6025 es2::Context *context = es2::getContext();
6026
6027 if(context)
6028 {
6029 GLfloat vals[4] = { x, 0, 0, 1 };
6030 context->setVertexAttrib(index, vals);
6031 }
6032}
6033
6034void VertexAttrib1fv(GLuint index, const GLfloat* values)
6035{
6036 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6037
6038 if(index >= es2::MAX_VERTEX_ATTRIBS)
6039 {
6040 return error(GL_INVALID_VALUE);
6041 }
6042
6043 es2::Context *context = es2::getContext();
6044
6045 if(context)
6046 {
6047 GLfloat vals[4] = { values[0], 0, 0, 1 };
6048 context->setVertexAttrib(index, vals);
6049 }
6050}
6051
6052void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6053{
6054 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
6055
6056 if(index >= es2::MAX_VERTEX_ATTRIBS)
6057 {
6058 return error(GL_INVALID_VALUE);
6059 }
6060
6061 es2::Context *context = es2::getContext();
6062
6063 if(context)
6064 {
6065 GLfloat vals[4] = { x, y, 0, 1 };
6066 context->setVertexAttrib(index, vals);
6067 }
6068}
6069
6070void VertexAttrib2fv(GLuint index, const GLfloat* values)
6071{
6072 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6073
6074 if(index >= es2::MAX_VERTEX_ATTRIBS)
6075 {
6076 return error(GL_INVALID_VALUE);
6077 }
6078
6079 es2::Context *context = es2::getContext();
6080
6081 if(context)
6082 {
6083 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6084 context->setVertexAttrib(index, vals);
6085 }
6086}
6087
6088void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6089{
6090 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
6091
6092 if(index >= es2::MAX_VERTEX_ATTRIBS)
6093 {
6094 return error(GL_INVALID_VALUE);
6095 }
6096
6097 es2::Context *context = es2::getContext();
6098
6099 if(context)
6100 {
6101 GLfloat vals[4] = { x, y, z, 1 };
6102 context->setVertexAttrib(index, vals);
6103 }
6104}
6105
6106void VertexAttrib3fv(GLuint index, const GLfloat* values)
6107{
6108 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6109
6110 if(index >= es2::MAX_VERTEX_ATTRIBS)
6111 {
6112 return error(GL_INVALID_VALUE);
6113 }
6114
6115 es2::Context *context = es2::getContext();
6116
6117 if(context)
6118 {
6119 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6120 context->setVertexAttrib(index, vals);
6121 }
6122}
6123
6124void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6125{
6126 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
6127
6128 if(index >= es2::MAX_VERTEX_ATTRIBS)
6129 {
6130 return error(GL_INVALID_VALUE);
6131 }
6132
6133 es2::Context *context = es2::getContext();
6134
6135 if(context)
6136 {
6137 GLfloat vals[4] = { x, y, z, w };
6138 context->setVertexAttrib(index, vals);
6139 }
6140}
6141
6142void VertexAttrib4fv(GLuint index, const GLfloat* values)
6143{
6144 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6145
6146 if(index >= es2::MAX_VERTEX_ATTRIBS)
6147 {
6148 return error(GL_INVALID_VALUE);
6149 }
6150
6151 es2::Context *context = es2::getContext();
6152
6153 if(context)
6154 {
6155 context->setVertexAttrib(index, values);
6156 }
6157}
6158
6159void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
6160{
6161 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
6162 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
6163 index, size, type, normalized, stride, ptr);
6164
6165 if(index >= es2::MAX_VERTEX_ATTRIBS)
6166 {
6167 return error(GL_INVALID_VALUE);
6168 }
6169
6170 if(size < 1 || size > 4)
6171 {
6172 return error(GL_INVALID_VALUE);
6173 }
6174
6175 GLint clientVersion = egl::getClientVersion();
6176
6177 switch(type)
6178 {
6179 case GL_BYTE:
6180 case GL_UNSIGNED_BYTE:
6181 case GL_SHORT:
6182 case GL_UNSIGNED_SHORT:
6183 case GL_FIXED:
6184 case GL_FLOAT:
6185 break;
6186 case GL_INT_2_10_10_10_REV:
6187 case GL_UNSIGNED_INT_2_10_10_10_REV:
6188 if(clientVersion >= 3)
6189 {
6190 if(size != 4)
6191 {
6192 return error(GL_INVALID_OPERATION);
6193 }
6194 break;
6195 }
6196 else return error(GL_INVALID_ENUM);
6197 case GL_INT:
6198 case GL_UNSIGNED_INT:
6199 case GL_HALF_FLOAT:
6200 if(clientVersion >= 3)
6201 {
6202 break;
6203 }
6204 else return error(GL_INVALID_ENUM);
6205 default:
6206 return error(GL_INVALID_ENUM);
6207 }
6208
6209 if(stride < 0)
6210 {
6211 return error(GL_INVALID_VALUE);
6212 }
6213
6214 es2::Context *context = es2::getContext();
6215
6216 if(context)
6217 {
6218 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6219 }
6220}
6221
6222void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
6223{
6224 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
6225
6226 if(width < 0 || height < 0)
6227 {
6228 return error(GL_INVALID_VALUE);
6229 }
6230
6231 es2::Context *context = es2::getContext();
6232
6233 if(context)
6234 {
6235 context->setViewportParams(x, y, width, height);
6236 }
6237}
6238
Alexis Hetub9dda642016-10-06 11:25:32 -04006239static void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter, bool allowPartialDepthStencilBlit)
Nicolas Capens0bac2852016-05-07 06:09:58 -04006240{
6241 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6242 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6243 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6244 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6245
6246 switch(filter)
6247 {
6248 case GL_NEAREST:
6249 break;
6250 default:
6251 return error(GL_INVALID_ENUM);
6252 }
6253
6254 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6255 {
6256 return error(GL_INVALID_VALUE);
6257 }
6258
6259 es2::Context *context = es2::getContext();
6260
6261 if(context)
6262 {
6263 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
6264 {
6265 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6266 return error(GL_INVALID_OPERATION);
6267 }
6268
Alexis Hetub9dda642016-10-06 11:25:32 -04006269 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, false, allowPartialDepthStencilBlit);
Nicolas Capens0bac2852016-05-07 06:09:58 -04006270 }
6271}
6272
Alexis Hetub9dda642016-10-06 11:25:32 -04006273void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
6274{
6275 BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, true);
6276}
6277
Nicolas Capens0bac2852016-05-07 06:09:58 -04006278void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6279 GLbitfield mask, GLenum filter)
6280{
6281 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6282 {
6283 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6284 return error(GL_INVALID_OPERATION);
6285 }
6286
Alexis Hetub9dda642016-10-06 11:25:32 -04006287 BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, false);
Nicolas Capens0bac2852016-05-07 06:09:58 -04006288}
6289
6290void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Alexis Hetu53f48092016-06-17 14:08:06 -04006291 GLint border, GLenum format, GLenum type, const GLvoid* data)
Nicolas Capens0bac2852016-05-07 06:09:58 -04006292{
6293 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6294 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
Alexis Hetu53f48092016-06-17 14:08:06 -04006295 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
6296 target, level, internalformat, width, height, depth, border, format, type, data);
Nicolas Capens0bac2852016-05-07 06:09:58 -04006297
6298 switch(target)
6299 {
6300 case GL_TEXTURE_3D_OES:
6301 switch(format)
6302 {
6303 case GL_DEPTH_COMPONENT:
6304 case GL_DEPTH_STENCIL_OES:
6305 return error(GL_INVALID_OPERATION);
6306 default:
6307 break;
6308 }
6309 break;
6310 default:
6311 return error(GL_INVALID_ENUM);
6312 }
6313
6314 if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
6315 {
6316 return;
6317 }
6318
6319 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6320 {
6321 return error(GL_INVALID_VALUE);
6322 }
6323
6324 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6325 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6326 {
6327 return error(GL_INVALID_VALUE);
6328 }
6329
6330 if(border != 0)
6331 {
6332 return error(GL_INVALID_VALUE);
6333 }
6334
6335 es2::Context *context = es2::getContext();
6336
6337 if(context)
6338 {
6339 es2::Texture3D *texture = context->getTexture3D();
6340
6341 if(!texture)
6342 {
6343 return error(GL_INVALID_OPERATION);
6344 }
6345
Alexis Hetu53f48092016-06-17 14:08:06 -04006346 texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), context->getPixels(data));
Nicolas Capens0bac2852016-05-07 06:09:58 -04006347 }
6348}
6349
Alexis Hetu53f48092016-06-17 14:08:06 -04006350void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data)
Nicolas Capens0bac2852016-05-07 06:09:58 -04006351{
6352 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6353 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
Alexis Hetu53f48092016-06-17 14:08:06 -04006354 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
6355 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
Nicolas Capens0bac2852016-05-07 06:09:58 -04006356
6357 switch(target)
6358 {
6359 case GL_TEXTURE_3D_OES:
6360 break;
6361 default:
6362 return error(GL_INVALID_ENUM);
6363 }
6364
6365 if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
6366 {
6367 return;
6368 }
6369
6370 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6371 {
6372 return error(GL_INVALID_VALUE);
6373 }
6374
6375 if((width < 0) || (height < 0) || (depth < 0))
6376 {
6377 return error(GL_INVALID_VALUE);
6378 }
6379
6380 es2::Context *context = es2::getContext();
6381
6382 if(context)
6383 {
6384 es2::Texture3D *texture = context->getTexture3D();
6385
6386 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
6387
6388 GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
6389 if(validationError == GL_NONE)
6390 {
Alexis Hetu53f48092016-06-17 14:08:06 -04006391 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
Nicolas Capens0bac2852016-05-07 06:09:58 -04006392 }
6393 else
6394 {
6395 return error(validationError);
6396 }
6397 }
6398}
6399
6400void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
6401{
6402 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6403 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
6404 target, level, xoffset, yoffset, zoffset, x, y, width, height);
6405
6406 switch(target)
6407 {
6408 case GL_TEXTURE_3D_OES:
6409 break;
6410 default:
6411 return error(GL_INVALID_ENUM);
6412 }
6413
6414 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6415 {
6416 return error(GL_INVALID_VALUE);
6417 }
6418
6419 es2::Context *context = es2::getContext();
6420
6421 if(context)
6422 {
6423 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6424
6425 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
6426 {
6427 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6428 }
6429
6430 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
6431
6432 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
6433 {
6434 return error(GL_INVALID_OPERATION);
6435 }
6436
6437 es2::Texture3D *texture = context->getTexture3D();
6438
6439 GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
6440
6441 if(validationError != GL_NONE)
6442 {
6443 return error(validationError);
6444 }
6445
6446 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
6447 }
6448}
6449
6450void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
6451{
6452 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
6453 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
6454 target, level, internalformat, width, height, depth, border, imageSize, data);
6455
6456 switch(target)
6457 {
6458 case GL_TEXTURE_3D_OES:
6459 break;
6460 default:
6461 return error(GL_INVALID_ENUM);
6462 }
6463
6464 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6465 {
6466 return error(GL_INVALID_VALUE);
6467 }
6468
6469 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6470 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6471 {
6472 return error(GL_INVALID_VALUE);
6473 }
6474
6475 switch(internalformat)
6476 {
6477 case GL_DEPTH_COMPONENT:
6478 case GL_DEPTH_COMPONENT16:
6479 case GL_DEPTH_COMPONENT32_OES:
6480 case GL_DEPTH_STENCIL_OES:
6481 case GL_DEPTH24_STENCIL8_OES:
6482 return error(GL_INVALID_OPERATION);
6483 default:
6484 {
6485 GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
6486 if(validationError != GL_NONE)
6487 {
6488 return error(validationError);
6489 }
6490 }
6491 }
6492
6493 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
6494 {
6495 return error(GL_INVALID_VALUE);
6496 }
6497
6498 es2::Context *context = es2::getContext();
6499
6500 if(context)
6501 {
6502 es2::Texture3D *texture = context->getTexture3D();
6503
6504 if(!texture)
6505 {
6506 return error(GL_INVALID_OPERATION);
6507 }
6508
6509 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
6510 }
6511}
6512
6513void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
6514{
6515 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6516 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6517 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
6518 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6519
6520 switch(target)
6521 {
6522 case GL_TEXTURE_3D_OES:
6523 break;
6524 default:
6525 return error(GL_INVALID_ENUM);
6526 }
6527
6528 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6529 {
6530 return error(GL_INVALID_VALUE);
6531 }
6532
6533 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6534 {
6535 return error(GL_INVALID_VALUE);
6536 }
6537
6538 GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
6539 if(validationError != GL_NONE)
6540 {
6541 return error(validationError);
6542 }
6543
6544 if(width == 0 || height == 0 || depth == 0 || !data)
6545 {
6546 return;
6547 }
6548
6549 es2::Context *context = es2::getContext();
6550
6551 if(context)
6552 {
6553 es2::Texture3D *texture = context->getTexture3D();
6554
6555 if(!texture)
6556 {
6557 return error(GL_INVALID_OPERATION);
6558 }
6559
Alexis Hetu53f48092016-06-17 14:08:06 -04006560 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, context->getPixels(data));
Nicolas Capens0bac2852016-05-07 06:09:58 -04006561 }
6562}
6563
6564void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
6565{
6566 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6567 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6568
6569 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
6570 {
6571 return error(GL_INVALID_ENUM);
6572 }
6573
6574 es2::Context *context = es2::getContext();
6575
6576 if(context)
6577 {
6578 if(texture == 0)
6579 {
6580 textarget = GL_NONE;
6581 }
6582 else
6583 {
6584 es2::Texture *tex = context->getTexture(texture);
6585
6586 if(!tex)
6587 {
6588 return error(GL_INVALID_OPERATION);
6589 }
6590
6591 if(tex->isCompressed(textarget, level))
6592 {
6593 return error(GL_INVALID_OPERATION);
6594 }
6595
6596 switch(textarget)
6597 {
6598 case GL_TEXTURE_3D_OES:
6599 if(tex->getTarget() != GL_TEXTURE_3D_OES)
6600 {
6601 return error(GL_INVALID_OPERATION);
6602 }
6603 break;
6604 default:
6605 return error(GL_INVALID_ENUM);
6606 }
6607
6608 if(level != 0)
6609 {
6610 return error(GL_INVALID_VALUE);
6611 }
6612 }
6613
6614 es2::Framebuffer *framebuffer = nullptr;
6615 GLuint framebufferName = 0;
6616 if(target == GL_READ_FRAMEBUFFER_ANGLE)
6617 {
6618 framebuffer = context->getReadFramebuffer();
6619 framebufferName = context->getReadFramebufferName();
6620 }
6621 else
6622 {
6623 framebuffer = context->getDrawFramebuffer();
6624 framebufferName = context->getDrawFramebufferName();
6625 }
6626
6627 if(framebufferName == 0 || !framebuffer)
6628 {
6629 return error(GL_INVALID_OPERATION);
6630 }
6631
6632 GLint clientVersion = context->getClientVersion();
6633
6634 switch(attachment)
6635 {
6636 case GL_COLOR_ATTACHMENT1:
6637 case GL_COLOR_ATTACHMENT2:
6638 case GL_COLOR_ATTACHMENT3:
6639 case GL_COLOR_ATTACHMENT4:
6640 case GL_COLOR_ATTACHMENT5:
6641 case GL_COLOR_ATTACHMENT6:
6642 case GL_COLOR_ATTACHMENT7:
6643 case GL_COLOR_ATTACHMENT8:
6644 case GL_COLOR_ATTACHMENT9:
6645 case GL_COLOR_ATTACHMENT10:
6646 case GL_COLOR_ATTACHMENT11:
6647 case GL_COLOR_ATTACHMENT12:
6648 case GL_COLOR_ATTACHMENT13:
6649 case GL_COLOR_ATTACHMENT14:
6650 case GL_COLOR_ATTACHMENT15:
6651 case GL_COLOR_ATTACHMENT16:
6652 case GL_COLOR_ATTACHMENT17:
6653 case GL_COLOR_ATTACHMENT18:
6654 case GL_COLOR_ATTACHMENT19:
6655 case GL_COLOR_ATTACHMENT20:
6656 case GL_COLOR_ATTACHMENT21:
6657 case GL_COLOR_ATTACHMENT22:
6658 case GL_COLOR_ATTACHMENT23:
6659 case GL_COLOR_ATTACHMENT24:
6660 case GL_COLOR_ATTACHMENT25:
6661 case GL_COLOR_ATTACHMENT26:
6662 case GL_COLOR_ATTACHMENT27:
6663 case GL_COLOR_ATTACHMENT28:
6664 case GL_COLOR_ATTACHMENT29:
6665 case GL_COLOR_ATTACHMENT30:
6666 case GL_COLOR_ATTACHMENT31:
6667 if(clientVersion < 3)
6668 {
6669 return error(GL_INVALID_ENUM);
6670 }
6671 // fall through
6672 case GL_COLOR_ATTACHMENT0:
6673 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
6674 {
6675 return error(GL_INVALID_ENUM);
6676 }
6677 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
6678 break;
6679 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
6680 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6681 default:
6682 return error(GL_INVALID_ENUM);
6683 }
6684 }
6685}
6686
6687void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
6688{
6689 if(egl::getClientVersion() == 1)
6690 {
6691 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
6692 }
6693
6694 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6695
6696 switch(target)
6697 {
6698 case GL_TEXTURE_2D:
6699 case GL_TEXTURE_EXTERNAL_OES:
6700 break;
6701 default:
6702 return error(GL_INVALID_ENUM);
6703 }
6704
Nicolas Capens0bac2852016-05-07 06:09:58 -04006705 es2::Context *context = es2::getContext();
6706
6707 if(context)
6708 {
Nicolas Capens58df2f62016-06-07 14:48:56 -04006709 es2::Texture2D *texture = nullptr;
Nicolas Capens0bac2852016-05-07 06:09:58 -04006710
6711 switch(target)
6712 {
6713 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
6714 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
6715 default: UNREACHABLE(target);
6716 }
6717
6718 if(!texture)
6719 {
6720 return error(GL_INVALID_OPERATION);
6721 }
6722
Nicolas Capens58df2f62016-06-07 14:48:56 -04006723 egl::Image *eglImage = context->getSharedImage(image);
Nicolas Capens0bac2852016-05-07 06:09:58 -04006724
Nicolas Capens58df2f62016-06-07 14:48:56 -04006725 if(!eglImage)
6726 {
6727 return error(GL_INVALID_OPERATION);
6728 }
6729
6730 texture->setSharedImage(eglImage);
Nicolas Capens0bac2852016-05-07 06:09:58 -04006731 }
6732}
6733
6734void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
6735{
6736 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6737
6738 UNIMPLEMENTED();
6739}
6740
6741GLboolean IsRenderbufferOES(GLuint renderbuffer)
6742{
6743 return IsRenderbuffer(renderbuffer);
6744}
6745
6746void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
6747{
6748 BindRenderbuffer(target, renderbuffer);
6749}
6750
6751void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
6752{
6753 DeleteRenderbuffers(n, renderbuffers);
6754}
6755
6756void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
6757{
6758 GenRenderbuffers(n, renderbuffers);
6759}
6760
6761void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
6762{
6763 RenderbufferStorage(target, internalformat, width, height);
6764}
6765
6766void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
6767{
6768 GetRenderbufferParameteriv(target, pname, params);
6769}
6770
6771GLboolean IsFramebufferOES(GLuint framebuffer)
6772{
6773 return IsFramebuffer(framebuffer);
6774}
6775
6776void BindFramebufferOES(GLenum target, GLuint framebuffer)
6777{
6778 BindFramebuffer(target, framebuffer);
6779}
6780
6781void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
6782{
6783 DeleteFramebuffers(n, framebuffers);
6784}
6785
6786void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
6787{
6788 GenFramebuffers(n, framebuffers);
6789}
6790
6791GLenum CheckFramebufferStatusOES(GLenum target)
6792{
6793 return CheckFramebufferStatus(target);
6794}
6795
6796void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
6797{
6798 FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
6799}
6800
6801void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
6802{
6803 FramebufferTexture2D(target, attachment, textarget, texture, level);
6804}
6805
6806void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
6807{
6808 GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
6809}
6810
6811void GenerateMipmapOES(GLenum target)
6812{
6813 GenerateMipmap(target);
6814}
6815
6816void DrawBuffersEXT(GLsizei n, const GLenum *bufs)
6817{
6818 TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);
6819
6820 if(n < 0 || n > MAX_DRAW_BUFFERS)
6821 {
6822 return error(GL_INVALID_VALUE);
6823 }
6824
6825 es2::Context *context = es2::getContext();
6826
6827 if(context)
6828 {
6829 GLuint drawFramebufferName = context->getDrawFramebufferName();
6830
6831 if((drawFramebufferName == 0) && (n != 1))
6832 {
6833 return error(GL_INVALID_OPERATION);
6834 }
6835
6836 for(unsigned int i = 0; i < (unsigned)n; i++)
6837 {
6838 switch(bufs[i])
6839 {
6840 case GL_BACK:
6841 if(drawFramebufferName != 0)
6842 {
6843 return error(GL_INVALID_OPERATION);
6844 }
6845 break;
6846 case GL_NONE:
6847 break;
6848 case GL_COLOR_ATTACHMENT0_EXT:
6849 case GL_COLOR_ATTACHMENT1_EXT:
6850 case GL_COLOR_ATTACHMENT2_EXT:
6851 case GL_COLOR_ATTACHMENT3_EXT:
6852 case GL_COLOR_ATTACHMENT4_EXT:
6853 case GL_COLOR_ATTACHMENT5_EXT:
6854 case GL_COLOR_ATTACHMENT6_EXT:
6855 case GL_COLOR_ATTACHMENT7_EXT:
6856 case GL_COLOR_ATTACHMENT8_EXT:
6857 case GL_COLOR_ATTACHMENT9_EXT:
6858 case GL_COLOR_ATTACHMENT10_EXT:
6859 case GL_COLOR_ATTACHMENT11_EXT:
6860 case GL_COLOR_ATTACHMENT12_EXT:
6861 case GL_COLOR_ATTACHMENT13_EXT:
6862 case GL_COLOR_ATTACHMENT14_EXT:
6863 case GL_COLOR_ATTACHMENT15_EXT:
6864 {
6865 GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0_EXT);
6866
6867 if(index >= MAX_COLOR_ATTACHMENTS)
6868 {
6869 return error(GL_INVALID_OPERATION);
6870 }
6871
6872 if(index != i)
6873 {
6874 return error(GL_INVALID_OPERATION);
6875 }
6876
6877 if(drawFramebufferName == 0)
6878 {
6879 return error(GL_INVALID_OPERATION);
6880 }
6881 }
6882 break;
6883 default:
6884 return error(GL_INVALID_ENUM);
6885 }
6886 }
6887
6888 context->setFramebufferDrawBuffers(n, bufs);
6889 }
6890}
6891
6892}
6893
6894extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
6895{
6896 struct Extension
6897 {
6898 const char *name;
6899 __eglMustCastToProperFunctionPointerType address;
6900 };
6901
6902 static const Extension glExtensions[] =
6903 {
6904 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6905
6906 EXTENSION(glTexImage3DOES),
6907 EXTENSION(glBlitFramebufferANGLE),
6908 EXTENSION(glBlitFramebufferNV),
6909 EXTENSION(glRenderbufferStorageMultisampleANGLE),
6910 EXTENSION(glDeleteFencesNV),
6911 EXTENSION(glGenFencesNV),
6912 EXTENSION(glIsFenceNV),
6913 EXTENSION(glTestFenceNV),
6914 EXTENSION(glGetFenceivNV),
6915 EXTENSION(glFinishFenceNV),
6916 EXTENSION(glSetFenceNV),
6917 EXTENSION(glGetGraphicsResetStatusEXT),
6918 EXTENSION(glReadnPixelsEXT),
6919 EXTENSION(glGetnUniformfvEXT),
6920 EXTENSION(glGetnUniformivEXT),
6921 EXTENSION(glGenQueriesEXT),
6922 EXTENSION(glDeleteQueriesEXT),
6923 EXTENSION(glIsQueryEXT),
6924 EXTENSION(glBeginQueryEXT),
6925 EXTENSION(glEndQueryEXT),
6926 EXTENSION(glGetQueryivEXT),
6927 EXTENSION(glGetQueryObjectuivEXT),
6928 EXTENSION(glEGLImageTargetTexture2DOES),
6929 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
6930 EXTENSION(glDrawElementsInstancedEXT),
6931 EXTENSION(glDrawArraysInstancedEXT),
6932 EXTENSION(glVertexAttribDivisorEXT),
6933 EXTENSION(glDrawArraysInstancedANGLE),
6934 EXTENSION(glDrawElementsInstancedANGLE),
6935 EXTENSION(glVertexAttribDivisorANGLE),
6936 EXTENSION(glIsRenderbufferOES),
6937 EXTENSION(glBindRenderbufferOES),
6938 EXTENSION(glDeleteRenderbuffersOES),
6939 EXTENSION(glGenRenderbuffersOES),
6940 EXTENSION(glRenderbufferStorageOES),
6941 EXTENSION(glGetRenderbufferParameterivOES),
6942 EXTENSION(glIsFramebufferOES),
6943 EXTENSION(glBindFramebufferOES),
6944 EXTENSION(glDeleteFramebuffersOES),
6945 EXTENSION(glGenFramebuffersOES),
6946 EXTENSION(glCheckFramebufferStatusOES),
6947 EXTENSION(glFramebufferRenderbufferOES),
6948 EXTENSION(glFramebufferTexture2DOES),
6949 EXTENSION(glGetFramebufferAttachmentParameterivOES),
6950 EXTENSION(glGenerateMipmapOES),
6951 EXTENSION(glDrawBuffersEXT),
6952
6953 #undef EXTENSION
6954 };
6955
6956 for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6957 {
6958 if(strcmp(procname, glExtensions[ext].name) == 0)
6959 {
6960 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6961 }
6962 }
6963
6964 return nullptr;
6965}