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