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