1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "utilities.h"
22 #include "Framebuffer.h"
24 #include "Renderbuffer.h"
28 #include "TransformFeedback.h"
29 #include "VertexArray.h"
30 #include "common/debug.h"
31 #include "Common/Version.h"
33 #include <GLES2/gl2.h>
34 #include <GLES2/gl2ext.h>
35 #include <GLES3/gl3.h>
40 #include <cutils/log.h>
46 static bool validImageSize(GLint level, GLsizei width, GLsizei height)
48 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
56 static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
58 GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);
59 if(validationError != GL_NONE)
61 return error(validationError, false);
64 // [OpenGL ES 2.0.24] table 3.9
68 if(colorbufferFormat != GL_ALPHA &&
69 colorbufferFormat != GL_RGBA &&
70 colorbufferFormat != GL_RGBA4 &&
71 colorbufferFormat != GL_RGB5_A1 &&
72 colorbufferFormat != GL_RGBA8_OES &&
73 colorbufferFormat != GL_BGRA8_EXT &&
74 colorbufferFormat != GL_RGBA16F_EXT &&
75 colorbufferFormat != GL_RGBA32F_EXT)
77 return error(GL_INVALID_OPERATION, false);
82 if(colorbufferFormat != GL_RGB &&
83 colorbufferFormat != GL_RGB565 &&
84 colorbufferFormat != GL_RGB8_OES &&
85 colorbufferFormat != GL_RGBA &&
86 colorbufferFormat != GL_RGBA4 &&
87 colorbufferFormat != GL_RGB5_A1 &&
88 colorbufferFormat != GL_RGBA8_OES &&
89 colorbufferFormat != GL_RGB16F_EXT &&
90 colorbufferFormat != GL_RGB32F_EXT &&
91 colorbufferFormat != GL_BGRA8_EXT &&
92 colorbufferFormat != GL_RGBA16F_EXT &&
93 colorbufferFormat != GL_RGBA32F_EXT)
95 return error(GL_INVALID_OPERATION, false);
98 case GL_LUMINANCE_ALPHA:
100 if(colorbufferFormat != GL_RGBA &&
101 colorbufferFormat != GL_RGBA4 &&
102 colorbufferFormat != GL_RGB5_A1 &&
103 colorbufferFormat != GL_RGBA8_OES &&
104 colorbufferFormat != GL_BGRA8_EXT &&
105 colorbufferFormat != GL_RGBA16F_EXT &&
106 colorbufferFormat != GL_RGBA32F_EXT)
108 return error(GL_INVALID_OPERATION, false);
111 case GL_DEPTH_COMPONENT:
112 case GL_DEPTH_STENCIL_OES:
113 return error(GL_INVALID_OPERATION, false);
115 return error(GL_INVALID_ENUM, false);
120 void ActiveTexture(GLenum texture)
122 TRACE("(GLenum texture = 0x%X)", texture);
124 es2::Context *context = es2::getContext();
128 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
130 return error(GL_INVALID_ENUM);
133 context->setActiveSampler(texture - GL_TEXTURE0);
137 void AttachShader(GLuint program, GLuint shader)
139 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
141 es2::Context *context = es2::getContext();
145 es2::Program *programObject = context->getProgram(program);
146 es2::Shader *shaderObject = context->getShader(shader);
150 if(context->getShader(program))
152 return error(GL_INVALID_OPERATION);
156 return error(GL_INVALID_VALUE);
162 if(context->getProgram(shader))
164 return error(GL_INVALID_OPERATION);
168 return error(GL_INVALID_VALUE);
172 if(!programObject->attachShader(shaderObject))
174 return error(GL_INVALID_OPERATION);
179 void BeginQueryEXT(GLenum target, GLuint name)
181 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
185 case GL_ANY_SAMPLES_PASSED_EXT:
186 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
189 return error(GL_INVALID_ENUM);
194 return error(GL_INVALID_OPERATION);
197 es2::Context *context = es2::getContext();
201 context->beginQuery(target, name);
205 void BindAttribLocation(GLuint program, GLuint index, const GLchar* name)
207 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
209 if(index >= es2::MAX_VERTEX_ATTRIBS)
211 return error(GL_INVALID_VALUE);
214 es2::Context *context = es2::getContext();
218 es2::Program *programObject = context->getProgram(program);
222 if(context->getShader(program))
224 return error(GL_INVALID_OPERATION);
228 return error(GL_INVALID_VALUE);
232 if(strncmp(name, "gl_", 3) == 0)
234 return error(GL_INVALID_OPERATION);
237 programObject->bindAttributeLocation(index, name);
241 void BindBuffer(GLenum target, GLuint buffer)
243 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
245 es2::Context *context = es2::getContext();
249 GLint clientVersion = egl::getClientVersion();
253 case GL_ARRAY_BUFFER:
254 context->bindArrayBuffer(buffer);
256 case GL_ELEMENT_ARRAY_BUFFER:
257 context->bindElementArrayBuffer(buffer);
259 case GL_COPY_READ_BUFFER:
260 if(clientVersion >= 3)
262 context->bindCopyReadBuffer(buffer);
265 else return error(GL_INVALID_ENUM);
266 case GL_COPY_WRITE_BUFFER:
267 if(clientVersion >= 3)
269 context->bindCopyWriteBuffer(buffer);
272 else return error(GL_INVALID_ENUM);
273 case GL_PIXEL_PACK_BUFFER:
274 if(clientVersion >= 3)
276 context->bindPixelPackBuffer(buffer);
279 else return error(GL_INVALID_ENUM);
280 case GL_PIXEL_UNPACK_BUFFER:
281 if(clientVersion >= 3)
283 context->bindPixelUnpackBuffer(buffer);
286 else return error(GL_INVALID_ENUM);
287 case GL_TRANSFORM_FEEDBACK_BUFFER:
288 if(clientVersion >= 3)
290 context->bindTransformFeedbackBuffer(buffer);
293 else return error(GL_INVALID_ENUM);
294 case GL_UNIFORM_BUFFER:
295 if(clientVersion >= 3)
297 context->bindGenericUniformBuffer(buffer);
300 else return error(GL_INVALID_ENUM);
302 return error(GL_INVALID_ENUM);
307 void BindFramebuffer(GLenum target, GLuint framebuffer)
309 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
311 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
313 return error(GL_INVALID_ENUM);
316 es2::Context *context = es2::getContext();
320 if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
322 context->bindReadFramebuffer(framebuffer);
325 if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
327 context->bindDrawFramebuffer(framebuffer);
332 void BindRenderbuffer(GLenum target, GLuint renderbuffer)
334 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
336 if(target != GL_RENDERBUFFER)
338 return error(GL_INVALID_ENUM);
341 es2::Context *context = es2::getContext();
345 // [OpenGL ES 2.0.25] Section 4.4.3 page 110
346 // [OpenGL ES 3.0.4] Section 4.4.2 page 204
347 // If renderbuffer is not zero, then the resulting renderbuffer object
348 // is a new state vector, initialized with a zero-sized memory buffer.
349 context->bindRenderbuffer(renderbuffer);
353 void BindTexture(GLenum target, GLuint texture)
355 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
357 es2::Context *context = es2::getContext();
361 es2::Texture *textureObject = context->getTexture(texture);
363 if(textureObject && textureObject->getTarget() != target && texture != 0)
365 return error(GL_INVALID_OPERATION);
368 GLint clientVersion = context->getClientVersion();
373 context->bindTexture2D(texture);
375 case GL_TEXTURE_CUBE_MAP:
376 context->bindTextureCubeMap(texture);
378 case GL_TEXTURE_EXTERNAL_OES:
379 context->bindTextureExternal(texture);
381 case GL_TEXTURE_2D_ARRAY:
382 if(clientVersion < 3)
384 return error(GL_INVALID_ENUM);
386 context->bindTexture2DArray(texture);
388 case GL_TEXTURE_3D_OES:
389 context->bindTexture3D(texture);
392 return error(GL_INVALID_ENUM);
397 void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
399 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
400 red, green, blue, alpha);
402 es2::Context* context = es2::getContext();
406 context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));
410 void BlendEquation(GLenum mode)
412 glBlendEquationSeparate(mode, mode);
415 void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
417 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
422 case GL_FUNC_SUBTRACT:
423 case GL_FUNC_REVERSE_SUBTRACT:
428 return error(GL_INVALID_ENUM);
434 case GL_FUNC_SUBTRACT:
435 case GL_FUNC_REVERSE_SUBTRACT:
440 return error(GL_INVALID_ENUM);
443 es2::Context *context = es2::getContext();
447 context->setBlendEquation(modeRGB, modeAlpha);
451 void BlendFunc(GLenum sfactor, GLenum dfactor)
453 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
456 void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
458 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
459 srcRGB, dstRGB, srcAlpha, dstAlpha);
461 GLint clientVersion = egl::getClientVersion();
468 case GL_ONE_MINUS_SRC_COLOR:
470 case GL_ONE_MINUS_DST_COLOR:
472 case GL_ONE_MINUS_SRC_ALPHA:
474 case GL_ONE_MINUS_DST_ALPHA:
475 case GL_CONSTANT_COLOR:
476 case GL_ONE_MINUS_CONSTANT_COLOR:
477 case GL_CONSTANT_ALPHA:
478 case GL_ONE_MINUS_CONSTANT_ALPHA:
479 case GL_SRC_ALPHA_SATURATE:
482 return error(GL_INVALID_ENUM);
490 case GL_ONE_MINUS_SRC_COLOR:
492 case GL_ONE_MINUS_DST_COLOR:
494 case GL_ONE_MINUS_SRC_ALPHA:
496 case GL_ONE_MINUS_DST_ALPHA:
497 case GL_CONSTANT_COLOR:
498 case GL_ONE_MINUS_CONSTANT_COLOR:
499 case GL_CONSTANT_ALPHA:
500 case GL_ONE_MINUS_CONSTANT_ALPHA:
502 case GL_SRC_ALPHA_SATURATE:
503 if(clientVersion < 3)
505 return error(GL_INVALID_ENUM);
509 return error(GL_INVALID_ENUM);
517 case GL_ONE_MINUS_SRC_COLOR:
519 case GL_ONE_MINUS_DST_COLOR:
521 case GL_ONE_MINUS_SRC_ALPHA:
523 case GL_ONE_MINUS_DST_ALPHA:
524 case GL_CONSTANT_COLOR:
525 case GL_ONE_MINUS_CONSTANT_COLOR:
526 case GL_CONSTANT_ALPHA:
527 case GL_ONE_MINUS_CONSTANT_ALPHA:
528 case GL_SRC_ALPHA_SATURATE:
531 return error(GL_INVALID_ENUM);
539 case GL_ONE_MINUS_SRC_COLOR:
541 case GL_ONE_MINUS_DST_COLOR:
543 case GL_ONE_MINUS_SRC_ALPHA:
545 case GL_ONE_MINUS_DST_ALPHA:
546 case GL_CONSTANT_COLOR:
547 case GL_ONE_MINUS_CONSTANT_COLOR:
548 case GL_CONSTANT_ALPHA:
549 case GL_ONE_MINUS_CONSTANT_ALPHA:
551 case GL_SRC_ALPHA_SATURATE:
552 if(clientVersion < 3)
554 return error(GL_INVALID_ENUM);
558 return error(GL_INVALID_ENUM);
561 es2::Context *context = es2::getContext();
565 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
569 void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
571 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
573 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
574 target, size, data, usage);
578 return error(GL_INVALID_VALUE);
581 GLint clientVersion = egl::getClientVersion();
587 case GL_DYNAMIC_DRAW:
593 case GL_DYNAMIC_READ:
594 case GL_DYNAMIC_COPY:
595 if(clientVersion < 3)
597 return error(GL_INVALID_ENUM);
601 return error(GL_INVALID_ENUM);
604 es2::Context *context = es2::getContext();
608 es2::Buffer *buffer = nullptr;
609 if(!context->getBuffer(target, &buffer))
611 return error(GL_INVALID_ENUM);
616 // A null buffer means that "0" is bound to the requested buffer target
617 return error(GL_INVALID_OPERATION);
620 buffer->bufferData(data, size, usage);
624 void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
626 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
627 offset = static_cast<GLint>(offset);
629 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
630 target, offset, size, data);
632 if(size < 0 || offset < 0)
634 return error(GL_INVALID_VALUE);
637 es2::Context *context = es2::getContext();
641 es2::Buffer *buffer = nullptr;
642 if(!context->getBuffer(target, &buffer))
644 return error(GL_INVALID_ENUM);
649 // A null buffer means that "0" is bound to the requested buffer target
650 return error(GL_INVALID_OPERATION);
653 if(buffer->isMapped())
655 // It is an invalid operation to update an already mapped buffer
656 return error(GL_INVALID_OPERATION);
659 if((size_t)size + offset > buffer->size())
661 return error(GL_INVALID_VALUE);
664 buffer->bufferSubData(data, size, offset);
668 GLenum CheckFramebufferStatus(GLenum target)
670 TRACE("(GLenum target = 0x%X)", target);
672 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
674 return error(GL_INVALID_ENUM, 0);
677 es2::Context *context = es2::getContext();
681 es2::Framebuffer *framebuffer = nullptr;
682 if(target == GL_READ_FRAMEBUFFER_ANGLE)
684 framebuffer = context->getReadFramebuffer();
688 framebuffer = context->getDrawFramebuffer();
691 return framebuffer->completeness();
697 void Clear(GLbitfield mask)
699 TRACE("(GLbitfield mask = %X)", mask);
701 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
703 return error(GL_INVALID_VALUE);
706 es2::Context *context = es2::getContext();
710 context->clear(mask);
714 void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
716 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
717 red, green, blue, alpha);
719 es2::Context *context = es2::getContext();
723 context->setClearColor(red, green, blue, alpha);
727 void ClearDepthf(GLclampf depth)
729 TRACE("(GLclampf depth = %f)", depth);
731 es2::Context *context = es2::getContext();
735 context->setClearDepth(depth);
739 void ClearStencil(GLint s)
741 TRACE("(GLint s = %d)", s);
743 es2::Context *context = es2::getContext();
747 context->setClearStencil(s);
751 void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
753 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
754 red, green, blue, alpha);
756 es2::Context *context = es2::getContext();
760 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
764 void CompileShader(GLuint shader)
766 TRACE("(GLuint shader = %d)", shader);
768 es2::Context *context = es2::getContext();
772 es2::Shader *shaderObject = context->getShader(shader);
776 if(context->getProgram(shader))
778 return error(GL_INVALID_OPERATION);
782 return error(GL_INVALID_VALUE);
786 shaderObject->compile();
790 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
791 GLint border, GLsizei imageSize, const GLvoid* data)
793 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
794 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
795 target, level, internalformat, width, height, border, imageSize, data);
797 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
799 return error(GL_INVALID_VALUE);
802 switch(internalformat)
804 case GL_DEPTH_COMPONENT:
805 case GL_DEPTH_COMPONENT16:
806 case GL_DEPTH_COMPONENT32_OES:
807 case GL_DEPTH_STENCIL_OES:
808 case GL_DEPTH24_STENCIL8_OES:
809 return error(GL_INVALID_OPERATION);
812 GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
813 if(validationError != GL_NONE)
815 return error(validationError);
823 return error(GL_INVALID_VALUE);
826 es2::Context *context = es2::getContext();
830 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
832 return error(GL_INVALID_VALUE);
838 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
839 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
841 return error(GL_INVALID_VALUE);
844 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
845 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
846 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
847 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
848 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
849 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
852 return error(GL_INVALID_VALUE);
855 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
856 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
858 return error(GL_INVALID_VALUE);
862 return error(GL_INVALID_ENUM);
865 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
867 return error(GL_INVALID_VALUE);
870 if(target == GL_TEXTURE_2D)
872 es2::Texture2D *texture = context->getTexture2D();
876 return error(GL_INVALID_OPERATION);
879 GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
880 if(validationError != GL_NONE)
882 return error(validationError);
885 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
889 es2::TextureCubeMap *texture = context->getTextureCubeMap();
893 return error(GL_INVALID_OPERATION);
898 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
899 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
900 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
901 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
902 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
903 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
906 GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
907 if(validationError != GL_NONE)
909 return error(validationError);
912 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
915 default: UNREACHABLE(target);
921 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
922 GLenum format, GLsizei imageSize, const GLvoid* data)
924 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
925 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
926 "GLsizei imageSize = %d, const GLvoid* data = %p)",
927 target, level, xoffset, yoffset, width, height, format, imageSize, data);
929 if(!es2::IsTextureTarget(target))
931 return error(GL_INVALID_ENUM);
934 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
936 return error(GL_INVALID_VALUE);
939 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
941 return error(GL_INVALID_VALUE);
944 GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
945 if(validationError != GL_NONE)
947 return error(validationError);
950 if(width == 0 || height == 0)
955 es2::Context *context = es2::getContext();
959 if(imageSize != egl::ComputeCompressedSize(width, height, format))
961 return error(GL_INVALID_VALUE);
964 if(xoffset % 4 != 0 || yoffset % 4 != 0)
966 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
967 return error(GL_INVALID_OPERATION);
970 GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);
972 if(target == GL_TEXTURE_2D)
974 es2::Texture2D *texture = context->getTexture2D();
976 GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
978 if(validationError == GL_NONE)
980 validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
983 if(validationError == GL_NONE)
985 texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
989 return error(validationError);
992 else if(es2::IsCubemapTextureTarget(target))
994 es2::TextureCubeMap *texture = context->getTextureCubeMap();
996 GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
998 if(validationError == GL_NONE)
1000 validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
1003 if(validationError == GL_NONE)
1005 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
1009 return error(validationError);
1012 else UNREACHABLE(target);
1016 void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1018 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
1019 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
1020 target, level, internalformat, x, y, width, height, border);
1022 if(!validImageSize(level, width, height))
1024 return error(GL_INVALID_VALUE);
1029 return error(GL_INVALID_VALUE);
1032 es2::Context *context = es2::getContext();
1039 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1040 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
1042 return error(GL_INVALID_VALUE);
1045 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1046 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1047 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1048 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1049 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1050 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1053 return error(GL_INVALID_VALUE);
1056 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1057 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1059 return error(GL_INVALID_VALUE);
1063 return error(GL_INVALID_ENUM);
1066 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
1068 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1070 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1073 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
1075 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
1077 return error(GL_INVALID_OPERATION);
1080 GLenum colorbufferFormat = source->getFormat();
1082 if(!validateColorBufferFormat(internalformat, colorbufferFormat))
1087 if(target == GL_TEXTURE_2D)
1089 es2::Texture2D *texture = context->getTexture2D();
1093 return error(GL_INVALID_OPERATION);
1096 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1098 else if(es2::IsCubemapTextureTarget(target))
1100 es2::TextureCubeMap *texture = context->getTextureCubeMap();
1104 return error(GL_INVALID_OPERATION);
1107 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1109 else UNREACHABLE(target);
1113 void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1115 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1116 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1117 target, level, xoffset, yoffset, x, y, width, height);
1119 if(!es2::IsTextureTarget(target))
1121 return error(GL_INVALID_ENUM);
1124 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1126 return error(GL_INVALID_VALUE);
1129 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1131 return error(GL_INVALID_VALUE);
1134 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1136 return error(GL_INVALID_VALUE);
1139 if(width == 0 || height == 0)
1144 es2::Context *context = es2::getContext();
1148 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
1150 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1152 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1155 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
1157 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
1159 return error(GL_INVALID_OPERATION);
1162 es2::Texture *texture = nullptr;
1164 if(target == GL_TEXTURE_2D)
1166 texture = context->getTexture2D();
1168 else if(es2::IsCubemapTextureTarget(target))
1170 texture = context->getTextureCubeMap();
1172 else UNREACHABLE(target);
1174 GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);
1175 if(validationError != GL_NONE)
1177 return error(validationError);
1180 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
1184 GLuint CreateProgram(void)
1188 es2::Context *context = es2::getContext();
1192 return context->createProgram();
1198 GLuint CreateShader(GLenum type)
1200 TRACE("(GLenum type = 0x%X)", type);
1202 es2::Context *context = es2::getContext();
1208 case GL_FRAGMENT_SHADER:
1209 case GL_VERTEX_SHADER:
1210 return context->createShader(type);
1212 return error(GL_INVALID_ENUM, 0);
1219 void CullFace(GLenum mode)
1221 TRACE("(GLenum mode = 0x%X)", mode);
1227 case GL_FRONT_AND_BACK:
1229 es2::Context *context = es2::getContext();
1233 context->setCullMode(mode);
1238 return error(GL_INVALID_ENUM);
1242 void DeleteBuffers(GLsizei n, const GLuint* buffers)
1244 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
1248 return error(GL_INVALID_VALUE);
1251 es2::Context *context = es2::getContext();
1255 for(int i = 0; i < n; i++)
1257 context->deleteBuffer(buffers[i]);
1262 void DeleteFencesNV(GLsizei n, const GLuint* fences)
1264 TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
1268 return error(GL_INVALID_VALUE);
1271 es2::Context *context = es2::getContext();
1275 for(int i = 0; i < n; i++)
1277 context->deleteFence(fences[i]);
1282 void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1284 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
1288 return error(GL_INVALID_VALUE);
1291 es2::Context *context = es2::getContext();
1295 for(int i = 0; i < n; i++)
1297 if(framebuffers[i] != 0)
1299 context->deleteFramebuffer(framebuffers[i]);
1305 void DeleteProgram(GLuint program)
1307 TRACE("(GLuint program = %d)", program);
1314 es2::Context *context = es2::getContext();
1318 if(!context->getProgram(program))
1320 if(context->getShader(program))
1322 return error(GL_INVALID_OPERATION);
1326 return error(GL_INVALID_VALUE);
1330 context->deleteProgram(program);
1334 void DeleteQueriesEXT(GLsizei n, const GLuint *ids)
1336 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
1340 return error(GL_INVALID_VALUE);
1343 es2::Context *context = es2::getContext();
1347 for(int i = 0; i < n; i++)
1349 context->deleteQuery(ids[i]);
1354 void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1356 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
1360 return error(GL_INVALID_VALUE);
1363 es2::Context *context = es2::getContext();
1367 for(int i = 0; i < n; i++)
1369 context->deleteRenderbuffer(renderbuffers[i]);
1374 void DeleteShader(GLuint shader)
1376 TRACE("(GLuint shader = %d)", shader);
1383 es2::Context *context = es2::getContext();
1387 if(!context->getShader(shader))
1389 if(context->getProgram(shader))
1391 return error(GL_INVALID_OPERATION);
1395 return error(GL_INVALID_VALUE);
1399 context->deleteShader(shader);
1403 void DeleteTextures(GLsizei n, const GLuint* textures)
1405 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
1409 return error(GL_INVALID_VALUE);
1412 es2::Context *context = es2::getContext();
1416 for(int i = 0; i < n; i++)
1418 if(textures[i] != 0)
1420 context->deleteTexture(textures[i]);
1426 void DepthFunc(GLenum func)
1428 TRACE("(GLenum func = 0x%X)", func);
1442 return error(GL_INVALID_ENUM);
1445 es2::Context *context = es2::getContext();
1449 context->setDepthFunc(func);
1453 void DepthMask(GLboolean flag)
1455 TRACE("(GLboolean flag = %d)", flag);
1457 es2::Context *context = es2::getContext();
1461 context->setDepthMask(flag != GL_FALSE);
1465 void DepthRangef(GLclampf zNear, GLclampf zFar)
1467 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1469 es2::Context *context = es2::getContext();
1473 context->setDepthRange(zNear, zFar);
1477 void DetachShader(GLuint program, GLuint shader)
1479 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
1481 es2::Context *context = es2::getContext();
1486 es2::Program *programObject = context->getProgram(program);
1487 es2::Shader *shaderObject = context->getShader(shader);
1491 es2::Shader *shaderByProgramHandle;
1492 shaderByProgramHandle = context->getShader(program);
1493 if(!shaderByProgramHandle)
1495 return error(GL_INVALID_VALUE);
1499 return error(GL_INVALID_OPERATION);
1505 es2::Program *programByShaderHandle = context->getProgram(shader);
1506 if(!programByShaderHandle)
1508 return error(GL_INVALID_VALUE);
1512 return error(GL_INVALID_OPERATION);
1516 if(!programObject->detachShader(shaderObject))
1518 return error(GL_INVALID_OPERATION);
1523 void Disable(GLenum cap)
1525 TRACE("(GLenum cap = 0x%X)", cap);
1527 es2::Context *context = es2::getContext();
1533 case GL_CULL_FACE: context->setCullFaceEnabled(false); break;
1534 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(false); break;
1535 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;
1536 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(false); break;
1537 case GL_SCISSOR_TEST: context->setScissorTestEnabled(false); break;
1538 case GL_STENCIL_TEST: context->setStencilTestEnabled(false); break;
1539 case GL_DEPTH_TEST: context->setDepthTestEnabled(false); break;
1540 case GL_BLEND: context->setBlendEnabled(false); break;
1541 case GL_DITHER: context->setDitherEnabled(false); break;
1542 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(false); break;
1543 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscardEnabled(false); break;
1545 return error(GL_INVALID_ENUM);
1550 void DisableVertexAttribArray(GLuint index)
1552 TRACE("(GLuint index = %d)", index);
1554 if(index >= es2::MAX_VERTEX_ATTRIBS)
1556 return error(GL_INVALID_VALUE);
1559 es2::Context *context = es2::getContext();
1563 context->setVertexAttribArrayEnabled(index, false);
1567 void DrawArrays(GLenum mode, GLint first, GLsizei count)
1569 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1578 case GL_TRIANGLE_FAN:
1579 case GL_TRIANGLE_STRIP:
1582 return error(GL_INVALID_ENUM);
1585 if(count < 0 || first < 0)
1587 return error(GL_INVALID_VALUE);
1590 es2::Context *context = es2::getContext();
1594 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1595 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1597 return error(GL_INVALID_OPERATION);
1600 context->drawArrays(mode, first, count);
1604 void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
1606 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
1607 mode, count, type, indices);
1616 case GL_TRIANGLE_FAN:
1617 case GL_TRIANGLE_STRIP:
1620 return error(GL_INVALID_ENUM);
1625 return error(GL_INVALID_VALUE);
1628 es2::Context *context = es2::getContext();
1632 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1633 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1635 return error(GL_INVALID_OPERATION);
1640 case GL_UNSIGNED_BYTE:
1641 case GL_UNSIGNED_SHORT:
1642 case GL_UNSIGNED_INT:
1645 return error(GL_INVALID_ENUM);
1648 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices);
1652 void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1654 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1655 mode, first, count, instanceCount);
1664 case GL_TRIANGLE_FAN:
1665 case GL_TRIANGLE_STRIP:
1668 return error(GL_INVALID_ENUM);
1671 if(count < 0 || instanceCount < 0)
1673 return error(GL_INVALID_VALUE);
1676 es2::Context *context = es2::getContext();
1680 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1681 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1683 return error(GL_INVALID_OPERATION);
1686 context->drawArrays(mode, first, count, instanceCount);
1690 void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
1692 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
1693 mode, count, type, indices, instanceCount);
1702 case GL_TRIANGLE_FAN:
1703 case GL_TRIANGLE_STRIP:
1706 return error(GL_INVALID_ENUM);
1711 case GL_UNSIGNED_BYTE:
1712 case GL_UNSIGNED_SHORT:
1713 case GL_UNSIGNED_INT:
1716 return error(GL_INVALID_ENUM);
1719 if(count < 0 || instanceCount < 0)
1721 return error(GL_INVALID_VALUE);
1724 es2::Context *context = es2::getContext();
1728 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1729 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1731 return error(GL_INVALID_OPERATION);
1734 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
1738 void VertexAttribDivisorEXT(GLuint index, GLuint divisor)
1740 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1742 es2::Context *context = es2::getContext();
1746 if(index >= es2::MAX_VERTEX_ATTRIBS)
1748 return error(GL_INVALID_VALUE);
1751 context->setVertexAttribDivisor(index, divisor);
1755 void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1757 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1758 mode, first, count, instanceCount);
1767 case GL_TRIANGLE_FAN:
1768 case GL_TRIANGLE_STRIP:
1771 return error(GL_INVALID_ENUM);
1774 if(count < 0 || instanceCount < 0)
1776 return error(GL_INVALID_VALUE);
1779 es2::Context *context = es2::getContext();
1783 if(!context->hasZeroDivisor())
1785 return error(GL_INVALID_OPERATION);
1788 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1789 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1791 return error(GL_INVALID_OPERATION);
1794 context->drawArrays(mode, first, count, instanceCount);
1798 void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
1800 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
1801 mode, count, type, indices, instanceCount);
1810 case GL_TRIANGLE_FAN:
1811 case GL_TRIANGLE_STRIP:
1814 return error(GL_INVALID_ENUM);
1819 case GL_UNSIGNED_BYTE:
1820 case GL_UNSIGNED_SHORT:
1821 case GL_UNSIGNED_INT:
1824 return error(GL_INVALID_ENUM);
1827 if(count < 0 || instanceCount < 0)
1829 return error(GL_INVALID_VALUE);
1832 es2::Context *context = es2::getContext();
1836 if(!context->hasZeroDivisor())
1838 return error(GL_INVALID_OPERATION);
1841 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1842 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1844 return error(GL_INVALID_OPERATION);
1847 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
1851 void VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
1853 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1855 es2::Context *context = es2::getContext();
1859 if(index >= MAX_VERTEX_ATTRIBS)
1861 return error(GL_INVALID_VALUE);
1864 context->setVertexAttribDivisor(index, divisor);
1868 void Enable(GLenum cap)
1870 TRACE("(GLenum cap = 0x%X)", cap);
1872 es2::Context *context = es2::getContext();
1878 case GL_CULL_FACE: context->setCullFaceEnabled(true); break;
1879 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(true); break;
1880 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;
1881 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(true); break;
1882 case GL_SCISSOR_TEST: context->setScissorTestEnabled(true); break;
1883 case GL_STENCIL_TEST: context->setStencilTestEnabled(true); break;
1884 case GL_DEPTH_TEST: context->setDepthTestEnabled(true); break;
1885 case GL_BLEND: context->setBlendEnabled(true); break;
1886 case GL_DITHER: context->setDitherEnabled(true); break;
1887 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(true); break;
1888 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscardEnabled(true); break;
1890 return error(GL_INVALID_ENUM);
1895 void EnableVertexAttribArray(GLuint index)
1897 TRACE("(GLuint index = %d)", index);
1899 if(index >= es2::MAX_VERTEX_ATTRIBS)
1901 return error(GL_INVALID_VALUE);
1904 es2::Context *context = es2::getContext();
1908 context->setVertexAttribArrayEnabled(index, true);
1912 void EndQueryEXT(GLenum target)
1914 TRACE("GLenum target = 0x%X)", target);
1918 case GL_ANY_SAMPLES_PASSED_EXT:
1919 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1922 return error(GL_INVALID_ENUM);
1925 es2::Context *context = es2::getContext();
1929 context->endQuery(target);
1933 void FinishFenceNV(GLuint fence)
1935 TRACE("(GLuint fence = %d)", fence);
1937 es2::Context *context = es2::getContext();
1941 es2::Fence *fenceObject = context->getFence(fence);
1945 return error(GL_INVALID_OPERATION);
1948 fenceObject->finishFence();
1956 es2::Context *context = es2::getContext();
1968 es2::Context *context = es2::getContext();
1976 void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1978 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1979 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1981 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
1982 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
1984 return error(GL_INVALID_ENUM);
1987 es2::Context *context = es2::getContext();
1991 es2::Framebuffer *framebuffer = nullptr;
1992 GLuint framebufferName = 0;
1993 if(target == GL_READ_FRAMEBUFFER_ANGLE)
1995 framebuffer = context->getReadFramebuffer();
1996 framebufferName = context->getReadFramebufferName();
2000 framebuffer = context->getDrawFramebuffer();
2001 framebufferName = context->getDrawFramebufferName();
2004 if(!framebuffer || framebufferName == 0)
2006 return error(GL_INVALID_OPERATION);
2009 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
2010 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
2011 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
2012 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
2013 if(renderbuffer != 0)
2015 if(!context->getRenderbuffer(renderbuffer))
2017 return error(GL_INVALID_OPERATION);
2021 GLint clientVersion = context->getClientVersion();
2025 case GL_COLOR_ATTACHMENT0:
2026 case GL_COLOR_ATTACHMENT1:
2027 case GL_COLOR_ATTACHMENT2:
2028 case GL_COLOR_ATTACHMENT3:
2029 case GL_COLOR_ATTACHMENT4:
2030 case GL_COLOR_ATTACHMENT5:
2031 case GL_COLOR_ATTACHMENT6:
2032 case GL_COLOR_ATTACHMENT7:
2033 case GL_COLOR_ATTACHMENT8:
2034 case GL_COLOR_ATTACHMENT9:
2035 case GL_COLOR_ATTACHMENT10:
2036 case GL_COLOR_ATTACHMENT11:
2037 case GL_COLOR_ATTACHMENT12:
2038 case GL_COLOR_ATTACHMENT13:
2039 case GL_COLOR_ATTACHMENT14:
2040 case GL_COLOR_ATTACHMENT15:
2041 case GL_COLOR_ATTACHMENT16:
2042 case GL_COLOR_ATTACHMENT17:
2043 case GL_COLOR_ATTACHMENT18:
2044 case GL_COLOR_ATTACHMENT19:
2045 case GL_COLOR_ATTACHMENT20:
2046 case GL_COLOR_ATTACHMENT21:
2047 case GL_COLOR_ATTACHMENT22:
2048 case GL_COLOR_ATTACHMENT23:
2049 case GL_COLOR_ATTACHMENT24:
2050 case GL_COLOR_ATTACHMENT25:
2051 case GL_COLOR_ATTACHMENT26:
2052 case GL_COLOR_ATTACHMENT27:
2053 case GL_COLOR_ATTACHMENT28:
2054 case GL_COLOR_ATTACHMENT29:
2055 case GL_COLOR_ATTACHMENT30:
2056 case GL_COLOR_ATTACHMENT31:
2057 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
2059 return error(GL_INVALID_ENUM);
2061 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0);
2063 case GL_DEPTH_ATTACHMENT:
2064 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2066 case GL_STENCIL_ATTACHMENT:
2067 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2069 case GL_DEPTH_STENCIL_ATTACHMENT:
2070 if(clientVersion >= 3)
2072 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2073 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2076 else return error(GL_INVALID_ENUM);
2078 return error(GL_INVALID_ENUM);
2083 void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2085 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
2086 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
2088 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2090 return error(GL_INVALID_ENUM);
2093 es2::Context *context = es2::getContext();
2097 GLint clientVersion = context->getClientVersion();
2101 textarget = GL_NONE;
2105 es2::Texture *tex = context->getTexture(texture);
2109 return error(GL_INVALID_OPERATION);
2115 if(tex->getTarget() != GL_TEXTURE_2D)
2117 return error(GL_INVALID_OPERATION);
2120 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2121 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2122 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2123 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2124 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2125 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2126 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2128 return error(GL_INVALID_OPERATION);
2132 return error(GL_INVALID_ENUM);
2135 if((level != 0) && (clientVersion < 3))
2137 return error(GL_INVALID_VALUE);
2140 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
2142 return error(GL_INVALID_VALUE);
2145 if(tex->isCompressed(textarget, level))
2147 return error(GL_INVALID_OPERATION);
2151 es2::Framebuffer *framebuffer = nullptr;
2152 GLuint framebufferName = 0;
2153 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2155 framebuffer = context->getReadFramebuffer();
2156 framebufferName = context->getReadFramebufferName();
2160 framebuffer = context->getDrawFramebuffer();
2161 framebufferName = context->getDrawFramebufferName();
2164 if(framebufferName == 0 || !framebuffer)
2166 return error(GL_INVALID_OPERATION);
2171 case GL_COLOR_ATTACHMENT0:
2172 case GL_COLOR_ATTACHMENT1:
2173 case GL_COLOR_ATTACHMENT2:
2174 case GL_COLOR_ATTACHMENT3:
2175 case GL_COLOR_ATTACHMENT4:
2176 case GL_COLOR_ATTACHMENT5:
2177 case GL_COLOR_ATTACHMENT6:
2178 case GL_COLOR_ATTACHMENT7:
2179 case GL_COLOR_ATTACHMENT8:
2180 case GL_COLOR_ATTACHMENT9:
2181 case GL_COLOR_ATTACHMENT10:
2182 case GL_COLOR_ATTACHMENT11:
2183 case GL_COLOR_ATTACHMENT12:
2184 case GL_COLOR_ATTACHMENT13:
2185 case GL_COLOR_ATTACHMENT14:
2186 case GL_COLOR_ATTACHMENT15:
2187 case GL_COLOR_ATTACHMENT16:
2188 case GL_COLOR_ATTACHMENT17:
2189 case GL_COLOR_ATTACHMENT18:
2190 case GL_COLOR_ATTACHMENT19:
2191 case GL_COLOR_ATTACHMENT20:
2192 case GL_COLOR_ATTACHMENT21:
2193 case GL_COLOR_ATTACHMENT22:
2194 case GL_COLOR_ATTACHMENT23:
2195 case GL_COLOR_ATTACHMENT24:
2196 case GL_COLOR_ATTACHMENT25:
2197 case GL_COLOR_ATTACHMENT26:
2198 case GL_COLOR_ATTACHMENT27:
2199 case GL_COLOR_ATTACHMENT28:
2200 case GL_COLOR_ATTACHMENT29:
2201 case GL_COLOR_ATTACHMENT30:
2202 case GL_COLOR_ATTACHMENT31:
2203 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
2205 return error(GL_INVALID_ENUM);
2207 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);
2209 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level); break;
2210 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;
2211 case GL_DEPTH_STENCIL_ATTACHMENT:
2212 if(clientVersion >= 3)
2214 framebuffer->setDepthbuffer(textarget, texture, level);
2215 framebuffer->setStencilbuffer(textarget, texture, level);
2218 else return error(GL_INVALID_ENUM);
2220 return error(GL_INVALID_ENUM);
2225 void FrontFace(GLenum mode)
2227 TRACE("(GLenum mode = 0x%X)", mode);
2234 es2::Context *context = es2::getContext();
2238 context->setFrontFace(mode);
2243 return error(GL_INVALID_ENUM);
2247 void GenBuffers(GLsizei n, GLuint* buffers)
2249 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
2253 return error(GL_INVALID_VALUE);
2256 es2::Context *context = es2::getContext();
2260 for(int i = 0; i < n; i++)
2262 buffers[i] = context->createBuffer();
2267 void GenerateMipmap(GLenum target)
2269 TRACE("(GLenum target = 0x%X)", target);
2271 es2::Context *context = es2::getContext();
2275 es2::Texture *texture = nullptr;
2277 GLint clientVersion = context->getClientVersion();
2282 texture = context->getTexture2D();
2284 case GL_TEXTURE_CUBE_MAP:
2285 texture = context->getTextureCubeMap();
2287 case GL_TEXTURE_2D_ARRAY:
2288 if(clientVersion < 3)
2290 return error(GL_INVALID_ENUM);
2294 texture = context->getTexture2DArray();
2297 case GL_TEXTURE_3D_OES:
2298 texture = context->getTexture3D();
2301 return error(GL_INVALID_ENUM);
2304 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2306 return error(GL_INVALID_OPERATION);
2309 texture->generateMipmaps();
2313 void GenFencesNV(GLsizei n, GLuint* fences)
2315 TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
2319 return error(GL_INVALID_VALUE);
2322 es2::Context *context = es2::getContext();
2326 for(int i = 0; i < n; i++)
2328 fences[i] = context->createFence();
2333 void GenFramebuffers(GLsizei n, GLuint* framebuffers)
2335 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
2339 return error(GL_INVALID_VALUE);
2342 es2::Context *context = es2::getContext();
2346 for(int i = 0; i < n; i++)
2348 framebuffers[i] = context->createFramebuffer();
2353 void GenQueriesEXT(GLsizei n, GLuint* ids)
2355 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
2359 return error(GL_INVALID_VALUE);
2362 es2::Context *context = es2::getContext();
2366 for(int i = 0; i < n; i++)
2368 ids[i] = context->createQuery();
2373 void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2375 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
2379 return error(GL_INVALID_VALUE);
2382 es2::Context *context = es2::getContext();
2386 for(int i = 0; i < n; i++)
2388 renderbuffers[i] = context->createRenderbuffer();
2393 void GenTextures(GLsizei n, GLuint* textures)
2395 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
2399 return error(GL_INVALID_VALUE);
2402 es2::Context *context = es2::getContext();
2406 for(int i = 0; i < n; i++)
2408 textures[i] = context->createTexture();
2413 void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
2415 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
2416 "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
2417 program, index, bufsize, length, size, type, name);
2421 return error(GL_INVALID_VALUE);
2424 es2::Context *context = es2::getContext();
2428 es2::Program *programObject = context->getProgram(program);
2432 if(context->getShader(program))
2434 return error(GL_INVALID_OPERATION);
2438 return error(GL_INVALID_VALUE);
2442 if(index >= programObject->getActiveAttributeCount())
2444 return error(GL_INVALID_VALUE);
2447 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2451 void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
2453 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2454 "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
2455 program, index, bufsize, length, size, type, name);
2459 return error(GL_INVALID_VALUE);
2462 es2::Context *context = es2::getContext();
2466 es2::Program *programObject = context->getProgram(program);
2470 if(context->getShader(program))
2472 return error(GL_INVALID_OPERATION);
2476 return error(GL_INVALID_VALUE);
2480 if(index >= programObject->getActiveUniformCount())
2482 return error(GL_INVALID_VALUE);
2485 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2489 void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2491 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
2492 program, maxcount, count, shaders);
2496 return error(GL_INVALID_VALUE);
2499 es2::Context *context = es2::getContext();
2503 es2::Program *programObject = context->getProgram(program);
2507 if(context->getShader(program))
2509 return error(GL_INVALID_OPERATION);
2513 return error(GL_INVALID_VALUE);
2517 return programObject->getAttachedShaders(maxcount, count, shaders);
2521 int GetAttribLocation(GLuint program, const GLchar* name)
2523 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
2525 es2::Context *context = es2::getContext();
2530 es2::Program *programObject = context->getProgram(program);
2534 if(context->getShader(program))
2536 return error(GL_INVALID_OPERATION, -1);
2540 return error(GL_INVALID_VALUE, -1);
2544 if(!programObject->isLinked())
2546 return error(GL_INVALID_OPERATION, -1);
2549 return programObject->getAttributeLocation(name);
2555 void GetBooleanv(GLenum pname, GLboolean* params)
2557 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params);
2559 es2::Context *context = es2::getContext();
2563 if(!(context->getBooleanv(pname, params)))
2566 unsigned int numParams = 0;
2567 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2568 return error(GL_INVALID_ENUM);
2571 return; // it is known that the pname is valid, but there are no parameters to return
2573 if(nativeType == GL_FLOAT)
2575 GLfloat *floatParams = nullptr;
2576 floatParams = new GLfloat[numParams];
2578 context->getFloatv(pname, floatParams);
2580 for(unsigned int i = 0; i < numParams; ++i)
2582 if(floatParams[i] == 0.0f)
2583 params[i] = GL_FALSE;
2585 params[i] = GL_TRUE;
2588 delete [] floatParams;
2590 else if(nativeType == GL_INT)
2592 GLint *intParams = nullptr;
2593 intParams = new GLint[numParams];
2595 context->getIntegerv(pname, intParams);
2597 for(unsigned int i = 0; i < numParams; ++i)
2599 if(intParams[i] == 0)
2600 params[i] = GL_FALSE;
2602 params[i] = GL_TRUE;
2605 delete [] intParams;
2611 void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2613 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
2615 es2::Context *context = es2::getContext();
2619 es2::Buffer *buffer;
2620 if(!context->getBuffer(target, &buffer))
2622 return error(GL_INVALID_ENUM);
2627 // A null buffer means that "0" is bound to the requested buffer target
2628 return error(GL_INVALID_OPERATION);
2631 GLint clientVersion = context->getClientVersion();
2635 case GL_BUFFER_USAGE:
2636 *params = buffer->usage();
2638 case GL_BUFFER_SIZE:
2639 *params = (GLint)buffer->size();
2641 case GL_BUFFER_ACCESS_FLAGS:
2642 if(clientVersion >= 3)
2644 *params = buffer->access();
2647 else return error(GL_INVALID_ENUM);
2648 case GL_BUFFER_MAPPED:
2649 if(clientVersion >= 3)
2651 *params = buffer->isMapped();
2654 else return error(GL_INVALID_ENUM);
2655 case GL_BUFFER_MAP_LENGTH:
2656 if(clientVersion >= 3)
2658 *params = (GLint)buffer->length();
2661 else return error(GL_INVALID_ENUM);
2662 case GL_BUFFER_MAP_OFFSET:
2663 if(clientVersion >= 3)
2665 *params = (GLint)buffer->offset();
2668 else return error(GL_INVALID_ENUM);
2670 return error(GL_INVALID_ENUM);
2675 GLenum GetError(void)
2679 es2::Context *context = es2::getContext();
2683 return context->getError();
2689 void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2691 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
2693 es2::Context *context = es2::getContext();
2697 es2::Fence *fenceObject = context->getFence(fence);
2701 return error(GL_INVALID_OPERATION);
2704 fenceObject->getFenceiv(pname, params);
2708 void GetFloatv(GLenum pname, GLfloat* params)
2710 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
2712 es2::Context *context = es2::getContext();
2716 if(!(context->getFloatv(pname, params)))
2719 unsigned int numParams = 0;
2720 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2721 return error(GL_INVALID_ENUM);
2724 return; // it is known that the pname is valid, but that there are no parameters to return.
2726 if(nativeType == GL_BOOL)
2728 GLboolean *boolParams = nullptr;
2729 boolParams = new GLboolean[numParams];
2731 context->getBooleanv(pname, boolParams);
2733 for(unsigned int i = 0; i < numParams; ++i)
2735 if(boolParams[i] == GL_FALSE)
2741 delete [] boolParams;
2743 else if(nativeType == GL_INT)
2745 GLint *intParams = nullptr;
2746 intParams = new GLint[numParams];
2748 context->getIntegerv(pname, intParams);
2750 for(unsigned int i = 0; i < numParams; ++i)
2752 params[i] = (GLfloat)intParams[i];
2755 delete [] intParams;
2761 void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2763 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
2764 target, attachment, pname, params);
2766 es2::Context *context = es2::getContext();
2770 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
2772 return error(GL_INVALID_ENUM);
2775 GLint clientVersion = context->getClientVersion();
2777 es2::Framebuffer *framebuffer = nullptr;
2778 if(target == GL_READ_FRAMEBUFFER)
2780 if(context->getReadFramebufferName() == 0)
2782 if(clientVersion < 3)
2784 return error(GL_INVALID_OPERATION);
2795 return error(GL_INVALID_ENUM);
2800 framebuffer = context->getReadFramebuffer();
2804 if(context->getDrawFramebufferName() == 0)
2806 if(clientVersion < 3)
2808 return error(GL_INVALID_OPERATION);
2819 return error(GL_INVALID_ENUM);
2824 framebuffer = context->getDrawFramebuffer();
2827 GLenum attachmentType;
2828 GLuint attachmentHandle;
2829 GLint attachmentLayer;
2830 Renderbuffer* renderbuffer = nullptr;
2834 if(clientVersion >= 3)
2836 attachmentType = framebuffer->getColorbufferType(0);
2837 attachmentHandle = framebuffer->getColorbufferName(0);
2838 attachmentLayer = framebuffer->getColorbufferLayer(0);
2839 renderbuffer = framebuffer->getColorbuffer(0);
2841 else return error(GL_INVALID_ENUM);
2843 case GL_COLOR_ATTACHMENT0:
2844 case GL_COLOR_ATTACHMENT1:
2845 case GL_COLOR_ATTACHMENT2:
2846 case GL_COLOR_ATTACHMENT3:
2847 case GL_COLOR_ATTACHMENT4:
2848 case GL_COLOR_ATTACHMENT5:
2849 case GL_COLOR_ATTACHMENT6:
2850 case GL_COLOR_ATTACHMENT7:
2851 case GL_COLOR_ATTACHMENT8:
2852 case GL_COLOR_ATTACHMENT9:
2853 case GL_COLOR_ATTACHMENT10:
2854 case GL_COLOR_ATTACHMENT11:
2855 case GL_COLOR_ATTACHMENT12:
2856 case GL_COLOR_ATTACHMENT13:
2857 case GL_COLOR_ATTACHMENT14:
2858 case GL_COLOR_ATTACHMENT15:
2859 case GL_COLOR_ATTACHMENT16:
2860 case GL_COLOR_ATTACHMENT17:
2861 case GL_COLOR_ATTACHMENT18:
2862 case GL_COLOR_ATTACHMENT19:
2863 case GL_COLOR_ATTACHMENT20:
2864 case GL_COLOR_ATTACHMENT21:
2865 case GL_COLOR_ATTACHMENT22:
2866 case GL_COLOR_ATTACHMENT23:
2867 case GL_COLOR_ATTACHMENT24:
2868 case GL_COLOR_ATTACHMENT25:
2869 case GL_COLOR_ATTACHMENT26:
2870 case GL_COLOR_ATTACHMENT27:
2871 case GL_COLOR_ATTACHMENT28:
2872 case GL_COLOR_ATTACHMENT29:
2873 case GL_COLOR_ATTACHMENT30:
2874 case GL_COLOR_ATTACHMENT31:
2875 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
2877 return error(GL_INVALID_ENUM);
2879 attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
2880 attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
2881 attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
2882 renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
2885 if(clientVersion < 3)
2887 return error(GL_INVALID_ENUM);
2890 case GL_DEPTH_ATTACHMENT:
2891 attachmentType = framebuffer->getDepthbufferType();
2892 attachmentHandle = framebuffer->getDepthbufferName();
2893 attachmentLayer = framebuffer->getDepthbufferLayer();
2894 renderbuffer = framebuffer->getDepthbuffer();
2897 if(clientVersion < 3)
2899 return error(GL_INVALID_ENUM);
2902 case GL_STENCIL_ATTACHMENT:
2903 attachmentType = framebuffer->getStencilbufferType();
2904 attachmentHandle = framebuffer->getStencilbufferName();
2905 attachmentLayer = framebuffer->getStencilbufferLayer();
2906 renderbuffer = framebuffer->getStencilbuffer();
2908 case GL_DEPTH_STENCIL_ATTACHMENT:
2909 if(clientVersion >= 3)
2911 attachmentType = framebuffer->getDepthbufferType();
2912 attachmentHandle = framebuffer->getDepthbufferName();
2913 attachmentLayer = framebuffer->getDepthbufferLayer();
2914 if(attachmentHandle != framebuffer->getStencilbufferName())
2916 // Different attachments to DEPTH and STENCIL, query fails
2917 return error(GL_INVALID_OPERATION);
2919 renderbuffer = framebuffer->getDepthbuffer();
2921 else return error(GL_INVALID_ENUM);
2924 return error(GL_INVALID_ENUM);
2927 GLenum attachmentObjectType = GL_NONE; // Type category
2928 if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))
2930 attachmentObjectType = attachmentType;
2932 else if(es2::IsTextureTarget(attachmentType))
2934 attachmentObjectType = GL_TEXTURE;
2936 else UNREACHABLE(attachmentType);
2938 if(attachmentObjectType != GL_NONE)
2942 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2943 *params = attachmentObjectType;
2945 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2946 if(Framebuffer::IsRenderbuffer(attachmentObjectType) || attachmentObjectType == GL_TEXTURE)
2948 *params = attachmentHandle;
2952 return error(GL_INVALID_ENUM);
2955 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2956 if(attachmentObjectType == GL_TEXTURE)
2958 *params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2962 return error(GL_INVALID_ENUM);
2965 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2966 if(attachmentObjectType == GL_TEXTURE)
2968 if(es2::IsCubemapTextureTarget(attachmentType))
2970 *params = attachmentType;
2979 return error(GL_INVALID_ENUM);
2982 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
2983 if(clientVersion >= 3)
2985 *params = attachmentLayer;
2987 else return error(GL_INVALID_ENUM);
2989 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
2990 if(clientVersion >= 3)
2992 *params = renderbuffer->getRedSize();
2994 else return error(GL_INVALID_ENUM);
2996 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
2997 if(clientVersion >= 3)
2999 *params = renderbuffer->getGreenSize();
3001 else return error(GL_INVALID_ENUM);
3003 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
3004 if(clientVersion >= 3)
3006 *params = renderbuffer->getBlueSize();
3008 else return error(GL_INVALID_ENUM);
3010 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
3011 if(clientVersion >= 3)
3013 *params = renderbuffer->getAlphaSize();
3015 else return error(GL_INVALID_ENUM);
3017 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
3018 if(clientVersion >= 3)
3020 *params = renderbuffer->getDepthSize();
3022 else return error(GL_INVALID_ENUM);
3024 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
3025 if(clientVersion >= 3)
3027 *params = renderbuffer->getStencilSize();
3029 else return error(GL_INVALID_ENUM);
3031 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
3032 // case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: // GL_EXT_color_buffer_half_float
3033 if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
3035 return error(GL_INVALID_OPERATION);
3038 *params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);
3040 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
3041 if(clientVersion >= 3)
3043 *params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added
3045 else return error(GL_INVALID_ENUM);
3048 return error(GL_INVALID_ENUM);
3053 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
3054 // is NONE, then querying any other pname will generate INVALID_ENUM.
3056 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
3057 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
3058 // INVALID_OPERATION for all other pnames
3062 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3066 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3067 if(clientVersion < 3)
3069 return error(GL_INVALID_ENUM);
3075 if(clientVersion < 3)
3077 return error(GL_INVALID_ENUM);
3081 return error(GL_INVALID_OPERATION);
3088 GLenum GetGraphicsResetStatusEXT(void)
3095 void GetIntegerv(GLenum pname, GLint* params)
3097 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
3099 es2::Context *context = es2::getContext();
3103 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
3105 ALOGI("expected_badness glGetIntegerv() called without current context.");
3107 ERR("glGetIntegerv() called without current context.");
3110 // This is not spec compliant! When there is no current GL context, functions should
3111 // have no side effects. Google Maps queries these values before creating a context,
3112 // so we need this as a bug-compatible workaround.
3115 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return;
3116 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return;
3117 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
3118 case GL_STENCIL_BITS: *params = 8; return;
3119 case GL_ALIASED_LINE_WIDTH_RANGE:
3120 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
3121 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
3128 if(!(context->getIntegerv(pname, params)))
3131 unsigned int numParams = 0;
3132 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3133 return error(GL_INVALID_ENUM);
3136 return; // it is known that pname is valid, but there are no parameters to return
3138 if(nativeType == GL_BOOL)
3140 GLboolean *boolParams = nullptr;
3141 boolParams = new GLboolean[numParams];
3143 context->getBooleanv(pname, boolParams);
3145 for(unsigned int i = 0; i < numParams; ++i)
3147 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
3150 delete [] boolParams;
3152 else if(nativeType == GL_FLOAT)
3154 GLfloat *floatParams = nullptr;
3155 floatParams = new GLfloat[numParams];
3157 context->getFloatv(pname, floatParams);
3159 for(unsigned int i = 0; i < numParams; ++i)
3161 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3163 params[i] = convert_float_int(floatParams[i]);
3167 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3171 delete [] floatParams;
3177 void GetProgramiv(GLuint program, GLenum pname, GLint* params)
3179 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
3181 es2::Context *context = es2::getContext();
3185 es2::Program *programObject = context->getProgram(program);
3189 if(context->getShader(program))
3191 return error(GL_INVALID_OPERATION);
3195 return error(GL_INVALID_VALUE);
3199 GLint clientVersion = egl::getClientVersion();
3203 case GL_DELETE_STATUS:
3204 *params = programObject->isFlaggedForDeletion();
3206 case GL_LINK_STATUS:
3207 *params = programObject->isLinked();
3209 case GL_VALIDATE_STATUS:
3210 *params = programObject->isValidated();
3212 case GL_INFO_LOG_LENGTH:
3213 *params = (GLint)programObject->getInfoLogLength();
3215 case GL_ATTACHED_SHADERS:
3216 *params = programObject->getAttachedShadersCount();
3218 case GL_ACTIVE_ATTRIBUTES:
3219 *params = (GLint)programObject->getActiveAttributeCount();
3221 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
3222 *params = programObject->getActiveAttributeMaxLength();
3224 case GL_ACTIVE_UNIFORMS:
3225 *params = (GLint)programObject->getActiveUniformCount();
3227 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
3228 *params = programObject->getActiveUniformMaxLength();
3230 case GL_ACTIVE_UNIFORM_BLOCKS:
3231 if(clientVersion >= 3)
3233 *params = (GLint)programObject->getActiveUniformBlockCount();
3236 else return error(GL_INVALID_ENUM);
3237 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
3238 if(clientVersion >= 3)
3240 *params = programObject->getActiveUniformBlockMaxLength();
3243 else return error(GL_INVALID_ENUM);
3244 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
3245 if(clientVersion >= 3)
3247 *params = programObject->getTransformFeedbackBufferMode();
3250 else return error(GL_INVALID_ENUM);
3251 case GL_TRANSFORM_FEEDBACK_VARYINGS:
3252 if(clientVersion >= 3)
3254 *params = programObject->getTransformFeedbackVaryingCount();
3257 else return error(GL_INVALID_ENUM);
3258 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
3259 if(clientVersion >= 3)
3261 *params = programObject->getTransformFeedbackVaryingMaxLength();
3264 else return error(GL_INVALID_ENUM);
3265 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
3266 if(clientVersion >= 3)
3268 *params = programObject->getBinaryRetrievableHint();
3271 else return error(GL_INVALID_ENUM);
3272 case GL_PROGRAM_BINARY_LENGTH:
3273 if(clientVersion >= 3)
3275 *params = programObject->getBinaryLength();
3278 else return error(GL_INVALID_ENUM);
3280 return error(GL_INVALID_ENUM);
3285 void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3287 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3288 program, bufsize, length, infolog);
3292 return error(GL_INVALID_VALUE);
3295 es2::Context *context = es2::getContext();
3299 es2::Program *programObject = context->getProgram(program);
3303 if(context->getShader(program))
3305 return error(GL_INVALID_OPERATION);
3309 return error(GL_INVALID_VALUE);
3313 programObject->getInfoLog(bufsize, length, infolog);
3317 void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3319 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
3323 case GL_CURRENT_QUERY_EXT:
3326 return error(GL_INVALID_ENUM);
3329 es2::Context *context = es2::getContext();
3333 params[0] = context->getActiveQuery(target);
3337 void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
3339 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
3343 case GL_QUERY_RESULT_EXT:
3344 case GL_QUERY_RESULT_AVAILABLE_EXT:
3347 return error(GL_INVALID_ENUM);
3350 es2::Context *context = es2::getContext();
3354 es2::Query *queryObject = context->getQuery(name);
3358 return error(GL_INVALID_OPERATION);
3361 if(context->getActiveQuery(queryObject->getType()) == name)
3363 return error(GL_INVALID_OPERATION);
3368 case GL_QUERY_RESULT_EXT:
3369 params[0] = queryObject->getResult();
3371 case GL_QUERY_RESULT_AVAILABLE_EXT:
3372 params[0] = queryObject->isResultAvailable();
3380 void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3382 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3384 es2::Context *context = es2::getContext();
3388 if(target != GL_RENDERBUFFER)
3390 return error(GL_INVALID_ENUM);
3393 if(context->getRenderbufferName() == 0)
3395 return error(GL_INVALID_OPERATION);
3398 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
3402 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3403 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3404 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
3405 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3406 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3407 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3408 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3409 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3410 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
3411 case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break;
3413 return error(GL_INVALID_ENUM);
3418 void GetShaderiv(GLuint shader, GLenum pname, GLint* params)
3420 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
3422 es2::Context *context = es2::getContext();
3426 es2::Shader *shaderObject = context->getShader(shader);
3430 if(context->getProgram(shader))
3432 return error(GL_INVALID_OPERATION);
3436 return error(GL_INVALID_VALUE);
3442 case GL_SHADER_TYPE:
3443 *params = shaderObject->getType();
3445 case GL_DELETE_STATUS:
3446 *params = shaderObject->isFlaggedForDeletion();
3448 case GL_COMPILE_STATUS:
3449 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3451 case GL_INFO_LOG_LENGTH:
3452 *params = (GLint)shaderObject->getInfoLogLength();
3454 case GL_SHADER_SOURCE_LENGTH:
3455 *params = (GLint)shaderObject->getSourceLength();
3458 return error(GL_INVALID_ENUM);
3463 void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3465 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3466 shader, bufsize, length, infolog);
3470 return error(GL_INVALID_VALUE);
3473 es2::Context *context = es2::getContext();
3477 es2::Shader *shaderObject = context->getShader(shader);
3481 if(context->getProgram(shader))
3483 return error(GL_INVALID_OPERATION);
3487 return error(GL_INVALID_VALUE);
3491 shaderObject->getInfoLog(bufsize, length, infolog);
3495 void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3497 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
3498 shadertype, precisiontype, range, precision);
3502 case GL_VERTEX_SHADER:
3503 case GL_FRAGMENT_SHADER:
3506 return error(GL_INVALID_ENUM);
3509 switch(precisiontype)
3512 case GL_MEDIUM_FLOAT:
3514 // IEEE 754 single-precision
3522 // Full integer precision is supported
3528 return error(GL_INVALID_ENUM);
3532 void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3534 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
3535 shader, bufsize, length, source);
3539 return error(GL_INVALID_VALUE);
3542 es2::Context *context = es2::getContext();
3546 es2::Shader *shaderObject = context->getShader(shader);
3550 if(context->getProgram(shader))
3552 return error(GL_INVALID_OPERATION);
3556 return error(GL_INVALID_VALUE);
3560 shaderObject->getSource(bufsize, length, source);
3564 const GLubyte* GetString(GLenum name)
3566 TRACE("(GLenum name = 0x%X)", name);
3571 return (GLubyte*)"Google Inc.";
3573 return (GLubyte*)"Google SwiftShader";
3576 es2::Context *context = es2::getContext();
3577 return (context && (context->getClientVersion() >= 3)) ?
3578 (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :
3579 (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3581 case GL_SHADING_LANGUAGE_VERSION:
3583 es2::Context *context = es2::getContext();
3584 return (context && (context->getClientVersion() >= 3)) ?
3585 (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :
3586 (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3590 es2::Context *context = es2::getContext();
3591 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)nullptr;
3594 return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
3598 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3600 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
3602 es2::Context *context = es2::getContext();
3606 es2::Texture *texture;
3608 GLint clientVersion = context->getClientVersion();
3613 texture = context->getTexture2D();
3615 case GL_TEXTURE_CUBE_MAP:
3616 texture = context->getTextureCubeMap();
3618 case GL_TEXTURE_EXTERNAL_OES:
3619 texture = context->getTextureExternal();
3621 case GL_TEXTURE_2D_ARRAY:
3622 if(clientVersion < 3)
3624 return error(GL_INVALID_ENUM);
3628 texture = context->getTexture2DArray();
3631 case GL_TEXTURE_3D_OES:
3632 texture = context->getTexture3D();
3635 return error(GL_INVALID_ENUM);
3640 case GL_TEXTURE_MAG_FILTER:
3641 *params = (GLfloat)texture->getMagFilter();
3643 case GL_TEXTURE_MIN_FILTER:
3644 *params = (GLfloat)texture->getMinFilter();
3646 case GL_TEXTURE_WRAP_S:
3647 *params = (GLfloat)texture->getWrapS();
3649 case GL_TEXTURE_WRAP_T:
3650 *params = (GLfloat)texture->getWrapT();
3652 case GL_TEXTURE_WRAP_R_OES:
3653 *params = (GLfloat)texture->getWrapR();
3655 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3656 *params = texture->getMaxAnisotropy();
3658 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3659 *params = (GLfloat)1;
3661 case GL_TEXTURE_BASE_LEVEL:
3662 if(clientVersion >= 3)
3664 *params = (GLfloat)texture->getBaseLevel();
3667 else return error(GL_INVALID_ENUM);
3668 case GL_TEXTURE_COMPARE_FUNC:
3669 if(clientVersion >= 3)
3671 *params = (GLfloat)texture->getCompareFunc();
3674 else return error(GL_INVALID_ENUM);
3675 case GL_TEXTURE_COMPARE_MODE:
3676 if(clientVersion >= 3)
3678 *params = (GLfloat)texture->getCompareMode();
3681 else return error(GL_INVALID_ENUM);
3682 case GL_TEXTURE_IMMUTABLE_FORMAT:
3683 if(clientVersion >= 3)
3685 *params = (GLfloat)texture->getImmutableFormat();
3688 else return error(GL_INVALID_ENUM);
3689 case GL_TEXTURE_IMMUTABLE_LEVELS:
3690 if(clientVersion >= 3)
3692 *params = (GLfloat)texture->getImmutableLevels();
3695 else return error(GL_INVALID_ENUM);
3696 case GL_TEXTURE_MAX_LEVEL:
3697 if(clientVersion >= 3)
3699 *params = (GLfloat)texture->getMaxLevel();
3702 else return error(GL_INVALID_ENUM);
3703 case GL_TEXTURE_MAX_LOD:
3704 if(clientVersion >= 3)
3706 *params = texture->getMaxLOD();
3709 else return error(GL_INVALID_ENUM);
3710 case GL_TEXTURE_MIN_LOD:
3711 if(clientVersion >= 3)
3713 *params = texture->getMinLOD();
3716 else return error(GL_INVALID_ENUM);
3717 case GL_TEXTURE_SWIZZLE_R:
3718 if(clientVersion >= 3)
3720 *params = (GLfloat)texture->getSwizzleR();
3723 else return error(GL_INVALID_ENUM);
3724 case GL_TEXTURE_SWIZZLE_G:
3725 if(clientVersion >= 3)
3727 *params = (GLfloat)texture->getSwizzleG();
3730 else return error(GL_INVALID_ENUM);
3731 case GL_TEXTURE_SWIZZLE_B:
3732 if(clientVersion >= 3)
3734 *params = (GLfloat)texture->getSwizzleB();
3737 else return error(GL_INVALID_ENUM);
3738 case GL_TEXTURE_SWIZZLE_A:
3739 if(clientVersion >= 3)
3741 *params = (GLfloat)texture->getSwizzleA();
3744 else return error(GL_INVALID_ENUM);
3746 return error(GL_INVALID_ENUM);
3751 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3753 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3755 es2::Context *context = es2::getContext();
3759 es2::Texture *texture;
3761 GLint clientVersion = context->getClientVersion();
3766 texture = context->getTexture2D();
3768 case GL_TEXTURE_CUBE_MAP:
3769 texture = context->getTextureCubeMap();
3771 case GL_TEXTURE_EXTERNAL_OES:
3772 texture = context->getTextureExternal();
3774 case GL_TEXTURE_2D_ARRAY:
3775 if(clientVersion < 3)
3777 return error(GL_INVALID_ENUM);
3781 texture = context->getTexture2DArray();
3784 case GL_TEXTURE_3D_OES:
3785 texture = context->getTexture3D();
3788 return error(GL_INVALID_ENUM);
3793 case GL_TEXTURE_MAG_FILTER:
3794 *params = texture->getMagFilter();
3796 case GL_TEXTURE_MIN_FILTER:
3797 *params = texture->getMinFilter();
3799 case GL_TEXTURE_WRAP_S:
3800 *params = texture->getWrapS();
3802 case GL_TEXTURE_WRAP_T:
3803 *params = texture->getWrapT();
3805 case GL_TEXTURE_WRAP_R_OES:
3806 *params = texture->getWrapR();
3808 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3809 *params = (GLint)texture->getMaxAnisotropy();
3811 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3814 case GL_TEXTURE_BASE_LEVEL:
3815 if(clientVersion >= 3)
3817 *params = texture->getBaseLevel();
3820 else return error(GL_INVALID_ENUM);
3821 case GL_TEXTURE_COMPARE_FUNC:
3822 if(clientVersion >= 3)
3824 *params = (GLint)texture->getCompareFunc();
3827 else return error(GL_INVALID_ENUM);
3828 case GL_TEXTURE_COMPARE_MODE:
3829 if(clientVersion >= 3)
3831 *params = (GLint)texture->getCompareMode();
3834 else return error(GL_INVALID_ENUM);
3835 case GL_TEXTURE_IMMUTABLE_FORMAT:
3836 if(clientVersion >= 3)
3838 *params = (GLint)texture->getImmutableFormat();
3841 else return error(GL_INVALID_ENUM);
3842 case GL_TEXTURE_IMMUTABLE_LEVELS:
3843 if(clientVersion >= 3)
3845 *params = (GLint)texture->getImmutableLevels();
3848 else return error(GL_INVALID_ENUM);
3849 case GL_TEXTURE_MAX_LEVEL:
3850 if(clientVersion >= 3)
3852 *params = texture->getMaxLevel();
3855 else return error(GL_INVALID_ENUM);
3856 case GL_TEXTURE_MAX_LOD:
3857 if(clientVersion >= 3)
3859 *params = (GLint)roundf(texture->getMaxLOD());
3862 else return error(GL_INVALID_ENUM);
3863 case GL_TEXTURE_MIN_LOD:
3864 if(clientVersion >= 3)
3866 *params = (GLint)roundf(texture->getMinLOD());
3869 else return error(GL_INVALID_ENUM);
3870 case GL_TEXTURE_SWIZZLE_R:
3871 if(clientVersion >= 3)
3873 *params = (GLint)texture->getSwizzleR();
3876 else return error(GL_INVALID_ENUM);
3877 case GL_TEXTURE_SWIZZLE_G:
3878 if(clientVersion >= 3)
3880 *params = (GLint)texture->getSwizzleG();
3883 else return error(GL_INVALID_ENUM);
3884 case GL_TEXTURE_SWIZZLE_B:
3885 if(clientVersion >= 3)
3887 *params = (GLint)texture->getSwizzleB();
3890 else return error(GL_INVALID_ENUM);
3891 case GL_TEXTURE_SWIZZLE_A:
3892 if(clientVersion >= 3)
3894 *params = (GLint)texture->getSwizzleA();
3897 else return error(GL_INVALID_ENUM);
3899 return error(GL_INVALID_ENUM);
3904 void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3906 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
3907 program, location, bufSize, params);
3911 return error(GL_INVALID_VALUE);
3914 es2::Context *context = es2::getContext();
3918 es2::Program *programObject = context->getProgram(program);
3922 if(context->getShader(program))
3924 return error(GL_INVALID_OPERATION);
3928 return error(GL_INVALID_VALUE);
3932 if(!programObject->isLinked())
3934 return error(GL_INVALID_OPERATION);
3937 if(!programObject->getUniformfv(location, &bufSize, params))
3939 return error(GL_INVALID_OPERATION);
3944 void GetUniformfv(GLuint program, GLint location, GLfloat* params)
3946 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
3948 es2::Context *context = es2::getContext();
3952 es2::Program *programObject = context->getProgram(program);
3956 if(context->getShader(program))
3958 return error(GL_INVALID_OPERATION);
3962 return error(GL_INVALID_VALUE);
3966 if(!programObject->isLinked())
3968 return error(GL_INVALID_OPERATION);
3971 if(!programObject->getUniformfv(location, nullptr, params))
3973 return error(GL_INVALID_OPERATION);
3978 void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3980 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
3981 program, location, bufSize, params);
3985 return error(GL_INVALID_VALUE);
3988 es2::Context *context = es2::getContext();
3992 es2::Program *programObject = context->getProgram(program);
3996 if(context->getShader(program))
3998 return error(GL_INVALID_OPERATION);
4002 return error(GL_INVALID_VALUE);
4006 if(!programObject->isLinked())
4008 return error(GL_INVALID_OPERATION);
4011 if(!programObject->getUniformiv(location, &bufSize, params))
4013 return error(GL_INVALID_OPERATION);
4018 void GetUniformiv(GLuint program, GLint location, GLint* params)
4020 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
4022 es2::Context *context = es2::getContext();
4026 es2::Program *programObject = context->getProgram(program);
4030 if(context->getShader(program))
4032 return error(GL_INVALID_OPERATION);
4036 return error(GL_INVALID_VALUE);
4040 if(!programObject->isLinked())
4042 return error(GL_INVALID_OPERATION);
4045 if(!programObject->getUniformiv(location, nullptr, params))
4047 return error(GL_INVALID_OPERATION);
4052 int GetUniformLocation(GLuint program, const GLchar* name)
4054 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
4056 es2::Context *context = es2::getContext();
4058 if(strstr(name, "gl_") == name)
4065 es2::Program *programObject = context->getProgram(program);
4069 if(context->getShader(program))
4071 return error(GL_INVALID_OPERATION, -1);
4075 return error(GL_INVALID_VALUE, -1);
4079 if(!programObject->isLinked())
4081 return error(GL_INVALID_OPERATION, -1);
4084 return programObject->getUniformLocation(name);
4090 void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4092 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
4094 es2::Context *context = es2::getContext();
4098 if(index >= es2::MAX_VERTEX_ATTRIBS)
4100 return error(GL_INVALID_VALUE);
4103 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4105 GLint clientVersion = context->getClientVersion();
4109 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4110 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4112 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4113 *params = (GLfloat)attribState.mSize;
4115 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4116 *params = (GLfloat)attribState.mStride;
4118 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4119 *params = (GLfloat)attribState.mType;
4121 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4122 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
4124 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4125 *params = (GLfloat)attribState.mBoundBuffer.name();
4127 case GL_CURRENT_VERTEX_ATTRIB:
4129 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4130 for(int i = 0; i < 4; ++i)
4132 params[i] = attrib.getCurrentValueF(i);
4136 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4137 if(clientVersion >= 3)
4139 switch(attribState.mType)
4142 case GL_UNSIGNED_BYTE:
4144 case GL_UNSIGNED_SHORT:
4146 case GL_INT_2_10_10_10_REV:
4147 case GL_UNSIGNED_INT:
4149 *params = (GLfloat)GL_TRUE;
4152 *params = (GLfloat)GL_FALSE;
4157 else return error(GL_INVALID_ENUM);
4158 default: return error(GL_INVALID_ENUM);
4163 void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4165 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
4167 es2::Context *context = es2::getContext();
4171 if(index >= es2::MAX_VERTEX_ATTRIBS)
4173 return error(GL_INVALID_VALUE);
4176 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4178 GLint clientVersion = context->getClientVersion();
4182 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4183 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4185 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4186 *params = attribState.mSize;
4188 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4189 *params = attribState.mStride;
4191 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4192 *params = attribState.mType;
4194 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4195 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
4197 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4198 *params = attribState.mBoundBuffer.name();
4200 case GL_CURRENT_VERTEX_ATTRIB:
4202 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4203 for(int i = 0; i < 4; ++i)
4205 float currentValue = attrib.getCurrentValueF(i);
4206 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4210 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4211 if(clientVersion >= 3)
4213 switch(attribState.mType)
4216 case GL_UNSIGNED_BYTE:
4218 case GL_UNSIGNED_SHORT:
4220 case GL_INT_2_10_10_10_REV:
4221 case GL_UNSIGNED_INT:
4231 else return error(GL_INVALID_ENUM);
4232 default: return error(GL_INVALID_ENUM);
4237 void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
4239 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
4241 es2::Context *context = es2::getContext();
4245 if(index >= es2::MAX_VERTEX_ATTRIBS)
4247 return error(GL_INVALID_VALUE);
4250 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4252 return error(GL_INVALID_ENUM);
4255 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
4259 void Hint(GLenum target, GLenum mode)
4261 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
4270 return error(GL_INVALID_ENUM);
4273 es2::Context *context = es2::getContext();
4276 case GL_GENERATE_MIPMAP_HINT:
4277 if(context) context->setGenerateMipmapHint(mode);
4279 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4280 if(context) context->setFragmentShaderDerivativeHint(mode);
4282 case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
4283 if(context) context->setTextureFilteringHint(mode);
4286 return error(GL_INVALID_ENUM);
4290 GLboolean IsBuffer(GLuint buffer)
4292 TRACE("(GLuint buffer = %d)", buffer);
4294 es2::Context *context = es2::getContext();
4296 if(context && buffer)
4298 es2::Buffer *bufferObject = context->getBuffer(buffer);
4309 GLboolean IsEnabled(GLenum cap)
4311 TRACE("(GLenum cap = 0x%X)", cap);
4313 es2::Context *context = es2::getContext();
4317 GLint clientVersion = context->getClientVersion();
4321 case GL_CULL_FACE: return context->isCullFaceEnabled();
4322 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4323 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4324 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4325 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4326 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4327 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4328 case GL_BLEND: return context->isBlendEnabled();
4329 case GL_DITHER: return context->isDitherEnabled();
4330 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4331 if(clientVersion >= 3)
4333 return context->isPrimitiveRestartFixedIndexEnabled();
4335 else return error(GL_INVALID_ENUM, false);
4336 case GL_RASTERIZER_DISCARD:
4337 if(clientVersion >= 3)
4339 return context->isRasterizerDiscardEnabled();
4341 else return error(GL_INVALID_ENUM, false);
4343 return error(GL_INVALID_ENUM, false);
4350 GLboolean IsFenceNV(GLuint fence)
4352 TRACE("(GLuint fence = %d)", fence);
4354 es2::Context *context = es2::getContext();
4358 es2::Fence *fenceObject = context->getFence(fence);
4365 return fenceObject->isFence();
4371 GLboolean IsFramebuffer(GLuint framebuffer)
4373 TRACE("(GLuint framebuffer = %d)", framebuffer);
4375 es2::Context *context = es2::getContext();
4377 if(context && framebuffer)
4379 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4381 if(framebufferObject)
4390 GLboolean IsProgram(GLuint program)
4392 TRACE("(GLuint program = %d)", program);
4394 es2::Context *context = es2::getContext();
4396 if(context && program)
4398 es2::Program *programObject = context->getProgram(program);
4409 GLboolean IsQueryEXT(GLuint name)
4411 TRACE("(GLuint name = %d)", name);
4418 es2::Context *context = es2::getContext();
4422 es2::Query *queryObject = context->getQuery(name);
4433 GLboolean IsRenderbuffer(GLuint renderbuffer)
4435 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
4437 es2::Context *context = es2::getContext();
4439 if(context && renderbuffer)
4441 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4443 if(renderbufferObject)
4452 GLboolean IsShader(GLuint shader)
4454 TRACE("(GLuint shader = %d)", shader);
4456 es2::Context *context = es2::getContext();
4458 if(context && shader)
4460 es2::Shader *shaderObject = context->getShader(shader);
4471 GLboolean IsTexture(GLuint texture)
4473 TRACE("(GLuint texture = %d)", texture);
4475 es2::Context *context = es2::getContext();
4477 if(context && texture)
4479 es2::Texture *textureObject = context->getTexture(texture);
4490 void LineWidth(GLfloat width)
4492 TRACE("(GLfloat width = %f)", width);
4496 return error(GL_INVALID_VALUE);
4499 es2::Context *context = es2::getContext();
4503 context->setLineWidth(width);
4507 void LinkProgram(GLuint program)
4509 TRACE("(GLuint program = %d)", program);
4511 es2::Context *context = es2::getContext();
4515 es2::Program *programObject = context->getProgram(program);
4519 if(context->getShader(program))
4521 return error(GL_INVALID_OPERATION);
4525 return error(GL_INVALID_VALUE);
4529 programObject->link();
4533 void PixelStorei(GLenum pname, GLint param)
4535 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
4537 es2::Context *context = es2::getContext();
4541 GLint clientVersion = context->getClientVersion();
4545 case GL_UNPACK_ALIGNMENT:
4546 if(param != 1 && param != 2 && param != 4 && param != 8)
4548 return error(GL_INVALID_VALUE);
4550 context->setUnpackAlignment(param);
4552 case GL_PACK_ALIGNMENT:
4553 if(param != 1 && param != 2 && param != 4 && param != 8)
4555 return error(GL_INVALID_VALUE);
4557 context->setPackAlignment(param);
4559 case GL_PACK_ROW_LENGTH:
4560 if(clientVersion >= 3)
4564 return error(GL_INVALID_VALUE);
4566 context->setPackRowLength(param);
4569 else return error(GL_INVALID_ENUM);
4570 case GL_PACK_SKIP_PIXELS:
4571 if(clientVersion >= 3)
4575 return error(GL_INVALID_VALUE);
4577 context->setPackSkipPixels(param);
4580 else return error(GL_INVALID_ENUM);
4581 case GL_PACK_SKIP_ROWS:
4582 if(clientVersion >= 3)
4586 return error(GL_INVALID_VALUE);
4588 context->setPackSkipRows(param);
4591 else return error(GL_INVALID_ENUM);
4592 case GL_UNPACK_ROW_LENGTH:
4593 if(clientVersion >= 3)
4597 return error(GL_INVALID_VALUE);
4599 context->setUnpackRowLength(param);
4602 else return error(GL_INVALID_ENUM);
4603 case GL_UNPACK_IMAGE_HEIGHT:
4604 if(clientVersion >= 3)
4608 return error(GL_INVALID_VALUE);
4610 context->setUnpackImageHeight(param);
4613 else return error(GL_INVALID_ENUM);
4614 case GL_UNPACK_SKIP_PIXELS:
4615 if(clientVersion >= 3)
4619 return error(GL_INVALID_VALUE);
4621 context->setUnpackSkipPixels(param);
4624 else return error(GL_INVALID_ENUM);
4625 case GL_UNPACK_SKIP_ROWS:
4626 if(clientVersion >= 3)
4630 return error(GL_INVALID_VALUE);
4632 context->setUnpackSkipRows(param);
4635 else return error(GL_INVALID_ENUM);
4636 case GL_UNPACK_SKIP_IMAGES:
4637 if(clientVersion >= 3) {
4640 return error(GL_INVALID_VALUE);
4642 context->setUnpackSkipImages(param);
4645 else return error(GL_INVALID_ENUM);
4647 return error(GL_INVALID_ENUM);
4652 void PolygonOffset(GLfloat factor, GLfloat units)
4654 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
4656 es2::Context *context = es2::getContext();
4660 context->setPolygonOffsetParams(factor, units);
4664 void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4665 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
4667 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4668 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
4669 x, y, width, height, format, type, bufSize, data);
4671 if(width < 0 || height < 0 || bufSize < 0)
4673 return error(GL_INVALID_VALUE);
4676 es2::Context *context = es2::getContext();
4680 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4684 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
4686 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4687 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
4688 x, y, width, height, format, type, pixels);
4690 if(width < 0 || height < 0)
4692 return error(GL_INVALID_VALUE);
4695 es2::Context *context = es2::getContext();
4699 context->readPixels(x, y, width, height, format, type, nullptr, pixels);
4703 void ReleaseShaderCompiler(void)
4707 es2::Shader::releaseCompiler();
4710 void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4712 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4713 target, samples, internalformat, width, height);
4717 case GL_RENDERBUFFER:
4720 return error(GL_INVALID_ENUM);
4723 if(width < 0 || height < 0 || samples < 0)
4725 return error(GL_INVALID_VALUE);
4728 es2::Context *context = es2::getContext();
4732 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4733 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4734 samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4736 return error(GL_INVALID_VALUE);
4739 GLuint handle = context->getRenderbufferName();
4742 return error(GL_INVALID_OPERATION);
4745 GLint clientVersion = context->getClientVersion();
4747 if(IsColorRenderable(internalformat, clientVersion, false))
4749 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4751 else if(IsDepthRenderable(internalformat, clientVersion) && IsStencilRenderable(internalformat, clientVersion))
4753 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));
4755 else if(IsDepthRenderable(internalformat, clientVersion))
4757 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));
4759 else if(IsStencilRenderable(internalformat, clientVersion))
4761 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4763 else error(GL_INVALID_ENUM);
4767 void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4769 RenderbufferStorageMultisample(target, samples, internalformat, width, height);
4772 void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4774 RenderbufferStorageMultisample(target, 0, internalformat, width, height);
4777 void SampleCoverage(GLclampf value, GLboolean invert)
4779 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
4781 es2::Context* context = es2::getContext();
4785 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4789 void SetFenceNV(GLuint fence, GLenum condition)
4791 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4793 if(condition != GL_ALL_COMPLETED_NV)
4795 return error(GL_INVALID_ENUM);
4798 es2::Context *context = es2::getContext();
4802 es2::Fence *fenceObject = context->getFence(fence);
4806 return error(GL_INVALID_OPERATION);
4809 fenceObject->setFence(condition);
4813 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
4815 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4817 if(width < 0 || height < 0)
4819 return error(GL_INVALID_VALUE);
4822 es2::Context* context = es2::getContext();
4826 context->setScissorParams(x, y, width, height);
4830 void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4832 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4833 "const GLvoid* binary = %p, GLsizei length = %d)",
4834 n, shaders, binaryformat, binary, length);
4836 // No binary shader formats are supported.
4837 return error(GL_INVALID_ENUM);
4840 void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
4842 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
4843 shader, count, string, length);
4847 return error(GL_INVALID_VALUE);
4850 es2::Context *context = es2::getContext();
4854 es2::Shader *shaderObject = context->getShader(shader);
4858 if(context->getProgram(shader))
4860 return error(GL_INVALID_OPERATION);
4864 return error(GL_INVALID_VALUE);
4868 shaderObject->setSource(count, string, length);
4872 void StencilFunc(GLenum func, GLint ref, GLuint mask)
4874 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4877 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4879 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4885 case GL_FRONT_AND_BACK:
4888 return error(GL_INVALID_ENUM);
4903 return error(GL_INVALID_ENUM);
4906 es2::Context *context = es2::getContext();
4910 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4912 context->setStencilParams(func, ref, mask);
4915 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4917 context->setStencilBackParams(func, ref, mask);
4922 void StencilMask(GLuint mask)
4924 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4927 void StencilMaskSeparate(GLenum face, GLuint mask)
4929 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4935 case GL_FRONT_AND_BACK:
4938 return error(GL_INVALID_ENUM);
4941 es2::Context *context = es2::getContext();
4945 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4947 context->setStencilWritemask(mask);
4950 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4952 context->setStencilBackWritemask(mask);
4957 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4959 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4962 void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4964 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4965 face, fail, zfail, zpass);
4971 case GL_FRONT_AND_BACK:
4974 return error(GL_INVALID_ENUM);
4989 return error(GL_INVALID_ENUM);
5004 return error(GL_INVALID_ENUM);
5019 return error(GL_INVALID_ENUM);
5022 es2::Context *context = es2::getContext();
5026 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
5028 context->setStencilOperations(fail, zfail, zpass);
5031 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
5033 context->setStencilBackOperations(fail, zfail, zpass);
5038 GLboolean TestFenceNV(GLuint fence)
5040 TRACE("(GLuint fence = %d)", fence);
5042 es2::Context *context = es2::getContext();
5046 es2::Fence *fenceObject = context->getFence(fence);
5050 return error(GL_INVALID_OPERATION, GL_TRUE);
5053 return fenceObject->testFence();
5059 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5060 GLint border, GLenum format, GLenum type, const GLvoid* data)
5062 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
5063 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* data = %p)",
5064 target, level, internalformat, width, height, border, format, type, data);
5066 if(!validImageSize(level, width, height))
5068 return error(GL_INVALID_VALUE);
5071 es2::Context *context = es2::getContext();
5075 GLint clientVersion = context->getClientVersion();
5076 if(clientVersion < 3)
5078 if(internalformat != (GLint)format)
5080 return error(GL_INVALID_OPERATION);
5084 GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);
5085 if(validationError != GL_NONE)
5087 return error(validationError);
5090 if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
5097 return error(GL_INVALID_VALUE);
5103 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5104 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
5106 return error(GL_INVALID_VALUE);
5109 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5110 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5111 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5112 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5113 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5114 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5117 return error(GL_INVALID_VALUE);
5120 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5121 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5123 return error(GL_INVALID_VALUE);
5127 return error(GL_INVALID_ENUM);
5130 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
5132 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
5133 if(validationError != GL_NONE)
5135 return error(validationError);
5138 if(target == GL_TEXTURE_2D)
5140 es2::Texture2D *texture = context->getTexture2D();
5144 return error(GL_INVALID_OPERATION);
5147 texture->setImage(context, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
5151 es2::TextureCubeMap *texture = context->getTextureCubeMap();
5155 return error(GL_INVALID_OPERATION);
5158 texture->setImage(context, target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
5163 void TexParameterf(GLenum target, GLenum pname, GLfloat param)
5165 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
5167 es2::Context *context = es2::getContext();
5171 es2::Texture *texture;
5173 GLint clientVersion = context->getClientVersion();
5178 texture = context->getTexture2D();
5180 case GL_TEXTURE_2D_ARRAY:
5181 if(clientVersion < 3)
5183 return error(GL_INVALID_ENUM);
5187 texture = context->getTexture2DArray();
5190 case GL_TEXTURE_3D_OES:
5191 texture = context->getTexture3D();
5193 case GL_TEXTURE_CUBE_MAP:
5194 texture = context->getTextureCubeMap();
5196 case GL_TEXTURE_EXTERNAL_OES:
5197 texture = context->getTextureExternal();
5200 return error(GL_INVALID_ENUM);
5205 case GL_TEXTURE_WRAP_S:
5206 if(!texture->setWrapS((GLenum)param))
5208 return error(GL_INVALID_ENUM);
5211 case GL_TEXTURE_WRAP_T:
5212 if(!texture->setWrapT((GLenum)param))
5214 return error(GL_INVALID_ENUM);
5217 case GL_TEXTURE_WRAP_R_OES:
5218 if(!texture->setWrapR((GLenum)param))
5220 return error(GL_INVALID_ENUM);
5223 case GL_TEXTURE_MIN_FILTER:
5224 if(!texture->setMinFilter((GLenum)param))
5226 return error(GL_INVALID_ENUM);
5229 case GL_TEXTURE_MAG_FILTER:
5230 if(!texture->setMagFilter((GLenum)param))
5232 return error(GL_INVALID_ENUM);
5235 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5236 if(!texture->setMaxAnisotropy(param))
5238 return error(GL_INVALID_VALUE);
5241 case GL_TEXTURE_BASE_LEVEL:
5242 if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))
5244 return error(GL_INVALID_VALUE);
5247 case GL_TEXTURE_COMPARE_FUNC:
5248 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5250 return error(GL_INVALID_VALUE);
5253 case GL_TEXTURE_COMPARE_MODE:
5254 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5256 return error(GL_INVALID_VALUE);
5259 case GL_TEXTURE_MAX_LEVEL:
5260 if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))
5262 return error(GL_INVALID_VALUE);
5265 case GL_TEXTURE_MAX_LOD:
5266 if(clientVersion < 3 || !texture->setMaxLOD(param))
5268 return error(GL_INVALID_VALUE);
5271 case GL_TEXTURE_MIN_LOD:
5272 if(clientVersion < 3 || !texture->setMinLOD(param))
5274 return error(GL_INVALID_VALUE);
5277 case GL_TEXTURE_SWIZZLE_R:
5278 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5280 return error(GL_INVALID_VALUE);
5283 case GL_TEXTURE_SWIZZLE_G:
5284 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5286 return error(GL_INVALID_VALUE);
5289 case GL_TEXTURE_SWIZZLE_B:
5290 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5292 return error(GL_INVALID_VALUE);
5295 case GL_TEXTURE_SWIZZLE_A:
5296 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5298 return error(GL_INVALID_VALUE);
5302 return error(GL_INVALID_ENUM);
5307 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5309 glTexParameterf(target, pname, *params);
5312 void TexParameteri(GLenum target, GLenum pname, GLint param)
5314 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
5316 es2::Context *context = es2::getContext();
5320 es2::Texture *texture;
5322 GLint clientVersion = context->getClientVersion();
5327 texture = context->getTexture2D();
5329 case GL_TEXTURE_2D_ARRAY:
5330 if(clientVersion < 3)
5332 return error(GL_INVALID_ENUM);
5336 texture = context->getTexture2DArray();
5339 case GL_TEXTURE_3D_OES:
5340 texture = context->getTexture3D();
5342 case GL_TEXTURE_CUBE_MAP:
5343 texture = context->getTextureCubeMap();
5345 case GL_TEXTURE_EXTERNAL_OES:
5346 texture = context->getTextureExternal();
5349 return error(GL_INVALID_ENUM);
5354 case GL_TEXTURE_WRAP_S:
5355 if(!texture->setWrapS((GLenum)param))
5357 return error(GL_INVALID_ENUM);
5360 case GL_TEXTURE_WRAP_T:
5361 if(!texture->setWrapT((GLenum)param))
5363 return error(GL_INVALID_ENUM);
5366 case GL_TEXTURE_WRAP_R_OES:
5367 if(!texture->setWrapR((GLenum)param))
5369 return error(GL_INVALID_ENUM);
5372 case GL_TEXTURE_MIN_FILTER:
5373 if(!texture->setMinFilter((GLenum)param))
5375 return error(GL_INVALID_ENUM);
5378 case GL_TEXTURE_MAG_FILTER:
5379 if(!texture->setMagFilter((GLenum)param))
5381 return error(GL_INVALID_ENUM);
5384 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5385 if(!texture->setMaxAnisotropy((GLfloat)param))
5387 return error(GL_INVALID_VALUE);
5390 case GL_TEXTURE_BASE_LEVEL:
5391 if(clientVersion < 3 || !texture->setBaseLevel(param))
5393 return error(GL_INVALID_VALUE);
5396 case GL_TEXTURE_COMPARE_FUNC:
5397 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5399 return error(GL_INVALID_VALUE);
5402 case GL_TEXTURE_COMPARE_MODE:
5403 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5405 return error(GL_INVALID_VALUE);
5408 case GL_TEXTURE_MAX_LEVEL:
5409 if(clientVersion < 3 || !texture->setMaxLevel(param))
5411 return error(GL_INVALID_VALUE);
5414 case GL_TEXTURE_MAX_LOD:
5415 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5417 return error(GL_INVALID_VALUE);
5420 case GL_TEXTURE_MIN_LOD:
5421 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5423 return error(GL_INVALID_VALUE);
5426 case GL_TEXTURE_SWIZZLE_R:
5427 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5429 return error(GL_INVALID_VALUE);
5432 case GL_TEXTURE_SWIZZLE_G:
5433 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5435 return error(GL_INVALID_VALUE);
5438 case GL_TEXTURE_SWIZZLE_B:
5439 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5441 return error(GL_INVALID_VALUE);
5444 case GL_TEXTURE_SWIZZLE_A:
5445 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5447 return error(GL_INVALID_VALUE);
5451 return error(GL_INVALID_ENUM);
5456 void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
5458 glTexParameteri(target, pname, *params);
5461 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5462 GLenum format, GLenum type, const GLvoid* data)
5464 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5465 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
5466 "const GLvoid* data = %p)",
5467 target, level, xoffset, yoffset, width, height, format, type, data);
5469 if(!es2::IsTextureTarget(target))
5471 return error(GL_INVALID_ENUM);
5474 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5476 return error(GL_INVALID_VALUE);
5479 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5481 return error(GL_INVALID_VALUE);
5484 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5486 return error(GL_INVALID_VALUE);
5489 if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
5494 if(width == 0 || height == 0)
5499 es2::Context *context = es2::getContext();
5503 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
5505 GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
5506 if(validationError != GL_NONE)
5508 return error(validationError);
5511 if(target == GL_TEXTURE_2D)
5513 es2::Texture2D *texture = context->getTexture2D();
5515 validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
5517 if(validationError == GL_NONE)
5519 texture->subImage(context, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
5523 return error(validationError);
5526 else if(es2::IsCubemapTextureTarget(target))
5528 es2::TextureCubeMap *texture = context->getTextureCubeMap();
5530 validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
5532 if(validationError == GL_NONE)
5534 texture->subImage(context, target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
5538 return error(validationError);
5541 else UNREACHABLE(target);
5545 void Uniform1f(GLint location, GLfloat x)
5547 glUniform1fv(location, 1, &x);
5550 void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
5552 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5556 return error(GL_INVALID_VALUE);
5564 es2::Context *context = es2::getContext();
5568 es2::Program *program = context->getCurrentProgram();
5572 return error(GL_INVALID_OPERATION);
5575 if(!program->setUniform1fv(location, count, v))
5577 return error(GL_INVALID_OPERATION);
5582 void Uniform1i(GLint location, GLint x)
5584 glUniform1iv(location, 1, &x);
5587 void Uniform1iv(GLint location, GLsizei count, const GLint* v)
5589 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5593 return error(GL_INVALID_VALUE);
5601 es2::Context *context = es2::getContext();
5605 es2::Program *program = context->getCurrentProgram();
5609 return error(GL_INVALID_OPERATION);
5612 if(!program->setUniform1iv(location, count, v))
5614 return error(GL_INVALID_OPERATION);
5619 void Uniform2f(GLint location, GLfloat x, GLfloat y)
5621 GLfloat xy[2] = {x, y};
5623 glUniform2fv(location, 1, (GLfloat*)&xy);
5626 void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
5628 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5632 return error(GL_INVALID_VALUE);
5640 es2::Context *context = es2::getContext();
5644 es2::Program *program = context->getCurrentProgram();
5648 return error(GL_INVALID_OPERATION);
5651 if(!program->setUniform2fv(location, count, v))
5653 return error(GL_INVALID_OPERATION);
5658 void Uniform2i(GLint location, GLint x, GLint y)
5660 GLint xy[4] = {x, y};
5662 glUniform2iv(location, 1, (GLint*)&xy);
5665 void Uniform2iv(GLint location, GLsizei count, const GLint* v)
5667 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5671 return error(GL_INVALID_VALUE);
5679 es2::Context *context = es2::getContext();
5683 es2::Program *program = context->getCurrentProgram();
5687 return error(GL_INVALID_OPERATION);
5690 if(!program->setUniform2iv(location, count, v))
5692 return error(GL_INVALID_OPERATION);
5697 void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5699 GLfloat xyz[3] = {x, y, z};
5701 glUniform3fv(location, 1, (GLfloat*)&xyz);
5704 void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
5706 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5710 return error(GL_INVALID_VALUE);
5718 es2::Context *context = es2::getContext();
5722 es2::Program *program = context->getCurrentProgram();
5726 return error(GL_INVALID_OPERATION);
5729 if(!program->setUniform3fv(location, count, v))
5731 return error(GL_INVALID_OPERATION);
5736 void Uniform3i(GLint location, GLint x, GLint y, GLint z)
5738 GLint xyz[3] = {x, y, z};
5740 glUniform3iv(location, 1, (GLint*)&xyz);
5743 void Uniform3iv(GLint location, GLsizei count, const GLint* v)
5745 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5749 return error(GL_INVALID_VALUE);
5757 es2::Context *context = es2::getContext();
5761 es2::Program *program = context->getCurrentProgram();
5765 return error(GL_INVALID_OPERATION);
5768 if(!program->setUniform3iv(location, count, v))
5770 return error(GL_INVALID_OPERATION);
5775 void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5777 GLfloat xyzw[4] = {x, y, z, w};
5779 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5782 void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
5784 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5788 return error(GL_INVALID_VALUE);
5796 es2::Context *context = es2::getContext();
5800 es2::Program *program = context->getCurrentProgram();
5804 return error(GL_INVALID_OPERATION);
5807 if(!program->setUniform4fv(location, count, v))
5809 return error(GL_INVALID_OPERATION);
5814 void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5816 GLint xyzw[4] = {x, y, z, w};
5818 glUniform4iv(location, 1, (GLint*)&xyzw);
5821 void Uniform4iv(GLint location, GLsizei count, const GLint* v)
5823 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5827 return error(GL_INVALID_VALUE);
5835 es2::Context *context = es2::getContext();
5839 es2::Program *program = context->getCurrentProgram();
5843 return error(GL_INVALID_OPERATION);
5846 if(!program->setUniform4iv(location, count, v))
5848 return error(GL_INVALID_OPERATION);
5853 void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5855 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5856 location, count, transpose, value);
5860 return error(GL_INVALID_VALUE);
5868 es2::Context *context = es2::getContext();
5872 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5874 return error(GL_INVALID_VALUE);
5877 es2::Program *program = context->getCurrentProgram();
5881 return error(GL_INVALID_OPERATION);
5884 if(!program->setUniformMatrix2fv(location, count, transpose, value))
5886 return error(GL_INVALID_OPERATION);
5891 void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5893 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5894 location, count, transpose, value);
5898 return error(GL_INVALID_VALUE);
5906 es2::Context *context = es2::getContext();
5910 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5912 return error(GL_INVALID_VALUE);
5915 es2::Program *program = context->getCurrentProgram();
5919 return error(GL_INVALID_OPERATION);
5922 if(!program->setUniformMatrix3fv(location, count, transpose, value))
5924 return error(GL_INVALID_OPERATION);
5929 void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5931 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5932 location, count, transpose, value);
5936 return error(GL_INVALID_VALUE);
5944 es2::Context *context = es2::getContext();
5948 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5950 return error(GL_INVALID_VALUE);
5953 es2::Program *program = context->getCurrentProgram();
5957 return error(GL_INVALID_OPERATION);
5960 if(!program->setUniformMatrix4fv(location, count, transpose, value))
5962 return error(GL_INVALID_OPERATION);
5967 void UseProgram(GLuint program)
5969 TRACE("(GLuint program = %d)", program);
5971 es2::Context *context = es2::getContext();
5975 es2::Program *programObject = context->getProgram(program);
5977 if(!programObject && program != 0)
5979 if(context->getShader(program))
5981 return error(GL_INVALID_OPERATION);
5985 return error(GL_INVALID_VALUE);
5989 if(program != 0 && !programObject->isLinked())
5991 return error(GL_INVALID_OPERATION);
5994 context->useProgram(program);
5998 void ValidateProgram(GLuint program)
6000 TRACE("(GLuint program = %d)", program);
6002 es2::Context *context = es2::getContext();
6006 es2::Program *programObject = context->getProgram(program);
6010 if(context->getShader(program))
6012 return error(GL_INVALID_OPERATION);
6016 return error(GL_INVALID_VALUE);
6020 programObject->validate(context->getDevice());
6024 void VertexAttrib1f(GLuint index, GLfloat x)
6026 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
6028 if(index >= es2::MAX_VERTEX_ATTRIBS)
6030 return error(GL_INVALID_VALUE);
6033 es2::Context *context = es2::getContext();
6037 GLfloat vals[4] = { x, 0, 0, 1 };
6038 context->setVertexAttrib(index, vals);
6042 void VertexAttrib1fv(GLuint index, const GLfloat* values)
6044 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6046 if(index >= es2::MAX_VERTEX_ATTRIBS)
6048 return error(GL_INVALID_VALUE);
6051 es2::Context *context = es2::getContext();
6055 GLfloat vals[4] = { values[0], 0, 0, 1 };
6056 context->setVertexAttrib(index, vals);
6060 void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6062 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
6064 if(index >= es2::MAX_VERTEX_ATTRIBS)
6066 return error(GL_INVALID_VALUE);
6069 es2::Context *context = es2::getContext();
6073 GLfloat vals[4] = { x, y, 0, 1 };
6074 context->setVertexAttrib(index, vals);
6078 void VertexAttrib2fv(GLuint index, const GLfloat* values)
6080 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6082 if(index >= es2::MAX_VERTEX_ATTRIBS)
6084 return error(GL_INVALID_VALUE);
6087 es2::Context *context = es2::getContext();
6091 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6092 context->setVertexAttrib(index, vals);
6096 void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6098 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
6100 if(index >= es2::MAX_VERTEX_ATTRIBS)
6102 return error(GL_INVALID_VALUE);
6105 es2::Context *context = es2::getContext();
6109 GLfloat vals[4] = { x, y, z, 1 };
6110 context->setVertexAttrib(index, vals);
6114 void VertexAttrib3fv(GLuint index, const GLfloat* values)
6116 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6118 if(index >= es2::MAX_VERTEX_ATTRIBS)
6120 return error(GL_INVALID_VALUE);
6123 es2::Context *context = es2::getContext();
6127 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6128 context->setVertexAttrib(index, vals);
6132 void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6134 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
6136 if(index >= es2::MAX_VERTEX_ATTRIBS)
6138 return error(GL_INVALID_VALUE);
6141 es2::Context *context = es2::getContext();
6145 GLfloat vals[4] = { x, y, z, w };
6146 context->setVertexAttrib(index, vals);
6150 void VertexAttrib4fv(GLuint index, const GLfloat* values)
6152 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6154 if(index >= es2::MAX_VERTEX_ATTRIBS)
6156 return error(GL_INVALID_VALUE);
6159 es2::Context *context = es2::getContext();
6163 context->setVertexAttrib(index, values);
6167 void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
6169 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
6170 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
6171 index, size, type, normalized, stride, ptr);
6173 if(index >= es2::MAX_VERTEX_ATTRIBS)
6175 return error(GL_INVALID_VALUE);
6178 if(size < 1 || size > 4)
6180 return error(GL_INVALID_VALUE);
6183 GLint clientVersion = egl::getClientVersion();
6188 case GL_UNSIGNED_BYTE:
6190 case GL_UNSIGNED_SHORT:
6193 case GL_HALF_FLOAT_OES: // GL_OES_vertex_half_float
6195 case GL_INT_2_10_10_10_REV:
6196 case GL_UNSIGNED_INT_2_10_10_10_REV:
6197 if(clientVersion >= 3)
6201 return error(GL_INVALID_OPERATION);
6205 else return error(GL_INVALID_ENUM);
6207 case GL_UNSIGNED_INT:
6209 if(clientVersion >= 3)
6213 else return error(GL_INVALID_ENUM);
6215 return error(GL_INVALID_ENUM);
6220 return error(GL_INVALID_VALUE);
6223 es2::Context *context = es2::getContext();
6227 es2::VertexArray* vertexArray = context->getCurrentVertexArray();
6228 if((context->getArrayBufferName() == 0) && vertexArray && (vertexArray->name != 0) && ptr)
6230 // GL_INVALID_OPERATION is generated if a non-zero vertex array object is bound, zero is bound
6231 // to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.
6232 return error(GL_INVALID_OPERATION);
6235 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6239 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
6241 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
6243 if(width < 0 || height < 0)
6245 return error(GL_INVALID_VALUE);
6248 es2::Context *context = es2::getContext();
6252 context->setViewportParams(x, y, width, height);
6256 static void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter, bool allowPartialDepthStencilBlit)
6258 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6259 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6260 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6261 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6268 return error(GL_INVALID_ENUM);
6271 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6273 return error(GL_INVALID_VALUE);
6276 es2::Context *context = es2::getContext();
6280 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
6282 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6283 return error(GL_INVALID_OPERATION);
6286 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, false, allowPartialDepthStencilBlit);
6290 void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
6292 BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, true);
6295 void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6296 GLbitfield mask, GLenum filter)
6298 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6300 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6301 return error(GL_INVALID_OPERATION);
6304 BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, false);
6307 void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6308 GLint border, GLenum format, GLenum type, const GLvoid* data)
6310 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6311 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
6312 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
6313 target, level, internalformat, width, height, depth, border, format, type, data);
6317 case GL_TEXTURE_3D_OES:
6320 case GL_DEPTH_COMPONENT:
6321 case GL_DEPTH_STENCIL_OES:
6322 return error(GL_INVALID_OPERATION);
6328 return error(GL_INVALID_ENUM);
6331 if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
6336 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6338 return error(GL_INVALID_VALUE);
6341 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6342 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6344 return error(GL_INVALID_VALUE);
6349 return error(GL_INVALID_VALUE);
6352 es2::Context *context = es2::getContext();
6356 es2::Texture3D *texture = context->getTexture3D();
6360 return error(GL_INVALID_OPERATION);
6363 GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
6364 GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
6365 if(validationError != GL_NONE)
6367 return error(validationError);
6370 texture->setImage(context, level, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
6374 void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data)
6376 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6377 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6378 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
6379 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
6383 case GL_TEXTURE_3D_OES:
6386 return error(GL_INVALID_ENUM);
6389 if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
6394 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6396 return error(GL_INVALID_VALUE);
6399 if((width < 0) || (height < 0) || (depth < 0))
6401 return error(GL_INVALID_VALUE);
6404 es2::Context *context = es2::getContext();
6408 es2::Texture3D *texture = context->getTexture3D();
6410 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
6412 GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
6414 if(validationError == GL_NONE)
6416 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
6419 if(validationError == GL_NONE)
6421 texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
6425 return error(validationError);
6430 void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
6432 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6433 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
6434 target, level, xoffset, yoffset, zoffset, x, y, width, height);
6438 case GL_TEXTURE_3D_OES:
6441 return error(GL_INVALID_ENUM);
6444 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6446 return error(GL_INVALID_VALUE);
6449 es2::Context *context = es2::getContext();
6453 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6455 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
6457 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6460 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
6462 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
6464 return error(GL_INVALID_OPERATION);
6467 es2::Texture3D *texture = context->getTexture3D();
6469 GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
6471 if(validationError != GL_NONE)
6473 return error(validationError);
6476 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
6480 void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
6482 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
6483 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
6484 target, level, internalformat, width, height, depth, border, imageSize, data);
6488 case GL_TEXTURE_3D_OES:
6491 return error(GL_INVALID_ENUM);
6494 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6496 return error(GL_INVALID_VALUE);
6499 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6500 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6502 return error(GL_INVALID_VALUE);
6505 switch(internalformat)
6507 case GL_DEPTH_COMPONENT:
6508 case GL_DEPTH_COMPONENT16:
6509 case GL_DEPTH_COMPONENT32_OES:
6510 case GL_DEPTH_STENCIL_OES:
6511 case GL_DEPTH24_STENCIL8_OES:
6512 return error(GL_INVALID_OPERATION);
6515 GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
6516 if(validationError != GL_NONE)
6518 return error(validationError);
6523 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
6525 return error(GL_INVALID_VALUE);
6528 es2::Context *context = es2::getContext();
6532 es2::Texture3D *texture = context->getTexture3D();
6536 return error(GL_INVALID_OPERATION);
6539 GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
6541 if(validationError != GL_NONE)
6543 return error(validationError);
6546 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
6550 void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
6552 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6553 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6554 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
6555 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6559 case GL_TEXTURE_3D_OES:
6562 return error(GL_INVALID_ENUM);
6565 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6567 return error(GL_INVALID_VALUE);
6570 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6572 return error(GL_INVALID_VALUE);
6575 GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
6576 if(validationError != GL_NONE)
6578 return error(validationError);
6581 if(width == 0 || height == 0 || depth == 0)
6586 es2::Context *context = es2::getContext();
6590 es2::Texture3D *texture = context->getTexture3D();
6594 return error(GL_INVALID_OPERATION);
6597 GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
6599 if(validationError != GL_NONE)
6601 return error(validationError);
6604 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6608 void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
6610 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6611 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6613 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
6615 return error(GL_INVALID_ENUM);
6618 es2::Context *context = es2::getContext();
6624 textarget = GL_NONE;
6628 es2::Texture *tex = context->getTexture(texture);
6632 return error(GL_INVALID_OPERATION);
6635 if(tex->isCompressed(textarget, level))
6637 return error(GL_INVALID_OPERATION);
6642 case GL_TEXTURE_3D_OES:
6643 if(tex->getTarget() != GL_TEXTURE_3D_OES)
6645 return error(GL_INVALID_OPERATION);
6649 return error(GL_INVALID_ENUM);
6654 return error(GL_INVALID_VALUE);
6658 es2::Framebuffer *framebuffer = nullptr;
6659 GLuint framebufferName = 0;
6660 if(target == GL_READ_FRAMEBUFFER_ANGLE)
6662 framebuffer = context->getReadFramebuffer();
6663 framebufferName = context->getReadFramebufferName();
6667 framebuffer = context->getDrawFramebuffer();
6668 framebufferName = context->getDrawFramebufferName();
6671 if(framebufferName == 0 || !framebuffer)
6673 return error(GL_INVALID_OPERATION);
6676 GLint clientVersion = context->getClientVersion();
6680 case GL_COLOR_ATTACHMENT1:
6681 case GL_COLOR_ATTACHMENT2:
6682 case GL_COLOR_ATTACHMENT3:
6683 case GL_COLOR_ATTACHMENT4:
6684 case GL_COLOR_ATTACHMENT5:
6685 case GL_COLOR_ATTACHMENT6:
6686 case GL_COLOR_ATTACHMENT7:
6687 case GL_COLOR_ATTACHMENT8:
6688 case GL_COLOR_ATTACHMENT9:
6689 case GL_COLOR_ATTACHMENT10:
6690 case GL_COLOR_ATTACHMENT11:
6691 case GL_COLOR_ATTACHMENT12:
6692 case GL_COLOR_ATTACHMENT13:
6693 case GL_COLOR_ATTACHMENT14:
6694 case GL_COLOR_ATTACHMENT15:
6695 case GL_COLOR_ATTACHMENT16:
6696 case GL_COLOR_ATTACHMENT17:
6697 case GL_COLOR_ATTACHMENT18:
6698 case GL_COLOR_ATTACHMENT19:
6699 case GL_COLOR_ATTACHMENT20:
6700 case GL_COLOR_ATTACHMENT21:
6701 case GL_COLOR_ATTACHMENT22:
6702 case GL_COLOR_ATTACHMENT23:
6703 case GL_COLOR_ATTACHMENT24:
6704 case GL_COLOR_ATTACHMENT25:
6705 case GL_COLOR_ATTACHMENT26:
6706 case GL_COLOR_ATTACHMENT27:
6707 case GL_COLOR_ATTACHMENT28:
6708 case GL_COLOR_ATTACHMENT29:
6709 case GL_COLOR_ATTACHMENT30:
6710 case GL_COLOR_ATTACHMENT31:
6711 if(clientVersion < 3)
6713 return error(GL_INVALID_ENUM);
6716 case GL_COLOR_ATTACHMENT0:
6717 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
6719 return error(GL_INVALID_ENUM);
6721 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
6723 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
6724 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6726 return error(GL_INVALID_ENUM);
6731 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
6733 if(egl::getClientVersion() == 1)
6735 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
6738 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6743 case GL_TEXTURE_EXTERNAL_OES:
6746 return error(GL_INVALID_ENUM);
6749 es2::Context *context = es2::getContext();
6753 es2::Texture2D *texture = nullptr;
6757 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
6758 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
6759 default: UNREACHABLE(target);
6764 return error(GL_INVALID_OPERATION);
6767 egl::Image *eglImage = context->getSharedImage(image);
6771 return error(GL_INVALID_OPERATION);
6774 texture->setSharedImage(eglImage);
6778 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
6780 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6785 GLboolean IsRenderbufferOES(GLuint renderbuffer)
6787 return IsRenderbuffer(renderbuffer);
6790 void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
6792 BindRenderbuffer(target, renderbuffer);
6795 void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
6797 DeleteRenderbuffers(n, renderbuffers);
6800 void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
6802 GenRenderbuffers(n, renderbuffers);
6805 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
6807 RenderbufferStorage(target, internalformat, width, height);
6810 void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
6812 GetRenderbufferParameteriv(target, pname, params);
6815 GLboolean IsFramebufferOES(GLuint framebuffer)
6817 return IsFramebuffer(framebuffer);
6820 void BindFramebufferOES(GLenum target, GLuint framebuffer)
6822 BindFramebuffer(target, framebuffer);
6825 void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
6827 DeleteFramebuffers(n, framebuffers);
6830 void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
6832 GenFramebuffers(n, framebuffers);
6835 GLenum CheckFramebufferStatusOES(GLenum target)
6837 return CheckFramebufferStatus(target);
6840 void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
6842 FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
6845 void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
6847 FramebufferTexture2D(target, attachment, textarget, texture, level);
6850 void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
6852 GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
6855 void GenerateMipmapOES(GLenum target)
6857 GenerateMipmap(target);
6860 void DrawBuffersEXT(GLsizei n, const GLenum *bufs)
6862 TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);
6864 if(n < 0 || n > MAX_DRAW_BUFFERS)
6866 return error(GL_INVALID_VALUE);
6869 es2::Context *context = es2::getContext();
6873 GLuint drawFramebufferName = context->getDrawFramebufferName();
6875 if((drawFramebufferName == 0) && (n != 1))
6877 return error(GL_INVALID_OPERATION);
6880 for(unsigned int i = 0; i < (unsigned)n; i++)
6885 if(drawFramebufferName != 0)
6887 return error(GL_INVALID_OPERATION);
6892 case GL_COLOR_ATTACHMENT0_EXT:
6893 case GL_COLOR_ATTACHMENT1_EXT:
6894 case GL_COLOR_ATTACHMENT2_EXT:
6895 case GL_COLOR_ATTACHMENT3_EXT:
6896 case GL_COLOR_ATTACHMENT4_EXT:
6897 case GL_COLOR_ATTACHMENT5_EXT:
6898 case GL_COLOR_ATTACHMENT6_EXT:
6899 case GL_COLOR_ATTACHMENT7_EXT:
6900 case GL_COLOR_ATTACHMENT8_EXT:
6901 case GL_COLOR_ATTACHMENT9_EXT:
6902 case GL_COLOR_ATTACHMENT10_EXT:
6903 case GL_COLOR_ATTACHMENT11_EXT:
6904 case GL_COLOR_ATTACHMENT12_EXT:
6905 case GL_COLOR_ATTACHMENT13_EXT:
6906 case GL_COLOR_ATTACHMENT14_EXT:
6907 case GL_COLOR_ATTACHMENT15_EXT:
6909 GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0_EXT);
6911 if(index >= MAX_COLOR_ATTACHMENTS)
6913 return error(GL_INVALID_OPERATION);
6918 return error(GL_INVALID_OPERATION);
6921 if(drawFramebufferName == 0)
6923 return error(GL_INVALID_OPERATION);
6928 return error(GL_INVALID_ENUM);
6932 context->setFramebufferDrawBuffers(n, bufs);
6938 extern "C" NO_SANITIZE_FUNCTION __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
6943 __eglMustCastToProperFunctionPointerType address;
6946 static const Extension glExtensions[] =
6948 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6950 EXTENSION(glTexImage3DOES),
6951 EXTENSION(glBlitFramebufferANGLE),
6952 EXTENSION(glBlitFramebufferNV),
6953 EXTENSION(glRenderbufferStorageMultisampleANGLE),
6954 EXTENSION(glDeleteFencesNV),
6955 EXTENSION(glGenFencesNV),
6956 EXTENSION(glIsFenceNV),
6957 EXTENSION(glTestFenceNV),
6958 EXTENSION(glGetFenceivNV),
6959 EXTENSION(glFinishFenceNV),
6960 EXTENSION(glSetFenceNV),
6961 EXTENSION(glGetGraphicsResetStatusEXT),
6962 EXTENSION(glReadnPixelsEXT),
6963 EXTENSION(glGetnUniformfvEXT),
6964 EXTENSION(glGetnUniformivEXT),
6965 EXTENSION(glGenQueriesEXT),
6966 EXTENSION(glDeleteQueriesEXT),
6967 EXTENSION(glIsQueryEXT),
6968 EXTENSION(glBeginQueryEXT),
6969 EXTENSION(glEndQueryEXT),
6970 EXTENSION(glGetQueryivEXT),
6971 EXTENSION(glGetQueryObjectuivEXT),
6972 EXTENSION(glEGLImageTargetTexture2DOES),
6973 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
6974 EXTENSION(glDrawElementsInstancedEXT),
6975 EXTENSION(glDrawArraysInstancedEXT),
6976 EXTENSION(glVertexAttribDivisorEXT),
6977 EXTENSION(glDrawArraysInstancedANGLE),
6978 EXTENSION(glDrawElementsInstancedANGLE),
6979 EXTENSION(glVertexAttribDivisorANGLE),
6980 EXTENSION(glIsRenderbufferOES),
6981 EXTENSION(glBindRenderbufferOES),
6982 EXTENSION(glDeleteRenderbuffersOES),
6983 EXTENSION(glGenRenderbuffersOES),
6984 EXTENSION(glRenderbufferStorageOES),
6985 EXTENSION(glGetRenderbufferParameterivOES),
6986 EXTENSION(glIsFramebufferOES),
6987 EXTENSION(glBindFramebufferOES),
6988 EXTENSION(glDeleteFramebuffersOES),
6989 EXTENSION(glGenFramebuffersOES),
6990 EXTENSION(glCheckFramebufferStatusOES),
6991 EXTENSION(glFramebufferRenderbufferOES),
6992 EXTENSION(glFramebufferTexture2DOES),
6993 EXTENSION(glGetFramebufferAttachmentParameterivOES),
6994 EXTENSION(glGenerateMipmapOES),
6995 EXTENSION(glDrawBuffersEXT),
7000 for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
7002 if(strcmp(procname, glExtensions[ext].name) == 0)
7004 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;