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>
41 #include <cutils/log.h>
47 static bool validImageSize(GLint level, GLsizei width, GLsizei height)
49 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
57 void ActiveTexture(GLenum texture)
59 TRACE("(GLenum texture = 0x%X)", texture);
61 es2::Context *context = es2::getContext();
65 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
67 return error(GL_INVALID_ENUM);
70 context->setActiveSampler(texture - GL_TEXTURE0);
74 void AttachShader(GLuint program, GLuint shader)
76 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
78 es2::Context *context = es2::getContext();
82 es2::Program *programObject = context->getProgram(program);
83 es2::Shader *shaderObject = context->getShader(shader);
87 if(context->getShader(program))
89 return error(GL_INVALID_OPERATION);
93 return error(GL_INVALID_VALUE);
99 if(context->getProgram(shader))
101 return error(GL_INVALID_OPERATION);
105 return error(GL_INVALID_VALUE);
109 if(!programObject->attachShader(shaderObject))
111 return error(GL_INVALID_OPERATION);
116 void BeginQueryEXT(GLenum target, GLuint name)
118 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
122 case GL_ANY_SAMPLES_PASSED_EXT:
123 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
126 return error(GL_INVALID_ENUM);
131 return error(GL_INVALID_OPERATION);
134 es2::Context *context = es2::getContext();
138 context->beginQuery(target, name);
142 void BindAttribLocation(GLuint program, GLuint index, const GLchar* name)
144 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
146 if(index >= es2::MAX_VERTEX_ATTRIBS)
148 return error(GL_INVALID_VALUE);
151 es2::Context *context = es2::getContext();
155 es2::Program *programObject = context->getProgram(program);
159 if(context->getShader(program))
161 return error(GL_INVALID_OPERATION);
165 return error(GL_INVALID_VALUE);
169 if(strncmp(name, "gl_", 3) == 0)
171 return error(GL_INVALID_OPERATION);
174 programObject->bindAttributeLocation(index, name);
178 void BindBuffer(GLenum target, GLuint buffer)
180 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
182 es2::Context *context = es2::getContext();
186 GLint clientVersion = egl::getClientVersion();
190 case GL_ARRAY_BUFFER:
191 context->bindArrayBuffer(buffer);
193 case GL_ELEMENT_ARRAY_BUFFER:
194 context->bindElementArrayBuffer(buffer);
196 case GL_COPY_READ_BUFFER:
197 if(clientVersion >= 3)
199 context->bindCopyReadBuffer(buffer);
202 else return error(GL_INVALID_ENUM);
203 case GL_COPY_WRITE_BUFFER:
204 if(clientVersion >= 3)
206 context->bindCopyWriteBuffer(buffer);
209 else return error(GL_INVALID_ENUM);
210 case GL_PIXEL_PACK_BUFFER:
211 if(clientVersion >= 3)
213 context->bindPixelPackBuffer(buffer);
216 else return error(GL_INVALID_ENUM);
217 case GL_PIXEL_UNPACK_BUFFER:
218 if(clientVersion >= 3)
220 context->bindPixelUnpackBuffer(buffer);
223 else return error(GL_INVALID_ENUM);
224 case GL_TRANSFORM_FEEDBACK_BUFFER:
225 if(clientVersion >= 3)
227 context->bindTransformFeedbackBuffer(buffer);
230 else return error(GL_INVALID_ENUM);
231 case GL_UNIFORM_BUFFER:
232 if(clientVersion >= 3)
234 context->bindGenericUniformBuffer(buffer);
237 else return error(GL_INVALID_ENUM);
239 return error(GL_INVALID_ENUM);
244 void BindFramebuffer(GLenum target, GLuint framebuffer)
246 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
248 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
250 return error(GL_INVALID_ENUM);
253 es2::Context *context = es2::getContext();
257 if(target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
259 context->bindReadFramebuffer(framebuffer);
262 if(target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
264 context->bindDrawFramebuffer(framebuffer);
269 void BindRenderbuffer(GLenum target, GLuint renderbuffer)
271 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
273 if(target != GL_RENDERBUFFER)
275 return error(GL_INVALID_ENUM);
278 es2::Context *context = es2::getContext();
282 // [OpenGL ES 2.0.25] Section 4.4.3 page 110
283 // [OpenGL ES 3.0.4] Section 4.4.2 page 204
284 // If renderbuffer is not zero, then the resulting renderbuffer object
285 // is a new state vector, initialized with a zero-sized memory buffer.
286 context->bindRenderbuffer(renderbuffer);
290 void BindTexture(GLenum target, GLuint texture)
292 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
294 es2::Context *context = es2::getContext();
298 es2::Texture *textureObject = context->getTexture(texture);
300 if(textureObject && textureObject->getTarget() != target && texture != 0)
302 return error(GL_INVALID_OPERATION);
305 GLint clientVersion = context->getClientVersion();
310 context->bindTexture(TEXTURE_2D, texture);
312 case GL_TEXTURE_CUBE_MAP:
313 context->bindTexture(TEXTURE_CUBE, texture);
315 case GL_TEXTURE_EXTERNAL_OES:
316 context->bindTexture(TEXTURE_EXTERNAL, texture);
318 case GL_TEXTURE_2D_ARRAY:
319 if(clientVersion < 3)
321 return error(GL_INVALID_ENUM);
323 context->bindTexture(TEXTURE_2D_ARRAY, texture);
326 context->bindTexture(TEXTURE_3D, texture);
328 case GL_TEXTURE_RECTANGLE_ARB:
329 context->bindTexture(TEXTURE_2D_RECT, texture);
332 return error(GL_INVALID_ENUM);
337 void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
339 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
340 red, green, blue, alpha);
342 es2::Context* context = es2::getContext();
346 context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));
350 void BlendEquation(GLenum mode)
352 glBlendEquationSeparate(mode, mode);
355 void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
357 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
362 case GL_FUNC_SUBTRACT:
363 case GL_FUNC_REVERSE_SUBTRACT:
368 return error(GL_INVALID_ENUM);
374 case GL_FUNC_SUBTRACT:
375 case GL_FUNC_REVERSE_SUBTRACT:
380 return error(GL_INVALID_ENUM);
383 es2::Context *context = es2::getContext();
387 context->setBlendEquation(modeRGB, modeAlpha);
391 void BlendFunc(GLenum sfactor, GLenum dfactor)
393 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
396 void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
398 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
399 srcRGB, dstRGB, srcAlpha, dstAlpha);
401 GLint clientVersion = egl::getClientVersion();
408 case GL_ONE_MINUS_SRC_COLOR:
410 case GL_ONE_MINUS_DST_COLOR:
412 case GL_ONE_MINUS_SRC_ALPHA:
414 case GL_ONE_MINUS_DST_ALPHA:
415 case GL_CONSTANT_COLOR:
416 case GL_ONE_MINUS_CONSTANT_COLOR:
417 case GL_CONSTANT_ALPHA:
418 case GL_ONE_MINUS_CONSTANT_ALPHA:
419 case GL_SRC_ALPHA_SATURATE:
422 return error(GL_INVALID_ENUM);
430 case GL_ONE_MINUS_SRC_COLOR:
432 case GL_ONE_MINUS_DST_COLOR:
434 case GL_ONE_MINUS_SRC_ALPHA:
436 case GL_ONE_MINUS_DST_ALPHA:
437 case GL_CONSTANT_COLOR:
438 case GL_ONE_MINUS_CONSTANT_COLOR:
439 case GL_CONSTANT_ALPHA:
440 case GL_ONE_MINUS_CONSTANT_ALPHA:
442 case GL_SRC_ALPHA_SATURATE:
443 if(clientVersion < 3)
445 return error(GL_INVALID_ENUM);
449 return error(GL_INVALID_ENUM);
457 case GL_ONE_MINUS_SRC_COLOR:
459 case GL_ONE_MINUS_DST_COLOR:
461 case GL_ONE_MINUS_SRC_ALPHA:
463 case GL_ONE_MINUS_DST_ALPHA:
464 case GL_CONSTANT_COLOR:
465 case GL_ONE_MINUS_CONSTANT_COLOR:
466 case GL_CONSTANT_ALPHA:
467 case GL_ONE_MINUS_CONSTANT_ALPHA:
468 case GL_SRC_ALPHA_SATURATE:
471 return error(GL_INVALID_ENUM);
479 case GL_ONE_MINUS_SRC_COLOR:
481 case GL_ONE_MINUS_DST_COLOR:
483 case GL_ONE_MINUS_SRC_ALPHA:
485 case GL_ONE_MINUS_DST_ALPHA:
486 case GL_CONSTANT_COLOR:
487 case GL_ONE_MINUS_CONSTANT_COLOR:
488 case GL_CONSTANT_ALPHA:
489 case GL_ONE_MINUS_CONSTANT_ALPHA:
491 case GL_SRC_ALPHA_SATURATE:
492 if(clientVersion < 3)
494 return error(GL_INVALID_ENUM);
498 return error(GL_INVALID_ENUM);
501 es2::Context *context = es2::getContext();
505 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
509 void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
511 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
513 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
514 target, size, data, usage);
518 return error(GL_INVALID_VALUE);
521 GLint clientVersion = egl::getClientVersion();
527 case GL_DYNAMIC_DRAW:
533 case GL_DYNAMIC_READ:
534 case GL_DYNAMIC_COPY:
535 if(clientVersion < 3)
537 return error(GL_INVALID_ENUM);
541 return error(GL_INVALID_ENUM);
544 es2::Context *context = es2::getContext();
548 es2::Buffer *buffer = nullptr;
549 if(!context->getBuffer(target, &buffer))
551 return error(GL_INVALID_ENUM);
556 // A null buffer means that "0" is bound to the requested buffer target
557 return error(GL_INVALID_OPERATION);
560 buffer->bufferData(data, size, usage);
564 void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
566 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
567 offset = static_cast<GLint>(offset);
569 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
570 target, offset, size, data);
572 if(size < 0 || offset < 0)
574 return error(GL_INVALID_VALUE);
577 es2::Context *context = es2::getContext();
581 es2::Buffer *buffer = nullptr;
582 if(!context->getBuffer(target, &buffer))
584 return error(GL_INVALID_ENUM);
589 // A null buffer means that "0" is bound to the requested buffer target
590 return error(GL_INVALID_OPERATION);
593 if(buffer->isMapped())
595 // It is an invalid operation to update an already mapped buffer
596 return error(GL_INVALID_OPERATION);
599 if((size_t)size + offset > buffer->size())
601 return error(GL_INVALID_VALUE);
604 buffer->bufferSubData(data, size, offset);
608 GLenum CheckFramebufferStatus(GLenum target)
610 TRACE("(GLenum target = 0x%X)", target);
612 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
614 return error(GL_INVALID_ENUM, 0);
617 es2::Context *context = es2::getContext();
621 es2::Framebuffer *framebuffer = nullptr;
622 if(target == GL_READ_FRAMEBUFFER)
624 framebuffer = context->getReadFramebuffer();
628 framebuffer = context->getDrawFramebuffer();
633 return GL_FRAMEBUFFER_UNDEFINED_OES;
636 return framebuffer->completeness();
642 void Clear(GLbitfield mask)
644 TRACE("(GLbitfield mask = %X)", mask);
646 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
648 return error(GL_INVALID_VALUE);
651 es2::Context *context = es2::getContext();
655 context->clear(mask);
659 void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
661 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
662 red, green, blue, alpha);
664 es2::Context *context = es2::getContext();
668 context->setClearColor(red, green, blue, alpha);
672 void ClearDepthf(GLclampf depth)
674 TRACE("(GLclampf depth = %f)", depth);
676 es2::Context *context = es2::getContext();
680 context->setClearDepth(depth);
684 void ClearStencil(GLint s)
686 TRACE("(GLint s = %d)", s);
688 es2::Context *context = es2::getContext();
692 context->setClearStencil(s);
696 void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
698 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
699 red, green, blue, alpha);
701 es2::Context *context = es2::getContext();
705 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
709 void CompileShader(GLuint shader)
711 TRACE("(GLuint shader = %d)", shader);
713 es2::Context *context = es2::getContext();
717 es2::Shader *shaderObject = context->getShader(shader);
721 if(context->getProgram(shader))
723 return error(GL_INVALID_OPERATION);
727 return error(GL_INVALID_VALUE);
731 shaderObject->compile();
735 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
736 GLint border, GLsizei imageSize, const GLvoid* data)
738 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
739 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
740 target, level, internalformat, width, height, border, imageSize, data);
742 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
744 return error(GL_INVALID_VALUE);
747 if(!IsCompressed(internalformat, egl::getClientVersion()))
749 return error(GL_INVALID_ENUM);
754 return error(GL_INVALID_VALUE);
757 es2::Context *context = es2::getContext();
761 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
763 return error(GL_INVALID_VALUE);
769 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
770 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
772 return error(GL_INVALID_VALUE);
775 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
776 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
777 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
778 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
779 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
780 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
783 return error(GL_INVALID_VALUE);
786 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
787 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
789 return error(GL_INVALID_VALUE);
792 case GL_TEXTURE_RECTANGLE_ARB: // Rectangle textures cannot be compressed
794 return error(GL_INVALID_ENUM);
797 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
799 return error(GL_INVALID_VALUE);
802 GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
803 if(validationError != GL_NO_ERROR)
805 return error(validationError);
808 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
810 es2::Texture2D *texture = context->getTexture2D(target);
814 return error(GL_INVALID_OPERATION);
817 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
819 else if(es2::IsCubemapTextureTarget(target))
821 es2::TextureCubeMap *texture = context->getTextureCubeMap();
825 return error(GL_INVALID_OPERATION);
828 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
830 else UNREACHABLE(target);
834 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
835 GLenum format, GLsizei imageSize, const GLvoid* data)
837 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
838 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
839 "GLsizei imageSize = %d, const GLvoid* data = %p)",
840 target, level, xoffset, yoffset, width, height, format, imageSize, data);
842 if(!es2::IsTextureTarget(target))
844 return error(GL_INVALID_ENUM);
847 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
849 return error(GL_INVALID_VALUE);
852 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
854 return error(GL_INVALID_VALUE);
857 if(imageSize != gl::ComputeCompressedSize(width, height, format))
859 return error(GL_INVALID_VALUE);
862 es2::Context *context = es2::getContext();
866 if(xoffset % 4 != 0 || yoffset % 4 != 0)
868 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
869 return error(GL_INVALID_OPERATION);
872 GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
873 if(validationError != GL_NO_ERROR)
875 return error(validationError);
878 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
880 es2::Texture2D *texture = context->getTexture2D(target);
882 GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
883 if(validationError != GL_NO_ERROR)
885 return error(validationError);
888 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
890 else if(es2::IsCubemapTextureTarget(target))
892 es2::TextureCubeMap *texture = context->getTextureCubeMap();
894 GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
895 if(validationError != GL_NO_ERROR)
897 return error(validationError);
900 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
902 else UNREACHABLE(target);
906 void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
908 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
909 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
910 target, level, internalformat, x, y, width, height, border);
912 if(!validImageSize(level, width, height))
914 return error(GL_INVALID_VALUE);
919 return error(GL_INVALID_VALUE);
922 es2::Context *context = es2::getContext();
928 case GL_TEXTURE_RECTANGLE_ARB:
931 return error(GL_INVALID_VALUE);
933 // Fall through to GL_TEXTURE_2D case.
935 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
936 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
938 return error(GL_INVALID_VALUE);
941 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
942 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
943 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
944 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
945 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
946 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
949 return error(GL_INVALID_VALUE);
952 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
953 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
955 return error(GL_INVALID_VALUE);
959 return error(GL_INVALID_ENUM);
962 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
964 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
966 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
969 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
971 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
973 return error(GL_INVALID_OPERATION);
976 GLenum colorbufferFormat = source->getFormat();
978 // Determine the sized internal format.
979 if(gl::IsUnsizedInternalFormat(internalformat))
981 if(gl::GetBaseInternalFormat(colorbufferFormat) == internalformat)
983 internalformat = colorbufferFormat;
985 else if(GetColorComponentType(colorbufferFormat) == GL_UNSIGNED_NORMALIZED && GetRedSize(colorbufferFormat) <= 8)
987 // TODO: Convert to the smallest format that fits all components.
988 // e.g. Copying RGBA4 to RGB should result in RGB565, not RGB8.
990 internalformat = gl::GetSizedInternalFormat(internalformat, GL_UNSIGNED_BYTE);
992 else if(GetColorComponentType(colorbufferFormat) == GL_INT)
994 internalformat = gl::GetSizedInternalFormat(internalformat, GL_INT);
996 else if(GetColorComponentType(colorbufferFormat) == GL_UNSIGNED_INT)
998 internalformat = gl::GetSizedInternalFormat(internalformat, GL_UNSIGNED_INT);
1000 else if(GetColorComponentType(colorbufferFormat) == GL_FLOAT && GetRedSize(colorbufferFormat) == 16) // GL_EXT_color_buffer_half_float
1002 internalformat = gl::GetSizedInternalFormat(internalformat, GL_HALF_FLOAT_OES);
1008 return error(GL_INVALID_OPERATION);
1012 if(!ValidateCopyFormats(internalformat, colorbufferFormat))
1017 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
1019 es2::Texture2D *texture = context->getTexture2D(target);
1023 return error(GL_INVALID_OPERATION);
1026 texture->copyImage(level, internalformat, x, y, width, height, source);
1028 else if(es2::IsCubemapTextureTarget(target))
1030 es2::TextureCubeMap *texture = context->getTextureCubeMap();
1034 return error(GL_INVALID_OPERATION);
1037 texture->copyImage(target, level, internalformat, x, y, width, height, source);
1039 else UNREACHABLE(target);
1043 void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1045 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1046 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1047 target, level, xoffset, yoffset, x, y, width, height);
1049 if(!es2::IsTextureTarget(target))
1051 return error(GL_INVALID_ENUM);
1054 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1056 return error(GL_INVALID_VALUE);
1059 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1061 return error(GL_INVALID_VALUE);
1064 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1066 return error(GL_INVALID_VALUE);
1069 es2::Context *context = es2::getContext();
1073 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
1075 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
1077 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1080 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
1082 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
1084 return error(GL_INVALID_OPERATION);
1087 es2::Texture *texture = nullptr;
1089 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
1091 texture = context->getTexture2D(target);
1093 else if(es2::IsCubemapTextureTarget(target))
1095 texture = context->getTextureCubeMap();
1097 else UNREACHABLE(target);
1099 GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE, GL_NONE, texture, context->getClientVersion());
1100 if(validationError != GL_NO_ERROR)
1102 return error(validationError);
1105 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, source);
1109 GLuint CreateProgram(void)
1113 es2::Context *context = es2::getContext();
1117 return context->createProgram();
1123 GLuint CreateShader(GLenum type)
1125 TRACE("(GLenum type = 0x%X)", type);
1127 es2::Context *context = es2::getContext();
1133 case GL_FRAGMENT_SHADER:
1134 case GL_VERTEX_SHADER:
1135 return context->createShader(type);
1137 return error(GL_INVALID_ENUM, 0);
1144 void CullFace(GLenum mode)
1146 TRACE("(GLenum mode = 0x%X)", mode);
1152 case GL_FRONT_AND_BACK:
1154 es2::Context *context = es2::getContext();
1158 context->setCullMode(mode);
1163 return error(GL_INVALID_ENUM);
1167 void DeleteBuffers(GLsizei n, const GLuint* buffers)
1169 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
1173 return error(GL_INVALID_VALUE);
1176 es2::Context *context = es2::getContext();
1180 for(int i = 0; i < n; i++)
1182 context->deleteBuffer(buffers[i]);
1187 void DeleteFencesNV(GLsizei n, const GLuint* fences)
1189 TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
1193 return error(GL_INVALID_VALUE);
1196 es2::Context *context = es2::getContext();
1200 for(int i = 0; i < n; i++)
1202 context->deleteFence(fences[i]);
1207 void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1209 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
1213 return error(GL_INVALID_VALUE);
1216 es2::Context *context = es2::getContext();
1220 for(int i = 0; i < n; i++)
1222 if(framebuffers[i] != 0)
1224 context->deleteFramebuffer(framebuffers[i]);
1230 void DeleteProgram(GLuint program)
1232 TRACE("(GLuint program = %d)", program);
1239 es2::Context *context = es2::getContext();
1243 if(!context->getProgram(program))
1245 if(context->getShader(program))
1247 return error(GL_INVALID_OPERATION);
1251 return error(GL_INVALID_VALUE);
1255 context->deleteProgram(program);
1259 void DeleteQueriesEXT(GLsizei n, const GLuint *ids)
1261 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
1265 return error(GL_INVALID_VALUE);
1268 es2::Context *context = es2::getContext();
1272 for(int i = 0; i < n; i++)
1274 context->deleteQuery(ids[i]);
1279 void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1281 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
1285 return error(GL_INVALID_VALUE);
1288 es2::Context *context = es2::getContext();
1292 for(int i = 0; i < n; i++)
1294 context->deleteRenderbuffer(renderbuffers[i]);
1299 void DeleteShader(GLuint shader)
1301 TRACE("(GLuint shader = %d)", shader);
1308 es2::Context *context = es2::getContext();
1312 if(!context->getShader(shader))
1314 if(context->getProgram(shader))
1316 return error(GL_INVALID_OPERATION);
1320 return error(GL_INVALID_VALUE);
1324 context->deleteShader(shader);
1328 void DeleteTextures(GLsizei n, const GLuint* textures)
1330 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
1334 return error(GL_INVALID_VALUE);
1337 es2::Context *context = es2::getContext();
1341 for(int i = 0; i < n; i++)
1343 if(textures[i] != 0)
1345 context->deleteTexture(textures[i]);
1351 void DepthFunc(GLenum func)
1353 TRACE("(GLenum func = 0x%X)", func);
1367 return error(GL_INVALID_ENUM);
1370 es2::Context *context = es2::getContext();
1374 context->setDepthFunc(func);
1378 void DepthMask(GLboolean flag)
1380 TRACE("(GLboolean flag = %d)", flag);
1382 es2::Context *context = es2::getContext();
1386 context->setDepthMask(flag != GL_FALSE);
1390 void DepthRangef(GLclampf zNear, GLclampf zFar)
1392 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1394 es2::Context *context = es2::getContext();
1398 context->setDepthRange(zNear, zFar);
1402 void DetachShader(GLuint program, GLuint shader)
1404 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
1406 es2::Context *context = es2::getContext();
1411 es2::Program *programObject = context->getProgram(program);
1412 es2::Shader *shaderObject = context->getShader(shader);
1416 es2::Shader *shaderByProgramHandle;
1417 shaderByProgramHandle = context->getShader(program);
1418 if(!shaderByProgramHandle)
1420 return error(GL_INVALID_VALUE);
1424 return error(GL_INVALID_OPERATION);
1430 es2::Program *programByShaderHandle = context->getProgram(shader);
1431 if(!programByShaderHandle)
1433 return error(GL_INVALID_VALUE);
1437 return error(GL_INVALID_OPERATION);
1441 if(!programObject->detachShader(shaderObject))
1443 return error(GL_INVALID_OPERATION);
1448 void Disable(GLenum cap)
1450 TRACE("(GLenum cap = 0x%X)", cap);
1452 es2::Context *context = es2::getContext();
1458 case GL_CULL_FACE: context->setCullFaceEnabled(false); break;
1459 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(false); break;
1460 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;
1461 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(false); break;
1462 case GL_SCISSOR_TEST: context->setScissorTestEnabled(false); break;
1463 case GL_STENCIL_TEST: context->setStencilTestEnabled(false); break;
1464 case GL_DEPTH_TEST: context->setDepthTestEnabled(false); break;
1465 case GL_BLEND: context->setBlendEnabled(false); break;
1466 case GL_DITHER: context->setDitherEnabled(false); break;
1467 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(false); break;
1468 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscardEnabled(false); break;
1470 return error(GL_INVALID_ENUM);
1475 void DisableVertexAttribArray(GLuint index)
1477 TRACE("(GLuint index = %d)", index);
1479 if(index >= es2::MAX_VERTEX_ATTRIBS)
1481 return error(GL_INVALID_VALUE);
1484 es2::Context *context = es2::getContext();
1488 context->setVertexAttribArrayEnabled(index, false);
1492 void DrawArrays(GLenum mode, GLint first, GLsizei count)
1494 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1503 case GL_TRIANGLE_FAN:
1504 case GL_TRIANGLE_STRIP:
1507 return error(GL_INVALID_ENUM);
1510 if(count < 0 || first < 0)
1512 return error(GL_INVALID_VALUE);
1515 es2::Context *context = es2::getContext();
1519 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1520 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1522 return error(GL_INVALID_OPERATION);
1525 context->drawArrays(mode, first, count);
1529 void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
1531 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
1532 mode, count, type, indices);
1541 case GL_TRIANGLE_FAN:
1542 case GL_TRIANGLE_STRIP:
1545 return error(GL_INVALID_ENUM);
1550 return error(GL_INVALID_VALUE);
1553 es2::Context *context = es2::getContext();
1557 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1558 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1560 return error(GL_INVALID_OPERATION);
1565 case GL_UNSIGNED_BYTE:
1566 case GL_UNSIGNED_SHORT:
1567 case GL_UNSIGNED_INT:
1570 return error(GL_INVALID_ENUM);
1573 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices);
1577 void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1579 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1580 mode, first, count, instanceCount);
1589 case GL_TRIANGLE_FAN:
1590 case GL_TRIANGLE_STRIP:
1593 return error(GL_INVALID_ENUM);
1596 if(count < 0 || instanceCount < 0)
1598 return error(GL_INVALID_VALUE);
1601 es2::Context *context = es2::getContext();
1605 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1606 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1608 return error(GL_INVALID_OPERATION);
1611 context->drawArrays(mode, first, count, instanceCount);
1615 void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
1617 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
1618 mode, count, type, indices, instanceCount);
1627 case GL_TRIANGLE_FAN:
1628 case GL_TRIANGLE_STRIP:
1631 return error(GL_INVALID_ENUM);
1636 case GL_UNSIGNED_BYTE:
1637 case GL_UNSIGNED_SHORT:
1638 case GL_UNSIGNED_INT:
1641 return error(GL_INVALID_ENUM);
1644 if(count < 0 || instanceCount < 0)
1646 return error(GL_INVALID_VALUE);
1649 es2::Context *context = es2::getContext();
1653 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1654 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1656 return error(GL_INVALID_OPERATION);
1659 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
1663 void VertexAttribDivisorEXT(GLuint index, GLuint divisor)
1665 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1667 es2::Context *context = es2::getContext();
1671 if(index >= es2::MAX_VERTEX_ATTRIBS)
1673 return error(GL_INVALID_VALUE);
1676 context->setVertexAttribDivisor(index, divisor);
1680 void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1682 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1683 mode, first, count, instanceCount);
1692 case GL_TRIANGLE_FAN:
1693 case GL_TRIANGLE_STRIP:
1696 return error(GL_INVALID_ENUM);
1699 if(count < 0 || instanceCount < 0)
1701 return error(GL_INVALID_VALUE);
1704 es2::Context *context = es2::getContext();
1708 if(!context->hasZeroDivisor())
1710 return error(GL_INVALID_OPERATION);
1713 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1714 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1716 return error(GL_INVALID_OPERATION);
1719 context->drawArrays(mode, first, count, instanceCount);
1723 void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
1725 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
1726 mode, count, type, indices, instanceCount);
1735 case GL_TRIANGLE_FAN:
1736 case GL_TRIANGLE_STRIP:
1739 return error(GL_INVALID_ENUM);
1744 case GL_UNSIGNED_BYTE:
1745 case GL_UNSIGNED_SHORT:
1746 case GL_UNSIGNED_INT:
1749 return error(GL_INVALID_ENUM);
1752 if(count < 0 || instanceCount < 0)
1754 return error(GL_INVALID_VALUE);
1757 es2::Context *context = es2::getContext();
1761 if(!context->hasZeroDivisor())
1763 return error(GL_INVALID_OPERATION);
1766 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1767 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1769 return error(GL_INVALID_OPERATION);
1772 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
1776 void VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
1778 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1780 es2::Context *context = es2::getContext();
1784 if(index >= MAX_VERTEX_ATTRIBS)
1786 return error(GL_INVALID_VALUE);
1789 context->setVertexAttribDivisor(index, divisor);
1793 void Enable(GLenum cap)
1795 TRACE("(GLenum cap = 0x%X)", cap);
1797 es2::Context *context = es2::getContext();
1803 case GL_CULL_FACE: context->setCullFaceEnabled(true); break;
1804 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(true); break;
1805 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;
1806 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(true); break;
1807 case GL_SCISSOR_TEST: context->setScissorTestEnabled(true); break;
1808 case GL_STENCIL_TEST: context->setStencilTestEnabled(true); break;
1809 case GL_DEPTH_TEST: context->setDepthTestEnabled(true); break;
1810 case GL_BLEND: context->setBlendEnabled(true); break;
1811 case GL_DITHER: context->setDitherEnabled(true); break;
1812 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(true); break;
1813 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscardEnabled(true); break;
1815 return error(GL_INVALID_ENUM);
1820 void EnableVertexAttribArray(GLuint index)
1822 TRACE("(GLuint index = %d)", index);
1824 if(index >= es2::MAX_VERTEX_ATTRIBS)
1826 return error(GL_INVALID_VALUE);
1829 es2::Context *context = es2::getContext();
1833 context->setVertexAttribArrayEnabled(index, true);
1837 void EndQueryEXT(GLenum target)
1839 TRACE("GLenum target = 0x%X)", target);
1843 case GL_ANY_SAMPLES_PASSED_EXT:
1844 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1847 return error(GL_INVALID_ENUM);
1850 es2::Context *context = es2::getContext();
1854 context->endQuery(target);
1858 void FinishFenceNV(GLuint fence)
1860 TRACE("(GLuint fence = %d)", fence);
1862 es2::Context *context = es2::getContext();
1866 es2::Fence *fenceObject = context->getFence(fence);
1870 return error(GL_INVALID_OPERATION);
1873 fenceObject->finishFence();
1881 es2::Context *context = es2::getContext();
1893 es2::Context *context = es2::getContext();
1901 void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1903 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1904 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1906 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) ||
1907 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
1909 return error(GL_INVALID_ENUM);
1912 es2::Context *context = es2::getContext();
1916 es2::Framebuffer *framebuffer = nullptr;
1917 GLuint framebufferName = 0;
1918 if(target == GL_READ_FRAMEBUFFER)
1920 framebuffer = context->getReadFramebuffer();
1921 framebufferName = context->getReadFramebufferName();
1925 framebuffer = context->getDrawFramebuffer();
1926 framebufferName = context->getDrawFramebufferName();
1929 if(!framebuffer || framebufferName == 0)
1931 return error(GL_INVALID_OPERATION);
1934 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
1935 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
1936 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
1937 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
1938 if(renderbuffer != 0)
1940 if(!context->getRenderbuffer(renderbuffer))
1942 return error(GL_INVALID_OPERATION);
1946 GLint clientVersion = context->getClientVersion();
1950 case GL_COLOR_ATTACHMENT0:
1951 case GL_COLOR_ATTACHMENT1:
1952 case GL_COLOR_ATTACHMENT2:
1953 case GL_COLOR_ATTACHMENT3:
1954 case GL_COLOR_ATTACHMENT4:
1955 case GL_COLOR_ATTACHMENT5:
1956 case GL_COLOR_ATTACHMENT6:
1957 case GL_COLOR_ATTACHMENT7:
1958 case GL_COLOR_ATTACHMENT8:
1959 case GL_COLOR_ATTACHMENT9:
1960 case GL_COLOR_ATTACHMENT10:
1961 case GL_COLOR_ATTACHMENT11:
1962 case GL_COLOR_ATTACHMENT12:
1963 case GL_COLOR_ATTACHMENT13:
1964 case GL_COLOR_ATTACHMENT14:
1965 case GL_COLOR_ATTACHMENT15:
1966 case GL_COLOR_ATTACHMENT16:
1967 case GL_COLOR_ATTACHMENT17:
1968 case GL_COLOR_ATTACHMENT18:
1969 case GL_COLOR_ATTACHMENT19:
1970 case GL_COLOR_ATTACHMENT20:
1971 case GL_COLOR_ATTACHMENT21:
1972 case GL_COLOR_ATTACHMENT22:
1973 case GL_COLOR_ATTACHMENT23:
1974 case GL_COLOR_ATTACHMENT24:
1975 case GL_COLOR_ATTACHMENT25:
1976 case GL_COLOR_ATTACHMENT26:
1977 case GL_COLOR_ATTACHMENT27:
1978 case GL_COLOR_ATTACHMENT28:
1979 case GL_COLOR_ATTACHMENT29:
1980 case GL_COLOR_ATTACHMENT30:
1981 case GL_COLOR_ATTACHMENT31:
1982 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
1984 return error(GL_INVALID_ENUM);
1986 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0);
1988 case GL_DEPTH_ATTACHMENT:
1989 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1991 case GL_STENCIL_ATTACHMENT:
1992 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1994 case GL_DEPTH_STENCIL_ATTACHMENT:
1995 if(clientVersion >= 3)
1997 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1998 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2001 else return error(GL_INVALID_ENUM);
2003 return error(GL_INVALID_ENUM);
2008 void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2010 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
2011 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
2013 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
2015 return error(GL_INVALID_ENUM);
2018 es2::Context *context = es2::getContext();
2022 GLint clientVersion = context->getClientVersion();
2026 textarget = GL_NONE;
2030 es2::Texture *tex = context->getTexture(texture);
2034 return error(GL_INVALID_OPERATION);
2040 if(tex->getTarget() != GL_TEXTURE_2D)
2042 return error(GL_INVALID_OPERATION);
2045 case GL_TEXTURE_RECTANGLE_ARB:
2046 if(tex->getTarget() != GL_TEXTURE_RECTANGLE_ARB)
2048 return error(GL_INVALID_OPERATION);
2051 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2052 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2053 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2054 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2055 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2056 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2057 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2059 return error(GL_INVALID_OPERATION);
2063 return error(GL_INVALID_ENUM);
2066 if((level != 0) && ((clientVersion < 3) || (textarget == GL_TEXTURE_RECTANGLE_ARB)))
2068 return error(GL_INVALID_VALUE);
2071 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
2073 return error(GL_INVALID_VALUE);
2076 if(tex->isCompressed(textarget, level))
2078 return error(GL_INVALID_OPERATION);
2082 es2::Framebuffer *framebuffer = nullptr;
2083 GLuint framebufferName = 0;
2084 if(target == GL_READ_FRAMEBUFFER)
2086 framebuffer = context->getReadFramebuffer();
2087 framebufferName = context->getReadFramebufferName();
2091 framebuffer = context->getDrawFramebuffer();
2092 framebufferName = context->getDrawFramebufferName();
2095 if(framebufferName == 0 || !framebuffer)
2097 return error(GL_INVALID_OPERATION);
2102 case GL_COLOR_ATTACHMENT0:
2103 case GL_COLOR_ATTACHMENT1:
2104 case GL_COLOR_ATTACHMENT2:
2105 case GL_COLOR_ATTACHMENT3:
2106 case GL_COLOR_ATTACHMENT4:
2107 case GL_COLOR_ATTACHMENT5:
2108 case GL_COLOR_ATTACHMENT6:
2109 case GL_COLOR_ATTACHMENT7:
2110 case GL_COLOR_ATTACHMENT8:
2111 case GL_COLOR_ATTACHMENT9:
2112 case GL_COLOR_ATTACHMENT10:
2113 case GL_COLOR_ATTACHMENT11:
2114 case GL_COLOR_ATTACHMENT12:
2115 case GL_COLOR_ATTACHMENT13:
2116 case GL_COLOR_ATTACHMENT14:
2117 case GL_COLOR_ATTACHMENT15:
2118 case GL_COLOR_ATTACHMENT16:
2119 case GL_COLOR_ATTACHMENT17:
2120 case GL_COLOR_ATTACHMENT18:
2121 case GL_COLOR_ATTACHMENT19:
2122 case GL_COLOR_ATTACHMENT20:
2123 case GL_COLOR_ATTACHMENT21:
2124 case GL_COLOR_ATTACHMENT22:
2125 case GL_COLOR_ATTACHMENT23:
2126 case GL_COLOR_ATTACHMENT24:
2127 case GL_COLOR_ATTACHMENT25:
2128 case GL_COLOR_ATTACHMENT26:
2129 case GL_COLOR_ATTACHMENT27:
2130 case GL_COLOR_ATTACHMENT28:
2131 case GL_COLOR_ATTACHMENT29:
2132 case GL_COLOR_ATTACHMENT30:
2133 case GL_COLOR_ATTACHMENT31:
2134 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
2136 return error(GL_INVALID_ENUM);
2138 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);
2140 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level); break;
2141 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;
2142 case GL_DEPTH_STENCIL_ATTACHMENT:
2143 if(clientVersion >= 3)
2145 framebuffer->setDepthbuffer(textarget, texture, level);
2146 framebuffer->setStencilbuffer(textarget, texture, level);
2149 else return error(GL_INVALID_ENUM);
2151 return error(GL_INVALID_ENUM);
2156 void FrontFace(GLenum mode)
2158 TRACE("(GLenum mode = 0x%X)", mode);
2165 es2::Context *context = es2::getContext();
2169 context->setFrontFace(mode);
2174 return error(GL_INVALID_ENUM);
2178 void GenBuffers(GLsizei n, GLuint* buffers)
2180 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
2184 return error(GL_INVALID_VALUE);
2187 es2::Context *context = es2::getContext();
2191 for(int i = 0; i < n; i++)
2193 buffers[i] = context->createBuffer();
2198 void GenerateMipmap(GLenum target)
2200 TRACE("(GLenum target = 0x%X)", target);
2202 es2::Context *context = es2::getContext();
2206 es2::Texture *texture = nullptr;
2208 GLint clientVersion = context->getClientVersion();
2213 texture = context->getTexture2D();
2215 case GL_TEXTURE_CUBE_MAP:
2217 TextureCubeMap *cube = context->getTextureCubeMap();
2220 if(!cube->isCubeComplete())
2222 return error(GL_INVALID_OPERATION);
2226 case GL_TEXTURE_2D_ARRAY:
2227 if(clientVersion < 3)
2229 return error(GL_INVALID_ENUM);
2233 texture = context->getTexture2DArray();
2237 texture = context->getTexture3D();
2239 case GL_TEXTURE_RECTANGLE_ARB:
2240 texture = context->getTexture2DRect();
2243 return error(GL_INVALID_ENUM);
2246 if(!IsMipmappable(texture->getFormat(target, texture->getBaseLevel()), clientVersion))
2248 return error(GL_INVALID_OPERATION);
2251 texture->generateMipmaps();
2255 void GenFencesNV(GLsizei n, GLuint* fences)
2257 TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
2261 return error(GL_INVALID_VALUE);
2264 es2::Context *context = es2::getContext();
2268 for(int i = 0; i < n; i++)
2270 fences[i] = context->createFence();
2275 void GenFramebuffers(GLsizei n, GLuint* framebuffers)
2277 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
2281 return error(GL_INVALID_VALUE);
2284 es2::Context *context = es2::getContext();
2288 for(int i = 0; i < n; i++)
2290 framebuffers[i] = context->createFramebuffer();
2295 void GenQueriesEXT(GLsizei n, GLuint* ids)
2297 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
2301 return error(GL_INVALID_VALUE);
2304 es2::Context *context = es2::getContext();
2308 for(int i = 0; i < n; i++)
2310 ids[i] = context->createQuery();
2315 void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2317 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
2321 return error(GL_INVALID_VALUE);
2324 es2::Context *context = es2::getContext();
2328 for(int i = 0; i < n; i++)
2330 renderbuffers[i] = context->createRenderbuffer();
2335 void GenTextures(GLsizei n, GLuint* textures)
2337 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
2341 return error(GL_INVALID_VALUE);
2344 es2::Context *context = es2::getContext();
2348 for(int i = 0; i < n; i++)
2350 textures[i] = context->createTexture();
2355 void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
2357 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
2358 "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
2359 program, index, bufsize, length, size, type, name);
2363 return error(GL_INVALID_VALUE);
2366 es2::Context *context = es2::getContext();
2370 es2::Program *programObject = context->getProgram(program);
2374 if(context->getShader(program))
2376 return error(GL_INVALID_OPERATION);
2380 return error(GL_INVALID_VALUE);
2384 if(index >= programObject->getActiveAttributeCount())
2386 return error(GL_INVALID_VALUE);
2389 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2393 void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
2395 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2396 "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
2397 program, index, bufsize, length, size, type, name);
2401 return error(GL_INVALID_VALUE);
2404 es2::Context *context = es2::getContext();
2408 es2::Program *programObject = context->getProgram(program);
2412 if(context->getShader(program))
2414 return error(GL_INVALID_OPERATION);
2418 return error(GL_INVALID_VALUE);
2422 if(index >= programObject->getActiveUniformCount())
2424 return error(GL_INVALID_VALUE);
2427 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2431 void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2433 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
2434 program, maxcount, count, shaders);
2438 return error(GL_INVALID_VALUE);
2441 es2::Context *context = es2::getContext();
2445 es2::Program *programObject = context->getProgram(program);
2449 if(context->getShader(program))
2451 return error(GL_INVALID_OPERATION);
2455 return error(GL_INVALID_VALUE);
2459 return programObject->getAttachedShaders(maxcount, count, shaders);
2463 int GetAttribLocation(GLuint program, const GLchar* name)
2465 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
2467 es2::Context *context = es2::getContext();
2472 es2::Program *programObject = context->getProgram(program);
2476 if(context->getShader(program))
2478 return error(GL_INVALID_OPERATION, -1);
2482 return error(GL_INVALID_VALUE, -1);
2486 if(!programObject->isLinked())
2488 return error(GL_INVALID_OPERATION, -1);
2491 return programObject->getAttributeLocation(name);
2497 void GetBooleanv(GLenum pname, GLboolean* params)
2499 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params);
2501 es2::Context *context = es2::getContext();
2505 if(!(context->getBooleanv(pname, params)))
2508 unsigned int numParams = 0;
2509 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2510 return error(GL_INVALID_ENUM);
2513 return; // it is known that the pname is valid, but there are no parameters to return
2515 if(nativeType == GL_FLOAT)
2517 GLfloat *floatParams = nullptr;
2518 floatParams = new GLfloat[numParams];
2520 context->getFloatv(pname, floatParams);
2522 for(unsigned int i = 0; i < numParams; ++i)
2524 if(floatParams[i] == 0.0f)
2525 params[i] = GL_FALSE;
2527 params[i] = GL_TRUE;
2530 delete [] floatParams;
2532 else if(nativeType == GL_INT)
2534 GLint *intParams = nullptr;
2535 intParams = new GLint[numParams];
2537 context->getIntegerv(pname, intParams);
2539 for(unsigned int i = 0; i < numParams; ++i)
2541 if(intParams[i] == 0)
2542 params[i] = GL_FALSE;
2544 params[i] = GL_TRUE;
2547 delete [] intParams;
2553 void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2555 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
2557 es2::Context *context = es2::getContext();
2561 es2::Buffer *buffer;
2562 if(!context->getBuffer(target, &buffer))
2564 return error(GL_INVALID_ENUM);
2569 // A null buffer means that "0" is bound to the requested buffer target
2570 return error(GL_INVALID_OPERATION);
2573 GLint clientVersion = context->getClientVersion();
2577 case GL_BUFFER_USAGE:
2578 *params = buffer->usage();
2580 case GL_BUFFER_SIZE:
2581 *params = (GLint)buffer->size();
2583 case GL_BUFFER_ACCESS_FLAGS:
2584 if(clientVersion >= 3)
2586 *params = buffer->access();
2589 else return error(GL_INVALID_ENUM);
2590 case GL_BUFFER_MAPPED:
2591 if(clientVersion >= 3)
2593 *params = buffer->isMapped();
2596 else return error(GL_INVALID_ENUM);
2597 case GL_BUFFER_MAP_LENGTH:
2598 if(clientVersion >= 3)
2600 *params = (GLint)buffer->length();
2603 else return error(GL_INVALID_ENUM);
2604 case GL_BUFFER_MAP_OFFSET:
2605 if(clientVersion >= 3)
2607 *params = (GLint)buffer->offset();
2610 else return error(GL_INVALID_ENUM);
2612 return error(GL_INVALID_ENUM);
2617 GLenum GetError(void)
2621 es2::Context *context = es2::getContext();
2625 return context->getError();
2631 void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2633 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
2635 es2::Context *context = es2::getContext();
2639 es2::Fence *fenceObject = context->getFence(fence);
2643 return error(GL_INVALID_OPERATION);
2646 fenceObject->getFenceiv(pname, params);
2650 void GetFloatv(GLenum pname, GLfloat* params)
2652 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
2654 es2::Context *context = es2::getContext();
2658 if(!(context->getFloatv(pname, params)))
2661 unsigned int numParams = 0;
2662 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2663 return error(GL_INVALID_ENUM);
2666 return; // it is known that the pname is valid, but that there are no parameters to return.
2668 if(nativeType == GL_BOOL)
2670 GLboolean *boolParams = nullptr;
2671 boolParams = new GLboolean[numParams];
2673 context->getBooleanv(pname, boolParams);
2675 for(unsigned int i = 0; i < numParams; ++i)
2677 if(boolParams[i] == GL_FALSE)
2683 delete [] boolParams;
2685 else if(nativeType == GL_INT)
2687 GLint *intParams = nullptr;
2688 intParams = new GLint[numParams];
2690 context->getIntegerv(pname, intParams);
2692 for(unsigned int i = 0; i < numParams; ++i)
2694 params[i] = (GLfloat)intParams[i];
2697 delete [] intParams;
2703 void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2705 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
2706 target, attachment, pname, params);
2708 es2::Context *context = es2::getContext();
2712 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
2714 return error(GL_INVALID_ENUM);
2717 GLuint framebufferName = 0;
2719 if(target == GL_READ_FRAMEBUFFER)
2721 framebufferName = context->getReadFramebufferName();
2725 framebufferName = context->getDrawFramebufferName();
2728 GLint clientVersion = context->getClientVersion();
2730 if(framebufferName == 0) // Default framebuffer.
2732 if(clientVersion < 3)
2734 return error(GL_INVALID_OPERATION);
2743 if(clientVersion < 3)
2745 return error(GL_INVALID_ENUM);
2748 if(framebufferName != 0)
2750 return error(GL_INVALID_OPERATION);
2753 case GL_DEPTH_ATTACHMENT:
2754 case GL_STENCIL_ATTACHMENT:
2755 if(framebufferName == 0)
2757 return error(GL_INVALID_OPERATION);
2760 case GL_DEPTH_STENCIL_ATTACHMENT:
2761 if(clientVersion < 3)
2763 return error(GL_INVALID_ENUM);
2766 if(framebufferName == 0)
2768 return error(GL_INVALID_OPERATION);
2772 if((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS)
2774 if(framebufferName == 0)
2776 return error(GL_INVALID_OPERATION);
2779 else return error(GL_INVALID_ENUM);
2782 es2::Framebuffer *framebuffer = context->getFramebuffer(framebufferName);
2786 return error(GL_INVALID_OPERATION);
2789 GLenum attachmentType;
2790 GLuint attachmentHandle;
2791 GLint attachmentLayer;
2792 Renderbuffer *renderbuffer = nullptr;
2796 attachmentType = framebuffer->getColorbufferType(0);
2797 attachmentHandle = framebuffer->getColorbufferName(0);
2798 attachmentLayer = framebuffer->getColorbufferLayer(0);
2799 renderbuffer = framebuffer->getColorbuffer(0);
2802 case GL_DEPTH_ATTACHMENT:
2803 attachmentType = framebuffer->getDepthbufferType();
2804 attachmentHandle = framebuffer->getDepthbufferName();
2805 attachmentLayer = framebuffer->getDepthbufferLayer();
2806 renderbuffer = framebuffer->getDepthbuffer();
2809 case GL_STENCIL_ATTACHMENT:
2810 attachmentType = framebuffer->getStencilbufferType();
2811 attachmentHandle = framebuffer->getStencilbufferName();
2812 attachmentLayer = framebuffer->getStencilbufferLayer();
2813 renderbuffer = framebuffer->getStencilbuffer();
2815 case GL_DEPTH_STENCIL_ATTACHMENT:
2816 attachmentType = framebuffer->getDepthbufferType();
2817 attachmentHandle = framebuffer->getDepthbufferName();
2818 attachmentLayer = framebuffer->getDepthbufferLayer();
2819 renderbuffer = framebuffer->getDepthbuffer();
2821 if(attachmentHandle != framebuffer->getStencilbufferName())
2823 // Different attachments to DEPTH and STENCIL, query fails
2824 return error(GL_INVALID_OPERATION);
2828 ASSERT((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS);
2829 attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
2830 attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
2831 attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
2832 renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
2836 GLenum attachmentObjectType = GL_NONE; // Type category
2837 if(framebufferName == 0)
2839 attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
2841 else if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))
2843 attachmentObjectType = attachmentType;
2845 else if(es2::IsTextureTarget(attachmentType))
2847 attachmentObjectType = GL_TEXTURE;
2849 else UNREACHABLE(attachmentType);
2851 if(attachmentObjectType != GL_NONE)
2855 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2856 *params = attachmentObjectType;
2858 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2859 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2861 *params = attachmentHandle;
2865 return error(GL_INVALID_ENUM);
2868 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2869 if(attachmentObjectType == GL_TEXTURE)
2871 *params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // glFramebufferTexture2D does not allow level to be set to anything else in GL ES 2.0
2875 return error(GL_INVALID_ENUM);
2878 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2879 if(attachmentObjectType == GL_TEXTURE)
2881 if(es2::IsCubemapTextureTarget(attachmentType))
2883 *params = attachmentType;
2892 return error(GL_INVALID_ENUM);
2895 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
2896 if(clientVersion >= 3)
2898 *params = attachmentLayer;
2900 else return error(GL_INVALID_ENUM);
2902 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
2903 if(clientVersion >= 3)
2905 *params = renderbuffer->getRedSize();
2907 else return error(GL_INVALID_ENUM);
2909 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
2910 if(clientVersion >= 3)
2912 *params = renderbuffer->getGreenSize();
2914 else return error(GL_INVALID_ENUM);
2916 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
2917 if(clientVersion >= 3)
2919 *params = renderbuffer->getBlueSize();
2921 else return error(GL_INVALID_ENUM);
2923 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
2924 if(clientVersion >= 3)
2926 *params = renderbuffer->getAlphaSize();
2928 else return error(GL_INVALID_ENUM);
2930 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
2931 if(clientVersion >= 3)
2933 *params = renderbuffer->getDepthSize();
2935 else return error(GL_INVALID_ENUM);
2937 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
2938 if(clientVersion >= 3)
2940 *params = renderbuffer->getStencilSize();
2942 else return error(GL_INVALID_ENUM);
2944 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
2945 // case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: // GL_EXT_color_buffer_half_float
2946 if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
2948 return error(GL_INVALID_OPERATION);
2951 *params = GetComponentType(renderbuffer->getFormat(), attachment);
2953 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
2954 if(clientVersion >= 3)
2956 *params = GetColorEncoding(renderbuffer->getFormat());
2958 else return error(GL_INVALID_ENUM);
2961 return error(GL_INVALID_ENUM);
2966 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
2967 // is NONE, then querying any other pname will generate INVALID_ENUM.
2969 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
2970 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
2971 // INVALID_OPERATION for all other pnames
2975 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2978 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2979 if(clientVersion < 3)
2981 return error(GL_INVALID_ENUM);
2986 if(clientVersion < 3)
2988 return error(GL_INVALID_ENUM);
2992 return error(GL_INVALID_OPERATION);
2999 GLenum GetGraphicsResetStatusEXT(void)
3006 void GetIntegerv(GLenum pname, GLint* params)
3008 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
3010 es2::Context *context = es2::getContext();
3014 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
3016 ALOGI("expected_badness glGetIntegerv() called without current context.");
3018 ERR("glGetIntegerv() called without current context.");
3021 // This is not spec compliant! When there is no current GL context, functions should
3022 // have no side effects. Google Maps queries these values before creating a context,
3023 // so we need this as a bug-compatible workaround.
3026 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return;
3027 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return;
3028 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
3029 case GL_STENCIL_BITS: *params = 8; return;
3030 case GL_ALIASED_LINE_WIDTH_RANGE:
3031 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
3032 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
3039 if(!(context->getIntegerv(pname, params)))
3042 unsigned int numParams = 0;
3043 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3044 return error(GL_INVALID_ENUM);
3047 return; // it is known that pname is valid, but there are no parameters to return
3049 if(nativeType == GL_BOOL)
3051 GLboolean *boolParams = nullptr;
3052 boolParams = new GLboolean[numParams];
3054 context->getBooleanv(pname, boolParams);
3056 for(unsigned int i = 0; i < numParams; ++i)
3058 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
3061 delete [] boolParams;
3063 else if(nativeType == GL_FLOAT)
3065 GLfloat *floatParams = nullptr;
3066 floatParams = new GLfloat[numParams];
3068 context->getFloatv(pname, floatParams);
3070 for(unsigned int i = 0; i < numParams; ++i)
3072 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3074 params[i] = convert_float_fixed(floatParams[i]);
3078 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3082 delete [] floatParams;
3088 void GetProgramiv(GLuint program, GLenum pname, GLint* params)
3090 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
3092 es2::Context *context = es2::getContext();
3096 es2::Program *programObject = context->getProgram(program);
3100 if(context->getShader(program))
3102 return error(GL_INVALID_OPERATION);
3106 return error(GL_INVALID_VALUE);
3110 GLint clientVersion = egl::getClientVersion();
3114 case GL_DELETE_STATUS:
3115 *params = programObject->isFlaggedForDeletion();
3117 case GL_LINK_STATUS:
3118 *params = programObject->isLinked();
3120 case GL_VALIDATE_STATUS:
3121 *params = programObject->isValidated();
3123 case GL_INFO_LOG_LENGTH:
3124 *params = (GLint)programObject->getInfoLogLength();
3126 case GL_ATTACHED_SHADERS:
3127 *params = programObject->getAttachedShadersCount();
3129 case GL_ACTIVE_ATTRIBUTES:
3130 *params = (GLint)programObject->getActiveAttributeCount();
3132 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
3133 *params = programObject->getActiveAttributeMaxLength();
3135 case GL_ACTIVE_UNIFORMS:
3136 *params = (GLint)programObject->getActiveUniformCount();
3138 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
3139 *params = programObject->getActiveUniformMaxLength();
3141 case GL_ACTIVE_UNIFORM_BLOCKS:
3142 if(clientVersion >= 3)
3144 *params = (GLint)programObject->getActiveUniformBlockCount();
3147 else return error(GL_INVALID_ENUM);
3148 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
3149 if(clientVersion >= 3)
3151 *params = programObject->getActiveUniformBlockMaxLength();
3154 else return error(GL_INVALID_ENUM);
3155 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
3156 if(clientVersion >= 3)
3158 *params = programObject->getTransformFeedbackBufferMode();
3161 else return error(GL_INVALID_ENUM);
3162 case GL_TRANSFORM_FEEDBACK_VARYINGS:
3163 if(clientVersion >= 3)
3165 *params = programObject->getTransformFeedbackVaryingCount();
3168 else return error(GL_INVALID_ENUM);
3169 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
3170 if(clientVersion >= 3)
3172 *params = programObject->getTransformFeedbackVaryingMaxLength();
3175 else return error(GL_INVALID_ENUM);
3176 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
3177 if(clientVersion >= 3)
3179 *params = programObject->getBinaryRetrievableHint();
3182 else return error(GL_INVALID_ENUM);
3183 case GL_PROGRAM_BINARY_LENGTH:
3184 if(clientVersion >= 3)
3186 *params = programObject->getBinaryLength();
3189 else return error(GL_INVALID_ENUM);
3191 return error(GL_INVALID_ENUM);
3196 void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3198 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3199 program, bufsize, length, infolog);
3203 return error(GL_INVALID_VALUE);
3206 es2::Context *context = es2::getContext();
3210 es2::Program *programObject = context->getProgram(program);
3214 if(context->getShader(program))
3216 return error(GL_INVALID_OPERATION);
3220 return error(GL_INVALID_VALUE);
3224 programObject->getInfoLog(bufsize, length, infolog);
3228 void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3230 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
3234 case GL_CURRENT_QUERY_EXT:
3237 return error(GL_INVALID_ENUM);
3240 es2::Context *context = es2::getContext();
3244 params[0] = context->getActiveQuery(target);
3248 void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
3250 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
3254 case GL_QUERY_RESULT_EXT:
3255 case GL_QUERY_RESULT_AVAILABLE_EXT:
3258 return error(GL_INVALID_ENUM);
3261 es2::Context *context = es2::getContext();
3265 es2::Query *queryObject = context->getQuery(name);
3269 return error(GL_INVALID_OPERATION);
3272 if(context->getActiveQuery(queryObject->getType()) == name)
3274 return error(GL_INVALID_OPERATION);
3279 case GL_QUERY_RESULT_EXT:
3280 params[0] = queryObject->getResult();
3282 case GL_QUERY_RESULT_AVAILABLE_EXT:
3283 params[0] = queryObject->isResultAvailable();
3291 void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3293 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3295 es2::Context *context = es2::getContext();
3299 if(target != GL_RENDERBUFFER)
3301 return error(GL_INVALID_ENUM);
3304 if(context->getRenderbufferName() == 0)
3306 return error(GL_INVALID_OPERATION);
3309 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
3313 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3314 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3315 case GL_RENDERBUFFER_INTERNAL_FORMAT:
3317 GLint internalformat = renderbuffer->getFormat();
3318 *params = (internalformat == GL_NONE) ? GL_RGBA4 : internalformat;
3321 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3322 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3323 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3324 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3325 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3326 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
3327 case GL_RENDERBUFFER_SAMPLES: *params = renderbuffer->getSamples(); break;
3329 return error(GL_INVALID_ENUM);
3334 void GetShaderiv(GLuint shader, GLenum pname, GLint* params)
3336 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
3338 es2::Context *context = es2::getContext();
3342 es2::Shader *shaderObject = context->getShader(shader);
3346 if(context->getProgram(shader))
3348 return error(GL_INVALID_OPERATION);
3352 return error(GL_INVALID_VALUE);
3358 case GL_SHADER_TYPE:
3359 *params = shaderObject->getType();
3361 case GL_DELETE_STATUS:
3362 *params = shaderObject->isFlaggedForDeletion();
3364 case GL_COMPILE_STATUS:
3365 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3367 case GL_INFO_LOG_LENGTH:
3368 *params = (GLint)shaderObject->getInfoLogLength();
3370 case GL_SHADER_SOURCE_LENGTH:
3371 *params = (GLint)shaderObject->getSourceLength();
3374 return error(GL_INVALID_ENUM);
3379 void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3381 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3382 shader, bufsize, length, infolog);
3386 return error(GL_INVALID_VALUE);
3389 es2::Context *context = es2::getContext();
3393 es2::Shader *shaderObject = context->getShader(shader);
3397 if(context->getProgram(shader))
3399 return error(GL_INVALID_OPERATION);
3403 return error(GL_INVALID_VALUE);
3407 shaderObject->getInfoLog(bufsize, length, infolog);
3411 void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3413 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
3414 shadertype, precisiontype, range, precision);
3418 case GL_VERTEX_SHADER:
3419 case GL_FRAGMENT_SHADER:
3422 return error(GL_INVALID_ENUM);
3425 switch(precisiontype)
3428 case GL_MEDIUM_FLOAT:
3430 // IEEE 754 single-precision
3438 // Full integer precision is supported
3444 return error(GL_INVALID_ENUM);
3448 void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3450 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
3451 shader, bufsize, length, source);
3455 return error(GL_INVALID_VALUE);
3458 es2::Context *context = es2::getContext();
3462 es2::Shader *shaderObject = context->getShader(shader);
3466 if(context->getProgram(shader))
3468 return error(GL_INVALID_OPERATION);
3472 return error(GL_INVALID_VALUE);
3476 shaderObject->getSource(bufsize, length, source);
3480 const GLubyte* GetString(GLenum name)
3482 TRACE("(GLenum name = 0x%X)", name);
3487 return (GLubyte*)"Google Inc.";
3489 return (GLubyte*)"Google SwiftShader";
3492 es2::Context *context = es2::getContext();
3493 return (context && (context->getClientVersion() >= 3)) ?
3494 (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :
3495 (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3497 case GL_SHADING_LANGUAGE_VERSION:
3499 es2::Context *context = es2::getContext();
3500 return (context && (context->getClientVersion() >= 3)) ?
3501 (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :
3502 (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3506 es2::Context *context = es2::getContext();
3507 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)nullptr;
3510 return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
3514 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3516 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
3518 es2::Context *context = es2::getContext();
3522 es2::Texture *texture;
3524 GLint clientVersion = context->getClientVersion();
3529 texture = context->getTexture2D();
3531 case GL_TEXTURE_CUBE_MAP:
3532 texture = context->getTextureCubeMap();
3534 case GL_TEXTURE_EXTERNAL_OES:
3535 texture = context->getTextureExternal();
3537 case GL_TEXTURE_2D_ARRAY:
3538 if(clientVersion < 3)
3540 return error(GL_INVALID_ENUM);
3544 texture = context->getTexture2DArray();
3548 texture = context->getTexture3D();
3550 case GL_TEXTURE_RECTANGLE_ARB:
3551 texture = context->getTexture2DRect();
3554 return error(GL_INVALID_ENUM);
3559 case GL_TEXTURE_MAG_FILTER:
3560 *params = (GLfloat)texture->getMagFilter();
3562 case GL_TEXTURE_MIN_FILTER:
3563 *params = (GLfloat)texture->getMinFilter();
3565 case GL_TEXTURE_WRAP_S:
3566 *params = (GLfloat)texture->getWrapS();
3568 case GL_TEXTURE_WRAP_T:
3569 *params = (GLfloat)texture->getWrapT();
3571 case GL_TEXTURE_WRAP_R_OES:
3572 *params = (GLfloat)texture->getWrapR();
3574 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3575 *params = texture->getMaxAnisotropy();
3577 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3578 *params = (GLfloat)1;
3580 case GL_TEXTURE_BASE_LEVEL:
3581 if(clientVersion >= 3)
3583 *params = (GLfloat)texture->getBaseLevel();
3586 else return error(GL_INVALID_ENUM);
3587 case GL_TEXTURE_COMPARE_FUNC:
3588 if(clientVersion >= 3)
3590 *params = (GLfloat)texture->getCompareFunc();
3593 else return error(GL_INVALID_ENUM);
3594 case GL_TEXTURE_COMPARE_MODE:
3595 if(clientVersion >= 3)
3597 *params = (GLfloat)texture->getCompareMode();
3600 else return error(GL_INVALID_ENUM);
3601 case GL_TEXTURE_IMMUTABLE_FORMAT:
3602 if(clientVersion >= 3)
3604 *params = (GLfloat)texture->getImmutableFormat();
3607 else return error(GL_INVALID_ENUM);
3608 case GL_TEXTURE_IMMUTABLE_LEVELS:
3609 if(clientVersion >= 3)
3611 *params = (GLfloat)texture->getImmutableLevels();
3614 else return error(GL_INVALID_ENUM);
3615 case GL_TEXTURE_MAX_LEVEL:
3616 if(clientVersion >= 3)
3618 *params = (GLfloat)texture->getMaxLevel();
3621 else return error(GL_INVALID_ENUM);
3622 case GL_TEXTURE_MAX_LOD:
3623 if(clientVersion >= 3)
3625 *params = texture->getMaxLOD();
3628 else return error(GL_INVALID_ENUM);
3629 case GL_TEXTURE_MIN_LOD:
3630 if(clientVersion >= 3)
3632 *params = texture->getMinLOD();
3635 else return error(GL_INVALID_ENUM);
3636 case GL_TEXTURE_SWIZZLE_R:
3637 if(clientVersion >= 3)
3639 *params = (GLfloat)texture->getSwizzleR();
3642 else return error(GL_INVALID_ENUM);
3643 case GL_TEXTURE_SWIZZLE_G:
3644 if(clientVersion >= 3)
3646 *params = (GLfloat)texture->getSwizzleG();
3649 else return error(GL_INVALID_ENUM);
3650 case GL_TEXTURE_SWIZZLE_B:
3651 if(clientVersion >= 3)
3653 *params = (GLfloat)texture->getSwizzleB();
3656 else return error(GL_INVALID_ENUM);
3657 case GL_TEXTURE_SWIZZLE_A:
3658 if(clientVersion >= 3)
3660 *params = (GLfloat)texture->getSwizzleA();
3663 else return error(GL_INVALID_ENUM);
3665 return error(GL_INVALID_ENUM);
3670 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3672 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3674 es2::Context *context = es2::getContext();
3678 es2::Texture *texture;
3680 GLint clientVersion = context->getClientVersion();
3685 texture = context->getTexture2D();
3687 case GL_TEXTURE_CUBE_MAP:
3688 texture = context->getTextureCubeMap();
3690 case GL_TEXTURE_EXTERNAL_OES:
3691 texture = context->getTextureExternal();
3693 case GL_TEXTURE_2D_ARRAY:
3694 if(clientVersion < 3)
3696 return error(GL_INVALID_ENUM);
3700 texture = context->getTexture2DArray();
3704 texture = context->getTexture3D();
3706 case GL_TEXTURE_RECTANGLE_ARB:
3707 texture = context->getTexture2DRect();
3710 return error(GL_INVALID_ENUM);
3715 case GL_TEXTURE_MAG_FILTER:
3716 *params = texture->getMagFilter();
3718 case GL_TEXTURE_MIN_FILTER:
3719 *params = texture->getMinFilter();
3721 case GL_TEXTURE_WRAP_S:
3722 *params = texture->getWrapS();
3724 case GL_TEXTURE_WRAP_T:
3725 *params = texture->getWrapT();
3727 case GL_TEXTURE_WRAP_R_OES:
3728 *params = texture->getWrapR();
3730 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3731 *params = (GLint)texture->getMaxAnisotropy();
3733 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3736 case GL_TEXTURE_BASE_LEVEL:
3737 if(clientVersion >= 3)
3739 *params = texture->getBaseLevel();
3742 else return error(GL_INVALID_ENUM);
3743 case GL_TEXTURE_COMPARE_FUNC:
3744 if(clientVersion >= 3)
3746 *params = (GLint)texture->getCompareFunc();
3749 else return error(GL_INVALID_ENUM);
3750 case GL_TEXTURE_COMPARE_MODE:
3751 if(clientVersion >= 3)
3753 *params = (GLint)texture->getCompareMode();
3756 else return error(GL_INVALID_ENUM);
3757 case GL_TEXTURE_IMMUTABLE_FORMAT:
3758 if(clientVersion >= 3)
3760 *params = (GLint)texture->getImmutableFormat();
3763 else return error(GL_INVALID_ENUM);
3764 case GL_TEXTURE_IMMUTABLE_LEVELS:
3765 if(clientVersion >= 3)
3767 *params = (GLint)texture->getImmutableLevels();
3770 else return error(GL_INVALID_ENUM);
3771 case GL_TEXTURE_MAX_LEVEL:
3772 if(clientVersion >= 3)
3774 *params = texture->getMaxLevel();
3777 else return error(GL_INVALID_ENUM);
3778 case GL_TEXTURE_MAX_LOD:
3779 if(clientVersion >= 3)
3781 *params = (GLint)roundf(texture->getMaxLOD());
3784 else return error(GL_INVALID_ENUM);
3785 case GL_TEXTURE_MIN_LOD:
3786 if(clientVersion >= 3)
3788 *params = (GLint)roundf(texture->getMinLOD());
3791 else return error(GL_INVALID_ENUM);
3792 case GL_TEXTURE_SWIZZLE_R:
3793 if(clientVersion >= 3)
3795 *params = (GLint)texture->getSwizzleR();
3798 else return error(GL_INVALID_ENUM);
3799 case GL_TEXTURE_SWIZZLE_G:
3800 if(clientVersion >= 3)
3802 *params = (GLint)texture->getSwizzleG();
3805 else return error(GL_INVALID_ENUM);
3806 case GL_TEXTURE_SWIZZLE_B:
3807 if(clientVersion >= 3)
3809 *params = (GLint)texture->getSwizzleB();
3812 else return error(GL_INVALID_ENUM);
3813 case GL_TEXTURE_SWIZZLE_A:
3814 if(clientVersion >= 3)
3816 *params = (GLint)texture->getSwizzleA();
3819 else return error(GL_INVALID_ENUM);
3821 return error(GL_INVALID_ENUM);
3826 void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3828 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
3829 program, location, bufSize, params);
3833 return error(GL_INVALID_VALUE);
3836 es2::Context *context = es2::getContext();
3840 es2::Program *programObject = context->getProgram(program);
3844 if(context->getShader(program))
3846 return error(GL_INVALID_OPERATION);
3850 return error(GL_INVALID_VALUE);
3854 if(!programObject->isLinked())
3856 return error(GL_INVALID_OPERATION);
3859 if(!programObject->getUniformfv(location, &bufSize, params))
3861 return error(GL_INVALID_OPERATION);
3866 void GetUniformfv(GLuint program, GLint location, GLfloat* params)
3868 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
3870 es2::Context *context = es2::getContext();
3874 es2::Program *programObject = context->getProgram(program);
3878 if(context->getShader(program))
3880 return error(GL_INVALID_OPERATION);
3884 return error(GL_INVALID_VALUE);
3888 if(!programObject->isLinked())
3890 return error(GL_INVALID_OPERATION);
3893 if(!programObject->getUniformfv(location, nullptr, params))
3895 return error(GL_INVALID_OPERATION);
3900 void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3902 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
3903 program, location, bufSize, params);
3907 return error(GL_INVALID_VALUE);
3910 es2::Context *context = es2::getContext();
3914 es2::Program *programObject = context->getProgram(program);
3918 if(context->getShader(program))
3920 return error(GL_INVALID_OPERATION);
3924 return error(GL_INVALID_VALUE);
3928 if(!programObject->isLinked())
3930 return error(GL_INVALID_OPERATION);
3933 if(!programObject->getUniformiv(location, &bufSize, params))
3935 return error(GL_INVALID_OPERATION);
3940 void GetUniformiv(GLuint program, GLint location, GLint* params)
3942 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
3944 es2::Context *context = es2::getContext();
3948 es2::Program *programObject = context->getProgram(program);
3952 if(context->getShader(program))
3954 return error(GL_INVALID_OPERATION);
3958 return error(GL_INVALID_VALUE);
3962 if(!programObject->isLinked())
3964 return error(GL_INVALID_OPERATION);
3967 if(!programObject->getUniformiv(location, nullptr, params))
3969 return error(GL_INVALID_OPERATION);
3974 int GetUniformLocation(GLuint program, const GLchar* name)
3976 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
3978 es2::Context *context = es2::getContext();
3980 if(strstr(name, "gl_") == name)
3987 es2::Program *programObject = context->getProgram(program);
3991 if(context->getShader(program))
3993 return error(GL_INVALID_OPERATION, -1);
3997 return error(GL_INVALID_VALUE, -1);
4001 if(!programObject->isLinked())
4003 return error(GL_INVALID_OPERATION, -1);
4006 return programObject->getUniformLocation(name);
4012 void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4014 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
4016 es2::Context *context = es2::getContext();
4020 if(index >= es2::MAX_VERTEX_ATTRIBS)
4022 return error(GL_INVALID_VALUE);
4025 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4027 GLint clientVersion = context->getClientVersion();
4031 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4032 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4034 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4035 *params = (GLfloat)attribState.mSize;
4037 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4038 *params = (GLfloat)attribState.mStride;
4040 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4041 *params = (GLfloat)attribState.mType;
4043 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4044 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
4046 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4047 *params = (GLfloat)attribState.mBoundBuffer.name();
4049 case GL_CURRENT_VERTEX_ATTRIB:
4051 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4052 for(int i = 0; i < 4; ++i)
4054 params[i] = attrib.getCurrentValueF(i);
4058 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4059 if(clientVersion >= 3)
4061 *params = (GLfloat)(attribState.mPureInteger ? GL_TRUE : GL_FALSE);
4064 else return error(GL_INVALID_ENUM);
4065 default: return error(GL_INVALID_ENUM);
4070 void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4072 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
4074 es2::Context *context = es2::getContext();
4078 if(index >= es2::MAX_VERTEX_ATTRIBS)
4080 return error(GL_INVALID_VALUE);
4083 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4085 GLint clientVersion = context->getClientVersion();
4089 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4090 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4092 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4093 *params = attribState.mSize;
4095 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4096 *params = attribState.mStride;
4098 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4099 *params = attribState.mType;
4101 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4102 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
4104 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4105 *params = attribState.mBoundBuffer.name();
4107 case GL_CURRENT_VERTEX_ATTRIB:
4109 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4110 for(int i = 0; i < 4; ++i)
4112 float currentValue = attrib.getCurrentValueF(i);
4113 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4117 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4118 if(clientVersion >= 3)
4120 *params = (attribState.mPureInteger ? GL_TRUE : GL_FALSE);
4123 else return error(GL_INVALID_ENUM);
4124 default: return error(GL_INVALID_ENUM);
4129 void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
4131 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
4133 es2::Context *context = es2::getContext();
4137 if(index >= es2::MAX_VERTEX_ATTRIBS)
4139 return error(GL_INVALID_VALUE);
4142 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4144 return error(GL_INVALID_ENUM);
4147 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
4151 void Hint(GLenum target, GLenum mode)
4153 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
4162 return error(GL_INVALID_ENUM);
4165 es2::Context *context = es2::getContext();
4171 case GL_GENERATE_MIPMAP_HINT:
4172 context->setGenerateMipmapHint(mode);
4174 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4175 context->setFragmentShaderDerivativeHint(mode);
4177 case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
4178 context->setTextureFilteringHint(mode);
4181 return error(GL_INVALID_ENUM);
4186 GLboolean IsBuffer(GLuint buffer)
4188 TRACE("(GLuint buffer = %d)", buffer);
4190 es2::Context *context = es2::getContext();
4192 if(context && buffer)
4194 es2::Buffer *bufferObject = context->getBuffer(buffer);
4205 GLboolean IsEnabled(GLenum cap)
4207 TRACE("(GLenum cap = 0x%X)", cap);
4209 es2::Context *context = es2::getContext();
4213 GLint clientVersion = context->getClientVersion();
4217 case GL_CULL_FACE: return context->isCullFaceEnabled();
4218 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4219 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4220 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4221 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4222 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4223 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4224 case GL_BLEND: return context->isBlendEnabled();
4225 case GL_DITHER: return context->isDitherEnabled();
4226 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4227 if(clientVersion >= 3)
4229 return context->isPrimitiveRestartFixedIndexEnabled();
4231 else return error(GL_INVALID_ENUM, false);
4232 case GL_RASTERIZER_DISCARD:
4233 if(clientVersion >= 3)
4235 return context->isRasterizerDiscardEnabled();
4237 else return error(GL_INVALID_ENUM, false);
4239 return error(GL_INVALID_ENUM, false);
4246 GLboolean IsFenceNV(GLuint fence)
4248 TRACE("(GLuint fence = %d)", fence);
4250 es2::Context *context = es2::getContext();
4254 es2::Fence *fenceObject = context->getFence(fence);
4261 return fenceObject->isFence();
4267 GLboolean IsFramebuffer(GLuint framebuffer)
4269 TRACE("(GLuint framebuffer = %d)", framebuffer);
4271 es2::Context *context = es2::getContext();
4273 if(context && framebuffer)
4275 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4277 if(framebufferObject)
4286 GLboolean IsProgram(GLuint program)
4288 TRACE("(GLuint program = %d)", program);
4290 es2::Context *context = es2::getContext();
4292 if(context && program)
4294 es2::Program *programObject = context->getProgram(program);
4305 GLboolean IsQueryEXT(GLuint name)
4307 TRACE("(GLuint name = %d)", name);
4314 es2::Context *context = es2::getContext();
4318 es2::Query *queryObject = context->getQuery(name);
4329 GLboolean IsRenderbuffer(GLuint renderbuffer)
4331 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
4333 es2::Context *context = es2::getContext();
4335 if(context && renderbuffer)
4337 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4339 if(renderbufferObject)
4348 GLboolean IsShader(GLuint shader)
4350 TRACE("(GLuint shader = %d)", shader);
4352 es2::Context *context = es2::getContext();
4354 if(context && shader)
4356 es2::Shader *shaderObject = context->getShader(shader);
4367 GLboolean IsTexture(GLuint texture)
4369 TRACE("(GLuint texture = %d)", texture);
4371 es2::Context *context = es2::getContext();
4373 if(context && texture)
4375 es2::Texture *textureObject = context->getTexture(texture);
4386 void LineWidth(GLfloat width)
4388 TRACE("(GLfloat width = %f)", width);
4392 return error(GL_INVALID_VALUE);
4395 es2::Context *context = es2::getContext();
4399 context->setLineWidth(width);
4403 void LinkProgram(GLuint program)
4405 TRACE("(GLuint program = %d)", program);
4407 es2::Context *context = es2::getContext();
4411 es2::Program *programObject = context->getProgram(program);
4415 if(context->getShader(program))
4417 return error(GL_INVALID_OPERATION);
4421 return error(GL_INVALID_VALUE);
4425 if(programObject == context->getCurrentProgram())
4427 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
4428 if(transformFeedback && transformFeedback->isActive())
4430 return error(GL_INVALID_OPERATION);
4434 programObject->link();
4438 void PixelStorei(GLenum pname, GLint param)
4440 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
4442 es2::Context *context = es2::getContext();
4446 GLint clientVersion = context->getClientVersion();
4450 case GL_UNPACK_ALIGNMENT:
4451 if(param != 1 && param != 2 && param != 4 && param != 8)
4453 return error(GL_INVALID_VALUE);
4455 context->setUnpackAlignment(param);
4457 case GL_PACK_ALIGNMENT:
4458 if(param != 1 && param != 2 && param != 4 && param != 8)
4460 return error(GL_INVALID_VALUE);
4462 context->setPackAlignment(param);
4464 case GL_PACK_ROW_LENGTH:
4465 if(clientVersion >= 3)
4469 return error(GL_INVALID_VALUE);
4471 context->setPackRowLength(param);
4474 else return error(GL_INVALID_ENUM);
4475 case GL_PACK_SKIP_PIXELS:
4476 if(clientVersion >= 3)
4480 return error(GL_INVALID_VALUE);
4482 context->setPackSkipPixels(param);
4485 else return error(GL_INVALID_ENUM);
4486 case GL_PACK_SKIP_ROWS:
4487 if(clientVersion >= 3)
4491 return error(GL_INVALID_VALUE);
4493 context->setPackSkipRows(param);
4496 else return error(GL_INVALID_ENUM);
4497 case GL_UNPACK_ROW_LENGTH:
4498 if(clientVersion >= 3)
4502 return error(GL_INVALID_VALUE);
4504 context->setUnpackRowLength(param);
4507 else return error(GL_INVALID_ENUM);
4508 case GL_UNPACK_IMAGE_HEIGHT:
4509 if(clientVersion >= 3)
4513 return error(GL_INVALID_VALUE);
4515 context->setUnpackImageHeight(param);
4518 else return error(GL_INVALID_ENUM);
4519 case GL_UNPACK_SKIP_PIXELS:
4520 if(clientVersion >= 3)
4524 return error(GL_INVALID_VALUE);
4526 context->setUnpackSkipPixels(param);
4529 else return error(GL_INVALID_ENUM);
4530 case GL_UNPACK_SKIP_ROWS:
4531 if(clientVersion >= 3)
4535 return error(GL_INVALID_VALUE);
4537 context->setUnpackSkipRows(param);
4540 else return error(GL_INVALID_ENUM);
4541 case GL_UNPACK_SKIP_IMAGES:
4542 if(clientVersion >= 3) {
4545 return error(GL_INVALID_VALUE);
4547 context->setUnpackSkipImages(param);
4550 else return error(GL_INVALID_ENUM);
4552 return error(GL_INVALID_ENUM);
4557 void PolygonOffset(GLfloat factor, GLfloat units)
4559 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
4561 es2::Context *context = es2::getContext();
4565 context->setPolygonOffsetParams(factor, units);
4569 void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4570 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
4572 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4573 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
4574 x, y, width, height, format, type, bufSize, data);
4576 if(width < 0 || height < 0 || bufSize < 0)
4578 return error(GL_INVALID_VALUE);
4581 es2::Context *context = es2::getContext();
4585 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4589 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
4591 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4592 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
4593 x, y, width, height, format, type, pixels);
4595 if(width < 0 || height < 0)
4597 return error(GL_INVALID_VALUE);
4600 es2::Context *context = es2::getContext();
4604 context->readPixels(x, y, width, height, format, type, nullptr, pixels);
4608 void ReleaseShaderCompiler(void)
4612 es2::Shader::releaseCompiler();
4615 void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4617 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4618 target, samples, internalformat, width, height);
4622 case GL_RENDERBUFFER:
4625 return error(GL_INVALID_ENUM);
4628 if(width < 0 || height < 0 || samples < 0 ||
4629 width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4630 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
4632 return error(GL_INVALID_VALUE);
4635 if(samples > es2::IMPLEMENTATION_MAX_SAMPLES ||
4636 (IsNonNormalizedInteger(internalformat) && samples > 0))
4638 return error(GL_INVALID_OPERATION);
4641 es2::Context *context = es2::getContext();
4645 GLuint handle = context->getRenderbufferName();
4648 return error(GL_INVALID_OPERATION);
4651 GLint clientVersion = context->getClientVersion();
4653 if(IsColorRenderable(internalformat, clientVersion))
4655 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4657 else if(IsDepthRenderable(internalformat, clientVersion) && IsStencilRenderable(internalformat, clientVersion))
4659 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));
4661 else if(IsDepthRenderable(internalformat, clientVersion))
4663 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));
4665 else if(IsStencilRenderable(internalformat, clientVersion))
4667 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4669 else error(GL_INVALID_ENUM);
4673 void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4675 RenderbufferStorageMultisample(target, samples, internalformat, width, height);
4678 void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4680 RenderbufferStorageMultisample(target, 0, internalformat, width, height);
4683 void SampleCoverage(GLclampf value, GLboolean invert)
4685 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
4687 es2::Context* context = es2::getContext();
4691 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4695 void SetFenceNV(GLuint fence, GLenum condition)
4697 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4699 if(condition != GL_ALL_COMPLETED_NV)
4701 return error(GL_INVALID_ENUM);
4704 es2::Context *context = es2::getContext();
4708 es2::Fence *fenceObject = context->getFence(fence);
4712 return error(GL_INVALID_OPERATION);
4715 fenceObject->setFence(condition);
4719 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
4721 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4723 if(width < 0 || height < 0)
4725 return error(GL_INVALID_VALUE);
4728 es2::Context* context = es2::getContext();
4732 context->setScissorParams(x, y, width, height);
4736 void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4738 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4739 "const GLvoid* binary = %p, GLsizei length = %d)",
4740 n, shaders, binaryformat, binary, length);
4742 // No binary shader formats are supported.
4743 return error(GL_INVALID_ENUM);
4746 void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
4748 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
4749 shader, count, string, length);
4753 return error(GL_INVALID_VALUE);
4756 es2::Context *context = es2::getContext();
4760 es2::Shader *shaderObject = context->getShader(shader);
4764 if(context->getProgram(shader))
4766 return error(GL_INVALID_OPERATION);
4770 return error(GL_INVALID_VALUE);
4774 shaderObject->setSource(count, string, length);
4778 void StencilFunc(GLenum func, GLint ref, GLuint mask)
4780 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4783 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4785 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4791 case GL_FRONT_AND_BACK:
4794 return error(GL_INVALID_ENUM);
4809 return error(GL_INVALID_ENUM);
4812 es2::Context *context = es2::getContext();
4816 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4818 context->setStencilParams(func, ref, mask);
4821 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4823 context->setStencilBackParams(func, ref, mask);
4828 void StencilMask(GLuint mask)
4830 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4833 void StencilMaskSeparate(GLenum face, GLuint mask)
4835 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4841 case GL_FRONT_AND_BACK:
4844 return error(GL_INVALID_ENUM);
4847 es2::Context *context = es2::getContext();
4851 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4853 context->setStencilWritemask(mask);
4856 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4858 context->setStencilBackWritemask(mask);
4863 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4865 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4868 void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4870 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4871 face, fail, zfail, zpass);
4877 case GL_FRONT_AND_BACK:
4880 return error(GL_INVALID_ENUM);
4895 return error(GL_INVALID_ENUM);
4910 return error(GL_INVALID_ENUM);
4925 return error(GL_INVALID_ENUM);
4928 es2::Context *context = es2::getContext();
4932 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4934 context->setStencilOperations(fail, zfail, zpass);
4937 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4939 context->setStencilBackOperations(fail, zfail, zpass);
4944 GLboolean TestFenceNV(GLuint fence)
4946 TRACE("(GLuint fence = %d)", fence);
4948 es2::Context *context = es2::getContext();
4952 es2::Fence *fenceObject = context->getFence(fence);
4956 return error(GL_INVALID_OPERATION, GL_TRUE);
4959 return fenceObject->testFence();
4965 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4966 GLint border, GLenum format, GLenum type, const GLvoid* data)
4968 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4969 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* data = %p)",
4970 target, level, internalformat, width, height, border, format, type, data);
4972 if(!validImageSize(level, width, height))
4974 return error(GL_INVALID_VALUE);
4977 es2::Context *context = es2::getContext();
4981 // Core OpenGL ES 2.0 requires format and internalformat to be equal (checked below),
4982 // but GL_APPLE_texture_format_BGRA8888 allows (only) GL_BGRA_EXT / GL_RGBA, while
4983 // GL_EXT_texture_format_BGRA8888 also allows GL_BGRA_EXT / GL_BGRA_EXT.
4984 if(format == GL_BGRA_EXT && internalformat == GL_RGBA)
4986 internalformat = GL_BGRA_EXT;
4989 GLint clientVersion = context->getClientVersion();
4990 if(clientVersion < 3)
4992 if((internalformat != (GLint)format) &&
4993 !((type == GL_FLOAT) && (format == GL_RGBA) && (internalformat == GL_RGBA32F))) // CHROMIUM_color_buffer_float_rgba
4995 return error(GL_INVALID_OPERATION);
4999 GLenum validationError = ValidateTextureFormatType(format, type, internalformat, target, clientVersion);
5000 if(validationError != GL_NO_ERROR)
5002 return error(validationError);
5007 return error(GL_INVALID_VALUE);
5012 case GL_TEXTURE_RECTANGLE_ARB:
5015 return error(GL_INVALID_VALUE); // Defining level other than 0 is not allowed
5017 // Fall through to GL_TEXTURE_2D case.
5019 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5020 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
5022 return error(GL_INVALID_VALUE);
5025 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5026 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5027 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5028 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5029 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5030 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5033 return error(GL_INVALID_VALUE);
5036 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5037 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5039 return error(GL_INVALID_VALUE);
5043 return error(GL_INVALID_ENUM);
5046 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
5047 if(validationError != GL_NO_ERROR)
5049 return error(validationError);
5052 GLint sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);
5054 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
5056 es2::Texture2D *texture = context->getTexture2D(target);
5060 return error(GL_INVALID_OPERATION);
5063 texture->setImage(level, width, height, sizedInternalFormat, format, type, context->getUnpackParameters(), data);
5067 es2::TextureCubeMap *texture = context->getTextureCubeMap();
5071 return error(GL_INVALID_OPERATION);
5074 texture->setImage(target, level, width, height, sizedInternalFormat, format, type, context->getUnpackParameters(), data);
5079 void TexParameterf(GLenum target, GLenum pname, GLfloat param)
5081 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
5083 es2::Context *context = es2::getContext();
5087 es2::Texture *texture;
5089 GLint clientVersion = context->getClientVersion();
5094 texture = context->getTexture2D();
5096 case GL_TEXTURE_2D_ARRAY:
5097 if(clientVersion < 3)
5099 return error(GL_INVALID_ENUM);
5103 texture = context->getTexture2DArray();
5107 texture = context->getTexture3D();
5109 case GL_TEXTURE_CUBE_MAP:
5110 texture = context->getTextureCubeMap();
5112 case GL_TEXTURE_EXTERNAL_OES:
5113 texture = context->getTextureExternal();
5115 case GL_TEXTURE_RECTANGLE_ARB:
5116 texture = context->getTexture2DRect();
5119 return error(GL_INVALID_ENUM);
5124 case GL_TEXTURE_WRAP_S:
5125 if(!texture->setWrapS((GLenum)param))
5127 return error(GL_INVALID_ENUM);
5130 case GL_TEXTURE_WRAP_T:
5131 if(!texture->setWrapT((GLenum)param))
5133 return error(GL_INVALID_ENUM);
5136 case GL_TEXTURE_WRAP_R_OES:
5137 if(!texture->setWrapR((GLenum)param))
5139 return error(GL_INVALID_ENUM);
5142 case GL_TEXTURE_MIN_FILTER:
5143 if(!texture->setMinFilter((GLenum)param))
5145 return error(GL_INVALID_ENUM);
5148 case GL_TEXTURE_MAG_FILTER:
5149 if(!texture->setMagFilter((GLenum)param))
5151 return error(GL_INVALID_ENUM);
5154 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5155 if(!texture->setMaxAnisotropy(param))
5157 return error(GL_INVALID_VALUE);
5160 case GL_TEXTURE_BASE_LEVEL:
5161 if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))
5163 return error(GL_INVALID_VALUE);
5166 case GL_TEXTURE_COMPARE_FUNC:
5167 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5169 return error(GL_INVALID_VALUE);
5172 case GL_TEXTURE_COMPARE_MODE:
5173 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5175 return error(GL_INVALID_VALUE);
5178 case GL_TEXTURE_MAX_LEVEL:
5179 if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))
5181 return error(GL_INVALID_VALUE);
5184 case GL_TEXTURE_MAX_LOD:
5185 if(clientVersion < 3 || !texture->setMaxLOD(param))
5187 return error(GL_INVALID_VALUE);
5190 case GL_TEXTURE_MIN_LOD:
5191 if(clientVersion < 3 || !texture->setMinLOD(param))
5193 return error(GL_INVALID_VALUE);
5196 case GL_TEXTURE_SWIZZLE_R:
5197 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5199 return error(GL_INVALID_VALUE);
5202 case GL_TEXTURE_SWIZZLE_G:
5203 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5205 return error(GL_INVALID_VALUE);
5208 case GL_TEXTURE_SWIZZLE_B:
5209 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5211 return error(GL_INVALID_VALUE);
5214 case GL_TEXTURE_SWIZZLE_A:
5215 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5217 return error(GL_INVALID_VALUE);
5221 return error(GL_INVALID_ENUM);
5226 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5228 glTexParameterf(target, pname, *params);
5231 void TexParameteri(GLenum target, GLenum pname, GLint param)
5233 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
5235 es2::Context *context = es2::getContext();
5239 es2::Texture *texture;
5241 GLint clientVersion = context->getClientVersion();
5246 texture = context->getTexture2D();
5248 case GL_TEXTURE_2D_ARRAY:
5249 if(clientVersion < 3)
5251 return error(GL_INVALID_ENUM);
5255 texture = context->getTexture2DArray();
5259 texture = context->getTexture3D();
5261 case GL_TEXTURE_CUBE_MAP:
5262 texture = context->getTextureCubeMap();
5264 case GL_TEXTURE_EXTERNAL_OES:
5265 texture = context->getTextureExternal();
5267 case GL_TEXTURE_RECTANGLE_ARB:
5268 texture = context->getTexture2DRect();
5271 return error(GL_INVALID_ENUM);
5276 case GL_TEXTURE_WRAP_S:
5277 if(!texture->setWrapS((GLenum)param))
5279 return error(GL_INVALID_ENUM);
5282 case GL_TEXTURE_WRAP_T:
5283 if(!texture->setWrapT((GLenum)param))
5285 return error(GL_INVALID_ENUM);
5288 case GL_TEXTURE_WRAP_R_OES:
5289 if(!texture->setWrapR((GLenum)param))
5291 return error(GL_INVALID_ENUM);
5294 case GL_TEXTURE_MIN_FILTER:
5295 if(!texture->setMinFilter((GLenum)param))
5297 return error(GL_INVALID_ENUM);
5300 case GL_TEXTURE_MAG_FILTER:
5301 if(!texture->setMagFilter((GLenum)param))
5303 return error(GL_INVALID_ENUM);
5306 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5307 if(!texture->setMaxAnisotropy((GLfloat)param))
5309 return error(GL_INVALID_VALUE);
5312 case GL_TEXTURE_BASE_LEVEL:
5313 if((texture->getTarget() == GL_TEXTURE_RECTANGLE_ARB) && (param != 0))
5315 return error(GL_INVALID_OPERATION); // Base level has to be 0
5317 if(clientVersion < 3 || !texture->setBaseLevel(param))
5319 return error(GL_INVALID_VALUE);
5322 case GL_TEXTURE_COMPARE_FUNC:
5323 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5325 return error(GL_INVALID_VALUE);
5328 case GL_TEXTURE_COMPARE_MODE:
5329 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5331 return error(GL_INVALID_VALUE);
5334 case GL_TEXTURE_MAX_LEVEL:
5335 if(clientVersion < 3 || !texture->setMaxLevel(param))
5337 return error(GL_INVALID_VALUE);
5340 case GL_TEXTURE_MAX_LOD:
5341 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5343 return error(GL_INVALID_VALUE);
5346 case GL_TEXTURE_MIN_LOD:
5347 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5349 return error(GL_INVALID_VALUE);
5352 case GL_TEXTURE_SWIZZLE_R:
5353 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5355 return error(GL_INVALID_VALUE);
5358 case GL_TEXTURE_SWIZZLE_G:
5359 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5361 return error(GL_INVALID_VALUE);
5364 case GL_TEXTURE_SWIZZLE_B:
5365 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5367 return error(GL_INVALID_VALUE);
5370 case GL_TEXTURE_SWIZZLE_A:
5371 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5373 return error(GL_INVALID_VALUE);
5377 return error(GL_INVALID_ENUM);
5382 void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
5384 glTexParameteri(target, pname, *params);
5387 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5388 GLenum format, GLenum type, const GLvoid* data)
5390 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5391 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
5392 "const GLvoid* data = %p)",
5393 target, level, xoffset, yoffset, width, height, format, type, data);
5395 if(!es2::IsTextureTarget(target))
5397 return error(GL_INVALID_ENUM);
5400 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5402 return error(GL_INVALID_VALUE);
5405 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5407 return error(GL_INVALID_VALUE);
5410 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5412 return error(GL_INVALID_VALUE);
5415 es2::Context *context = es2::getContext();
5419 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
5421 es2::Texture2D *texture = context->getTexture2D(target);
5423 GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
5424 if(validationError != GL_NO_ERROR)
5426 return error(validationError);
5429 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
5430 if(validationError != GL_NO_ERROR)
5432 return error(validationError);
5435 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackParameters(), data);
5437 else if(es2::IsCubemapTextureTarget(target))
5439 es2::TextureCubeMap *texture = context->getTextureCubeMap();
5441 GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
5442 if(validationError != GL_NO_ERROR)
5444 return error(validationError);
5447 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
5448 if(validationError != GL_NO_ERROR)
5450 return error(validationError);
5453 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackParameters(), data);
5455 else UNREACHABLE(target);
5459 void Uniform1f(GLint location, GLfloat x)
5461 glUniform1fv(location, 1, &x);
5464 void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
5466 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5470 return error(GL_INVALID_VALUE);
5473 es2::Context *context = es2::getContext();
5477 es2::Program *program = context->getCurrentProgram();
5481 return error(GL_INVALID_OPERATION);
5489 if(!program->setUniform1fv(location, count, v))
5491 return error(GL_INVALID_OPERATION);
5496 void Uniform1i(GLint location, GLint x)
5498 glUniform1iv(location, 1, &x);
5501 void Uniform1iv(GLint location, GLsizei count, const GLint* v)
5503 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5507 return error(GL_INVALID_VALUE);
5510 es2::Context *context = es2::getContext();
5514 es2::Program *program = context->getCurrentProgram();
5518 return error(GL_INVALID_OPERATION);
5526 if(!program->setUniform1iv(location, count, v))
5528 return error(GL_INVALID_OPERATION);
5533 void Uniform2f(GLint location, GLfloat x, GLfloat y)
5535 GLfloat xy[2] = {x, y};
5537 glUniform2fv(location, 1, (GLfloat*)&xy);
5540 void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
5542 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5546 return error(GL_INVALID_VALUE);
5549 es2::Context *context = es2::getContext();
5553 es2::Program *program = context->getCurrentProgram();
5557 return error(GL_INVALID_OPERATION);
5565 if(!program->setUniform2fv(location, count, v))
5567 return error(GL_INVALID_OPERATION);
5572 void Uniform2i(GLint location, GLint x, GLint y)
5574 GLint xy[4] = {x, y};
5576 glUniform2iv(location, 1, (GLint*)&xy);
5579 void Uniform2iv(GLint location, GLsizei count, const GLint* v)
5581 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5585 return error(GL_INVALID_VALUE);
5588 es2::Context *context = es2::getContext();
5592 es2::Program *program = context->getCurrentProgram();
5596 return error(GL_INVALID_OPERATION);
5604 if(!program->setUniform2iv(location, count, v))
5606 return error(GL_INVALID_OPERATION);
5611 void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5613 GLfloat xyz[3] = {x, y, z};
5615 glUniform3fv(location, 1, (GLfloat*)&xyz);
5618 void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
5620 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5624 return error(GL_INVALID_VALUE);
5627 es2::Context *context = es2::getContext();
5631 es2::Program *program = context->getCurrentProgram();
5635 return error(GL_INVALID_OPERATION);
5643 if(!program->setUniform3fv(location, count, v))
5645 return error(GL_INVALID_OPERATION);
5650 void Uniform3i(GLint location, GLint x, GLint y, GLint z)
5652 GLint xyz[3] = {x, y, z};
5654 glUniform3iv(location, 1, (GLint*)&xyz);
5657 void Uniform3iv(GLint location, GLsizei count, const GLint* v)
5659 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5663 return error(GL_INVALID_VALUE);
5666 es2::Context *context = es2::getContext();
5670 es2::Program *program = context->getCurrentProgram();
5674 return error(GL_INVALID_OPERATION);
5682 if(!program->setUniform3iv(location, count, v))
5684 return error(GL_INVALID_OPERATION);
5689 void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5691 GLfloat xyzw[4] = {x, y, z, w};
5693 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5696 void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
5698 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5702 return error(GL_INVALID_VALUE);
5705 es2::Context *context = es2::getContext();
5709 es2::Program *program = context->getCurrentProgram();
5713 return error(GL_INVALID_OPERATION);
5721 if(!program->setUniform4fv(location, count, v))
5723 return error(GL_INVALID_OPERATION);
5728 void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5730 GLint xyzw[4] = {x, y, z, w};
5732 glUniform4iv(location, 1, (GLint*)&xyzw);
5735 void Uniform4iv(GLint location, GLsizei count, const GLint* v)
5737 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5741 return error(GL_INVALID_VALUE);
5744 es2::Context *context = es2::getContext();
5748 es2::Program *program = context->getCurrentProgram();
5752 return error(GL_INVALID_OPERATION);
5760 if(!program->setUniform4iv(location, count, v))
5762 return error(GL_INVALID_OPERATION);
5767 void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5769 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5770 location, count, transpose, value);
5774 return error(GL_INVALID_VALUE);
5777 es2::Context *context = es2::getContext();
5781 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5783 return error(GL_INVALID_VALUE);
5786 es2::Program *program = context->getCurrentProgram();
5790 return error(GL_INVALID_OPERATION);
5798 if(!program->setUniformMatrix2fv(location, count, transpose, value))
5800 return error(GL_INVALID_OPERATION);
5805 void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5807 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5808 location, count, transpose, value);
5812 return error(GL_INVALID_VALUE);
5815 es2::Context *context = es2::getContext();
5819 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5821 return error(GL_INVALID_VALUE);
5824 es2::Program *program = context->getCurrentProgram();
5828 return error(GL_INVALID_OPERATION);
5836 if(!program->setUniformMatrix3fv(location, count, transpose, value))
5838 return error(GL_INVALID_OPERATION);
5843 void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5845 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5846 location, count, transpose, value);
5850 return error(GL_INVALID_VALUE);
5853 es2::Context *context = es2::getContext();
5857 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5859 return error(GL_INVALID_VALUE);
5862 es2::Program *program = context->getCurrentProgram();
5866 return error(GL_INVALID_OPERATION);
5874 if(!program->setUniformMatrix4fv(location, count, transpose, value))
5876 return error(GL_INVALID_OPERATION);
5881 void UseProgram(GLuint program)
5883 TRACE("(GLuint program = %d)", program);
5885 es2::Context *context = es2::getContext();
5889 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
5890 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
5892 return error(GL_INVALID_OPERATION);
5895 es2::Program *programObject = context->getProgram(program);
5897 if(!programObject && program != 0)
5899 if(context->getShader(program))
5901 return error(GL_INVALID_OPERATION);
5905 return error(GL_INVALID_VALUE);
5909 if(program != 0 && !programObject->isLinked())
5911 return error(GL_INVALID_OPERATION);
5914 context->useProgram(program);
5918 void ValidateProgram(GLuint program)
5920 TRACE("(GLuint program = %d)", program);
5922 es2::Context *context = es2::getContext();
5926 es2::Program *programObject = context->getProgram(program);
5930 if(context->getShader(program))
5932 return error(GL_INVALID_OPERATION);
5936 return error(GL_INVALID_VALUE);
5940 programObject->validate(context->getDevice());
5944 void VertexAttrib1f(GLuint index, GLfloat x)
5946 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
5948 if(index >= es2::MAX_VERTEX_ATTRIBS)
5950 return error(GL_INVALID_VALUE);
5953 es2::Context *context = es2::getContext();
5957 GLfloat vals[4] = { x, 0, 0, 1 };
5958 context->setVertexAttrib(index, vals);
5962 void VertexAttrib1fv(GLuint index, const GLfloat* values)
5964 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
5966 if(index >= es2::MAX_VERTEX_ATTRIBS)
5968 return error(GL_INVALID_VALUE);
5971 es2::Context *context = es2::getContext();
5975 GLfloat vals[4] = { values[0], 0, 0, 1 };
5976 context->setVertexAttrib(index, vals);
5980 void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5982 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
5984 if(index >= es2::MAX_VERTEX_ATTRIBS)
5986 return error(GL_INVALID_VALUE);
5989 es2::Context *context = es2::getContext();
5993 GLfloat vals[4] = { x, y, 0, 1 };
5994 context->setVertexAttrib(index, vals);
5998 void VertexAttrib2fv(GLuint index, const GLfloat* values)
6000 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6002 if(index >= es2::MAX_VERTEX_ATTRIBS)
6004 return error(GL_INVALID_VALUE);
6007 es2::Context *context = es2::getContext();
6011 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6012 context->setVertexAttrib(index, vals);
6016 void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6018 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
6020 if(index >= es2::MAX_VERTEX_ATTRIBS)
6022 return error(GL_INVALID_VALUE);
6025 es2::Context *context = es2::getContext();
6029 GLfloat vals[4] = { x, y, z, 1 };
6030 context->setVertexAttrib(index, vals);
6034 void VertexAttrib3fv(GLuint index, const GLfloat* values)
6036 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6038 if(index >= es2::MAX_VERTEX_ATTRIBS)
6040 return error(GL_INVALID_VALUE);
6043 es2::Context *context = es2::getContext();
6047 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6048 context->setVertexAttrib(index, vals);
6052 void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6054 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
6056 if(index >= es2::MAX_VERTEX_ATTRIBS)
6058 return error(GL_INVALID_VALUE);
6061 es2::Context *context = es2::getContext();
6065 GLfloat vals[4] = { x, y, z, w };
6066 context->setVertexAttrib(index, vals);
6070 void VertexAttrib4fv(GLuint index, const GLfloat* values)
6072 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6074 if(index >= es2::MAX_VERTEX_ATTRIBS)
6076 return error(GL_INVALID_VALUE);
6079 es2::Context *context = es2::getContext();
6083 context->setVertexAttrib(index, values);
6087 void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
6089 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
6090 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
6091 index, size, type, normalized, stride, ptr);
6093 if(index >= es2::MAX_VERTEX_ATTRIBS)
6095 return error(GL_INVALID_VALUE);
6098 if(size < 1 || size > 4)
6100 return error(GL_INVALID_VALUE);
6103 GLint clientVersion = egl::getClientVersion();
6108 case GL_UNSIGNED_BYTE:
6110 case GL_UNSIGNED_SHORT:
6113 case GL_HALF_FLOAT_OES: // GL_OES_vertex_half_float
6116 case GL_INT_2_10_10_10_REV:
6117 case GL_UNSIGNED_INT_2_10_10_10_REV:
6118 if(clientVersion >= 3)
6122 return error(GL_INVALID_OPERATION);
6126 else return error(GL_INVALID_ENUM);
6128 case GL_UNSIGNED_INT:
6129 if(clientVersion >= 3)
6133 else return error(GL_INVALID_ENUM);
6135 return error(GL_INVALID_ENUM);
6140 return error(GL_INVALID_VALUE);
6143 es2::Context *context = es2::getContext();
6147 es2::VertexArray* vertexArray = context->getCurrentVertexArray();
6148 if((context->getArrayBufferName() == 0) && vertexArray && (vertexArray->name != 0) && ptr)
6150 // GL_INVALID_OPERATION is generated if a non-zero vertex array object is bound, zero is bound
6151 // to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.
6152 return error(GL_INVALID_OPERATION);
6155 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), false, stride, ptr);
6159 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
6161 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
6163 if(width < 0 || height < 0)
6165 return error(GL_INVALID_VALUE);
6168 es2::Context *context = es2::getContext();
6172 context->setViewportParams(x, y, width, height);
6176 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)
6178 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6179 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6180 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6181 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6188 return error(GL_INVALID_ENUM);
6191 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6193 return error(GL_INVALID_VALUE);
6196 es2::Context *context = es2::getContext();
6200 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
6202 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6203 return error(GL_INVALID_OPERATION);
6206 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, false, allowPartialDepthStencilBlit);
6210 void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
6212 BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, true);
6215 void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6216 GLbitfield mask, GLenum filter)
6218 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6220 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6221 return error(GL_INVALID_OPERATION);
6224 BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, false);
6227 void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6228 GLint border, GLenum format, GLenum type, const GLvoid* data)
6230 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6231 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
6232 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
6233 target, level, internalformat, width, height, depth, border, format, type, data);
6240 case GL_DEPTH_COMPONENT:
6241 case GL_DEPTH_STENCIL_OES:
6242 return error(GL_INVALID_OPERATION);
6248 return error(GL_INVALID_ENUM);
6251 if(internalformat != format)
6253 return error(GL_INVALID_OPERATION);
6256 GLenum validationError = ValidateTextureFormatType(format, type, internalformat, target, egl::getClientVersion());
6257 if(validationError != GL_NO_ERROR)
6259 return error(validationError);
6262 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6264 return error(GL_INVALID_VALUE);
6267 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE >> level;
6268 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6270 return error(GL_INVALID_VALUE);
6275 return error(GL_INVALID_VALUE);
6278 es2::Context *context = es2::getContext();
6282 es2::Texture3D *texture = context->getTexture3D();
6286 return error(GL_INVALID_OPERATION);
6289 GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type));
6290 if(validationError != GL_NO_ERROR)
6292 return error(validationError);
6295 GLint sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);
6296 texture->setImage(level, width, height, depth, sizedInternalFormat, format, type, context->getUnpackParameters(), data);
6300 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)
6302 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6303 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6304 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
6305 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
6312 return error(GL_INVALID_ENUM);
6315 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6317 return error(GL_INVALID_VALUE);
6320 if((width < 0) || (height < 0) || (depth < 0))
6322 return error(GL_INVALID_VALUE);
6325 es2::Context *context = es2::getContext();
6329 es2::Texture3D *texture = context->getTexture3D();
6331 GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion());
6332 if(validationError != GL_NO_ERROR)
6334 return error(validationError);
6337 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type));
6338 if(validationError != GL_NO_ERROR)
6340 return error(validationError);
6343 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackParameters(), data);
6347 void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
6349 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6350 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
6351 target, level, xoffset, yoffset, zoffset, x, y, width, height);
6358 return error(GL_INVALID_ENUM);
6361 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6363 return error(GL_INVALID_VALUE);
6366 es2::Context *context = es2::getContext();
6370 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6372 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
6374 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6377 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
6379 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
6381 return error(GL_INVALID_OPERATION);
6384 es2::Texture3D *texture = context->getTexture3D();
6386 GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, zoffset, width, height, 1, GL_NONE, GL_NONE, texture, context->getClientVersion());
6387 if(validationError != GL_NO_ERROR)
6389 return error(validationError);
6392 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
6396 void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
6398 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
6399 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
6400 target, level, internalformat, width, height, depth, border, imageSize, data);
6407 return error(GL_INVALID_ENUM);
6410 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6412 return error(GL_INVALID_VALUE);
6415 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE >> level;
6416 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6418 return error(GL_INVALID_VALUE);
6421 if(!IsCompressed(internalformat, egl::getClientVersion()))
6423 return error(GL_INVALID_ENUM);
6426 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat) * depth)
6428 return error(GL_INVALID_VALUE);
6431 es2::Context *context = es2::getContext();
6435 es2::Texture3D *texture = context->getTexture3D();
6439 return error(GL_INVALID_OPERATION);
6442 GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
6444 if(validationError != GL_NO_ERROR)
6446 return error(validationError);
6449 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
6453 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)
6455 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6456 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6457 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
6458 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6465 return error(GL_INVALID_ENUM);
6468 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6470 return error(GL_INVALID_VALUE);
6473 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6475 return error(GL_INVALID_VALUE);
6478 if(!IsCompressed(format, egl::getClientVersion()))
6480 return error(GL_INVALID_ENUM);
6483 if(imageSize != gl::ComputeCompressedSize(width, height, format) * depth)
6485 return error(GL_INVALID_VALUE);
6488 es2::Context *context = es2::getContext();
6492 es2::Texture3D *texture = context->getTexture3D();
6496 return error(GL_INVALID_OPERATION);
6499 GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
6500 if(validationError != GL_NO_ERROR)
6502 return error(validationError);
6505 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6509 void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
6511 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6512 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6514 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
6516 return error(GL_INVALID_ENUM);
6519 es2::Context *context = es2::getContext();
6525 textarget = GL_NONE;
6529 es2::Texture *tex = context->getTexture(texture);
6533 return error(GL_INVALID_OPERATION);
6536 if(tex->isCompressed(textarget, level))
6538 return error(GL_INVALID_OPERATION);
6544 if(tex->getTarget() != GL_TEXTURE_3D)
6546 return error(GL_INVALID_OPERATION);
6550 return error(GL_INVALID_ENUM);
6555 return error(GL_INVALID_VALUE);
6559 es2::Framebuffer *framebuffer = nullptr;
6560 GLuint framebufferName = 0;
6561 if(target == GL_READ_FRAMEBUFFER)
6563 framebuffer = context->getReadFramebuffer();
6564 framebufferName = context->getReadFramebufferName();
6568 framebuffer = context->getDrawFramebuffer();
6569 framebufferName = context->getDrawFramebufferName();
6572 if(framebufferName == 0 || !framebuffer)
6574 return error(GL_INVALID_OPERATION);
6577 GLint clientVersion = context->getClientVersion();
6581 case GL_COLOR_ATTACHMENT1:
6582 case GL_COLOR_ATTACHMENT2:
6583 case GL_COLOR_ATTACHMENT3:
6584 case GL_COLOR_ATTACHMENT4:
6585 case GL_COLOR_ATTACHMENT5:
6586 case GL_COLOR_ATTACHMENT6:
6587 case GL_COLOR_ATTACHMENT7:
6588 case GL_COLOR_ATTACHMENT8:
6589 case GL_COLOR_ATTACHMENT9:
6590 case GL_COLOR_ATTACHMENT10:
6591 case GL_COLOR_ATTACHMENT11:
6592 case GL_COLOR_ATTACHMENT12:
6593 case GL_COLOR_ATTACHMENT13:
6594 case GL_COLOR_ATTACHMENT14:
6595 case GL_COLOR_ATTACHMENT15:
6596 case GL_COLOR_ATTACHMENT16:
6597 case GL_COLOR_ATTACHMENT17:
6598 case GL_COLOR_ATTACHMENT18:
6599 case GL_COLOR_ATTACHMENT19:
6600 case GL_COLOR_ATTACHMENT20:
6601 case GL_COLOR_ATTACHMENT21:
6602 case GL_COLOR_ATTACHMENT22:
6603 case GL_COLOR_ATTACHMENT23:
6604 case GL_COLOR_ATTACHMENT24:
6605 case GL_COLOR_ATTACHMENT25:
6606 case GL_COLOR_ATTACHMENT26:
6607 case GL_COLOR_ATTACHMENT27:
6608 case GL_COLOR_ATTACHMENT28:
6609 case GL_COLOR_ATTACHMENT29:
6610 case GL_COLOR_ATTACHMENT30:
6611 case GL_COLOR_ATTACHMENT31:
6612 if(clientVersion < 3)
6614 return error(GL_INVALID_ENUM);
6617 case GL_COLOR_ATTACHMENT0:
6618 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
6620 return error(GL_INVALID_ENUM);
6622 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
6624 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
6625 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6627 return error(GL_INVALID_ENUM);
6632 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
6634 if(egl::getClientVersion() == 1)
6636 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
6639 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6644 case GL_TEXTURE_RECTANGLE_ARB:
6645 case GL_TEXTURE_EXTERNAL_OES:
6648 return error(GL_INVALID_ENUM);
6651 es2::Context *context = es2::getContext();
6655 es2::Texture2D *texture = context->getTexture2D(target);
6659 return error(GL_INVALID_OPERATION);
6662 egl::Image *eglImage = context->getSharedImage(image);
6666 return error(GL_INVALID_OPERATION);
6669 texture->setSharedImage(eglImage);
6673 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
6675 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6680 GLboolean IsRenderbufferOES(GLuint renderbuffer)
6682 return IsRenderbuffer(renderbuffer);
6685 void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
6687 BindRenderbuffer(target, renderbuffer);
6690 void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
6692 DeleteRenderbuffers(n, renderbuffers);
6695 void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
6697 GenRenderbuffers(n, renderbuffers);
6700 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
6702 RenderbufferStorage(target, internalformat, width, height);
6705 void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
6707 GetRenderbufferParameteriv(target, pname, params);
6710 GLboolean IsFramebufferOES(GLuint framebuffer)
6712 return IsFramebuffer(framebuffer);
6715 void BindFramebufferOES(GLenum target, GLuint framebuffer)
6717 BindFramebuffer(target, framebuffer);
6720 void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
6722 DeleteFramebuffers(n, framebuffers);
6725 void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
6727 GenFramebuffers(n, framebuffers);
6730 GLenum CheckFramebufferStatusOES(GLenum target)
6732 return CheckFramebufferStatus(target);
6735 void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
6737 FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
6740 void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
6742 FramebufferTexture2D(target, attachment, textarget, texture, level);
6745 void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
6747 GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
6750 void GenerateMipmapOES(GLenum target)
6752 GenerateMipmap(target);
6755 void DrawBuffersEXT(GLsizei n, const GLenum *bufs)
6757 TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);
6759 if(n < 0 || n > MAX_DRAW_BUFFERS)
6761 return error(GL_INVALID_VALUE);
6764 es2::Context *context = es2::getContext();
6768 GLuint drawFramebufferName = context->getDrawFramebufferName();
6770 if((drawFramebufferName == 0) && (n != 1))
6772 return error(GL_INVALID_OPERATION);
6775 for(unsigned int i = 0; i < (unsigned)n; i++)
6780 if(drawFramebufferName != 0)
6782 return error(GL_INVALID_OPERATION);
6787 case GL_COLOR_ATTACHMENT0_EXT:
6788 case GL_COLOR_ATTACHMENT1_EXT:
6789 case GL_COLOR_ATTACHMENT2_EXT:
6790 case GL_COLOR_ATTACHMENT3_EXT:
6791 case GL_COLOR_ATTACHMENT4_EXT:
6792 case GL_COLOR_ATTACHMENT5_EXT:
6793 case GL_COLOR_ATTACHMENT6_EXT:
6794 case GL_COLOR_ATTACHMENT7_EXT:
6795 case GL_COLOR_ATTACHMENT8_EXT:
6796 case GL_COLOR_ATTACHMENT9_EXT:
6797 case GL_COLOR_ATTACHMENT10_EXT:
6798 case GL_COLOR_ATTACHMENT11_EXT:
6799 case GL_COLOR_ATTACHMENT12_EXT:
6800 case GL_COLOR_ATTACHMENT13_EXT:
6801 case GL_COLOR_ATTACHMENT14_EXT:
6802 case GL_COLOR_ATTACHMENT15_EXT:
6804 GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0_EXT);
6806 if(index >= MAX_COLOR_ATTACHMENTS)
6808 return error(GL_INVALID_OPERATION);
6813 return error(GL_INVALID_OPERATION);
6816 if(drawFramebufferName == 0)
6818 return error(GL_INVALID_OPERATION);
6823 return error(GL_INVALID_ENUM);
6827 context->setFramebufferDrawBuffers(n, bufs);
6833 extern "C" NO_SANITIZE_FUNCTION __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
6838 __eglMustCastToProperFunctionPointerType address;
6841 struct CompareFunctor
6843 bool operator()(const Function &a, const Function &b) const
6845 return strcmp(a.name, b.name) < 0;
6849 // This array must be kept sorted with respect to strcmp(), so that binary search works correctly.
6850 // The Unix command "LC_COLLATE=C sort" will generate the correct order.
6851 static const Function glFunctions[] =
6853 #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6855 FUNCTION(glActiveTexture),
6856 FUNCTION(glAttachShader),
6857 FUNCTION(glBeginQuery),
6858 FUNCTION(glBeginQueryEXT),
6859 FUNCTION(glBeginTransformFeedback),
6860 FUNCTION(glBindAttribLocation),
6861 FUNCTION(glBindBuffer),
6862 FUNCTION(glBindBufferBase),
6863 FUNCTION(glBindBufferRange),
6864 FUNCTION(glBindFramebuffer),
6865 FUNCTION(glBindFramebufferOES),
6866 FUNCTION(glBindRenderbuffer),
6867 FUNCTION(glBindRenderbufferOES),
6868 FUNCTION(glBindSampler),
6869 FUNCTION(glBindTexture),
6870 FUNCTION(glBindTransformFeedback),
6871 FUNCTION(glBindVertexArray),
6872 FUNCTION(glBindVertexArrayOES),
6873 FUNCTION(glBlendColor),
6874 FUNCTION(glBlendEquation),
6875 FUNCTION(glBlendEquationSeparate),
6876 FUNCTION(glBlendFunc),
6877 FUNCTION(glBlendFuncSeparate),
6878 FUNCTION(glBlitFramebuffer),
6879 FUNCTION(glBlitFramebufferANGLE),
6880 FUNCTION(glBufferData),
6881 FUNCTION(glBufferSubData),
6882 FUNCTION(glCheckFramebufferStatus),
6883 FUNCTION(glCheckFramebufferStatusOES),
6885 FUNCTION(glClearBufferfi),
6886 FUNCTION(glClearBufferfv),
6887 FUNCTION(glClearBufferiv),
6888 FUNCTION(glClearBufferuiv),
6889 FUNCTION(glClearColor),
6890 FUNCTION(glClearDepthf),
6891 FUNCTION(glClearStencil),
6892 FUNCTION(glClientWaitSync),
6893 FUNCTION(glColorMask),
6894 FUNCTION(glCompileShader),
6895 FUNCTION(glCompressedTexImage2D),
6896 FUNCTION(glCompressedTexImage3D),
6897 FUNCTION(glCompressedTexSubImage2D),
6898 FUNCTION(glCompressedTexSubImage3D),
6899 FUNCTION(glCopyBufferSubData),
6900 FUNCTION(glCopyTexImage2D),
6901 FUNCTION(glCopyTexSubImage2D),
6902 FUNCTION(glCopyTexSubImage3D),
6903 FUNCTION(glCreateProgram),
6904 FUNCTION(glCreateShader),
6905 FUNCTION(glCullFace),
6906 FUNCTION(glDeleteBuffers),
6907 FUNCTION(glDeleteFencesNV),
6908 FUNCTION(glDeleteFramebuffers),
6909 FUNCTION(glDeleteFramebuffersOES),
6910 FUNCTION(glDeleteProgram),
6911 FUNCTION(glDeleteQueries),
6912 FUNCTION(glDeleteQueriesEXT),
6913 FUNCTION(glDeleteRenderbuffers),
6914 FUNCTION(glDeleteRenderbuffersOES),
6915 FUNCTION(glDeleteSamplers),
6916 FUNCTION(glDeleteShader),
6917 FUNCTION(glDeleteSync),
6918 FUNCTION(glDeleteTextures),
6919 FUNCTION(glDeleteTransformFeedbacks),
6920 FUNCTION(glDeleteVertexArrays),
6921 FUNCTION(glDeleteVertexArraysOES),
6922 FUNCTION(glDepthFunc),
6923 FUNCTION(glDepthMask),
6924 FUNCTION(glDepthRangef),
6925 FUNCTION(glDetachShader),
6926 FUNCTION(glDisable),
6927 FUNCTION(glDisableVertexAttribArray),
6928 FUNCTION(glDrawArrays),
6929 FUNCTION(glDrawArraysInstanced),
6930 FUNCTION(glDrawBuffers),
6931 FUNCTION(glDrawBuffersEXT),
6932 FUNCTION(glDrawElements),
6933 FUNCTION(glDrawElementsInstanced),
6934 FUNCTION(glDrawRangeElements),
6935 FUNCTION(glEGLImageTargetRenderbufferStorageOES),
6936 FUNCTION(glEGLImageTargetTexture2DOES),
6938 FUNCTION(glEnableVertexAttribArray),
6939 FUNCTION(glEndQuery),
6940 FUNCTION(glEndQueryEXT),
6941 FUNCTION(glEndTransformFeedback),
6942 FUNCTION(glFenceSync),
6944 FUNCTION(glFinishFenceNV),
6946 FUNCTION(glFlushMappedBufferRange),
6947 FUNCTION(glFramebufferRenderbuffer),
6948 FUNCTION(glFramebufferRenderbufferOES),
6949 FUNCTION(glFramebufferTexture2D),
6950 FUNCTION(glFramebufferTexture2DOES),
6951 FUNCTION(glFramebufferTextureLayer),
6952 FUNCTION(glFrontFace),
6953 FUNCTION(glGenBuffers),
6954 FUNCTION(glGenFencesNV),
6955 FUNCTION(glGenFramebuffers),
6956 FUNCTION(glGenFramebuffersOES),
6957 FUNCTION(glGenQueries),
6958 FUNCTION(glGenQueriesEXT),
6959 FUNCTION(glGenRenderbuffers),
6960 FUNCTION(glGenRenderbuffersOES),
6961 FUNCTION(glGenSamplers),
6962 FUNCTION(glGenTextures),
6963 FUNCTION(glGenTransformFeedbacks),
6964 FUNCTION(glGenVertexArrays),
6965 FUNCTION(glGenVertexArraysOES),
6966 FUNCTION(glGenerateMipmap),
6967 FUNCTION(glGenerateMipmapOES),
6968 FUNCTION(glGetActiveAttrib),
6969 FUNCTION(glGetActiveUniform),
6970 FUNCTION(glGetActiveUniformBlockName),
6971 FUNCTION(glGetActiveUniformBlockiv),
6972 FUNCTION(glGetActiveUniformsiv),
6973 FUNCTION(glGetAttachedShaders),
6974 FUNCTION(glGetAttribLocation),
6975 FUNCTION(glGetBooleanv),
6976 FUNCTION(glGetBufferParameteri64v),
6977 FUNCTION(glGetBufferParameteriv),
6978 FUNCTION(glGetBufferPointerv),
6979 FUNCTION(glGetError),
6980 FUNCTION(glGetFenceivNV),
6981 FUNCTION(glGetFloatv),
6982 FUNCTION(glGetFragDataLocation),
6983 FUNCTION(glGetFramebufferAttachmentParameteriv),
6984 FUNCTION(glGetFramebufferAttachmentParameterivOES),
6985 FUNCTION(glGetGraphicsResetStatusEXT),
6986 FUNCTION(glGetInteger64i_v),
6987 FUNCTION(glGetInteger64v),
6988 FUNCTION(glGetIntegeri_v),
6989 FUNCTION(glGetIntegerv),
6990 FUNCTION(glGetInternalformativ),
6991 FUNCTION(glGetProgramBinary),
6992 FUNCTION(glGetProgramInfoLog),
6993 FUNCTION(glGetProgramiv),
6994 FUNCTION(glGetQueryObjectuiv),
6995 FUNCTION(glGetQueryObjectuivEXT),
6996 FUNCTION(glGetQueryiv),
6997 FUNCTION(glGetQueryivEXT),
6998 FUNCTION(glGetRenderbufferParameteriv),
6999 FUNCTION(glGetRenderbufferParameterivOES),
7000 FUNCTION(glGetSamplerParameterfv),
7001 FUNCTION(glGetSamplerParameteriv),
7002 FUNCTION(glGetShaderInfoLog),
7003 FUNCTION(glGetShaderPrecisionFormat),
7004 FUNCTION(glGetShaderSource),
7005 FUNCTION(glGetShaderiv),
7006 FUNCTION(glGetString),
7007 FUNCTION(glGetStringi),
7008 FUNCTION(glGetSynciv),
7009 FUNCTION(glGetTexParameterfv),
7010 FUNCTION(glGetTexParameteriv),
7011 FUNCTION(glGetTransformFeedbackVarying),
7012 FUNCTION(glGetUniformBlockIndex),
7013 FUNCTION(glGetUniformIndices),
7014 FUNCTION(glGetUniformLocation),
7015 FUNCTION(glGetUniformfv),
7016 FUNCTION(glGetUniformiv),
7017 FUNCTION(glGetUniformuiv),
7018 FUNCTION(glGetVertexAttribIiv),
7019 FUNCTION(glGetVertexAttribIuiv),
7020 FUNCTION(glGetVertexAttribPointerv),
7021 FUNCTION(glGetVertexAttribfv),
7022 FUNCTION(glGetVertexAttribiv),
7023 FUNCTION(glGetnUniformfvEXT),
7024 FUNCTION(glGetnUniformivEXT),
7026 FUNCTION(glInvalidateFramebuffer),
7027 FUNCTION(glInvalidateSubFramebuffer),
7028 FUNCTION(glIsBuffer),
7029 FUNCTION(glIsEnabled),
7030 FUNCTION(glIsFenceNV),
7031 FUNCTION(glIsFramebuffer),
7032 FUNCTION(glIsFramebufferOES),
7033 FUNCTION(glIsProgram),
7034 FUNCTION(glIsQuery),
7035 FUNCTION(glIsQueryEXT),
7036 FUNCTION(glIsRenderbuffer),
7037 FUNCTION(glIsRenderbufferOES),
7038 FUNCTION(glIsSampler),
7039 FUNCTION(glIsShader),
7041 FUNCTION(glIsTexture),
7042 FUNCTION(glIsTransformFeedback),
7043 FUNCTION(glIsVertexArray),
7044 FUNCTION(glIsVertexArrayOES),
7045 FUNCTION(glLineWidth),
7046 FUNCTION(glLinkProgram),
7047 FUNCTION(glMapBufferRange),
7048 FUNCTION(glPauseTransformFeedback),
7049 FUNCTION(glPixelStorei),
7050 FUNCTION(glPolygonOffset),
7051 FUNCTION(glProgramBinary),
7052 FUNCTION(glProgramParameteri),
7053 FUNCTION(glReadBuffer),
7054 FUNCTION(glReadPixels),
7055 FUNCTION(glReadnPixelsEXT),
7056 FUNCTION(glReleaseShaderCompiler),
7057 FUNCTION(glRenderbufferStorage),
7058 FUNCTION(glRenderbufferStorageMultisample),
7059 FUNCTION(glRenderbufferStorageMultisampleANGLE),
7060 FUNCTION(glRenderbufferStorageOES),
7061 FUNCTION(glResumeTransformFeedback),
7062 FUNCTION(glSampleCoverage),
7063 FUNCTION(glSamplerParameterf),
7064 FUNCTION(glSamplerParameterfv),
7065 FUNCTION(glSamplerParameteri),
7066 FUNCTION(glSamplerParameteriv),
7067 FUNCTION(glScissor),
7068 FUNCTION(glSetFenceNV),
7069 FUNCTION(glShaderBinary),
7070 FUNCTION(glShaderSource),
7071 FUNCTION(glStencilFunc),
7072 FUNCTION(glStencilFuncSeparate),
7073 FUNCTION(glStencilMask),
7074 FUNCTION(glStencilMaskSeparate),
7075 FUNCTION(glStencilOp),
7076 FUNCTION(glStencilOpSeparate),
7077 FUNCTION(glTestFenceNV),
7078 FUNCTION(glTexImage2D),
7079 FUNCTION(glTexImage3D),
7080 FUNCTION(glTexImage3DOES),
7081 FUNCTION(glTexParameterf),
7082 FUNCTION(glTexParameterfv),
7083 FUNCTION(glTexParameteri),
7084 FUNCTION(glTexParameteriv),
7085 FUNCTION(glTexStorage2D),
7086 FUNCTION(glTexStorage3D),
7087 FUNCTION(glTexSubImage2D),
7088 FUNCTION(glTexSubImage3D),
7089 FUNCTION(glTransformFeedbackVaryings),
7090 FUNCTION(glUniform1f),
7091 FUNCTION(glUniform1fv),
7092 FUNCTION(glUniform1i),
7093 FUNCTION(glUniform1iv),
7094 FUNCTION(glUniform1ui),
7095 FUNCTION(glUniform1uiv),
7096 FUNCTION(glUniform2f),
7097 FUNCTION(glUniform2fv),
7098 FUNCTION(glUniform2i),
7099 FUNCTION(glUniform2iv),
7100 FUNCTION(glUniform2ui),
7101 FUNCTION(glUniform2uiv),
7102 FUNCTION(glUniform3f),
7103 FUNCTION(glUniform3fv),
7104 FUNCTION(glUniform3i),
7105 FUNCTION(glUniform3iv),
7106 FUNCTION(glUniform3ui),
7107 FUNCTION(glUniform3uiv),
7108 FUNCTION(glUniform4f),
7109 FUNCTION(glUniform4fv),
7110 FUNCTION(glUniform4i),
7111 FUNCTION(glUniform4iv),
7112 FUNCTION(glUniform4ui),
7113 FUNCTION(glUniform4uiv),
7114 FUNCTION(glUniformBlockBinding),
7115 FUNCTION(glUniformMatrix2fv),
7116 FUNCTION(glUniformMatrix2x3fv),
7117 FUNCTION(glUniformMatrix2x4fv),
7118 FUNCTION(glUniformMatrix3fv),
7119 FUNCTION(glUniformMatrix3x2fv),
7120 FUNCTION(glUniformMatrix3x4fv),
7121 FUNCTION(glUniformMatrix4fv),
7122 FUNCTION(glUniformMatrix4x2fv),
7123 FUNCTION(glUniformMatrix4x3fv),
7124 FUNCTION(glUnmapBuffer),
7125 FUNCTION(glUseProgram),
7126 FUNCTION(glValidateProgram),
7127 FUNCTION(glVertexAttrib1f),
7128 FUNCTION(glVertexAttrib1fv),
7129 FUNCTION(glVertexAttrib2f),
7130 FUNCTION(glVertexAttrib2fv),
7131 FUNCTION(glVertexAttrib3f),
7132 FUNCTION(glVertexAttrib3fv),
7133 FUNCTION(glVertexAttrib4f),
7134 FUNCTION(glVertexAttrib4fv),
7135 FUNCTION(glVertexAttribDivisor),
7136 FUNCTION(glVertexAttribDivisorANGLE),
7137 FUNCTION(glVertexAttribDivisorEXT),
7138 FUNCTION(glVertexAttribI4i),
7139 FUNCTION(glVertexAttribI4iv),
7140 FUNCTION(glVertexAttribI4ui),
7141 FUNCTION(glVertexAttribI4uiv),
7142 FUNCTION(glVertexAttribIPointer),
7143 FUNCTION(glVertexAttribPointer),
7144 FUNCTION(glViewport),
7145 FUNCTION(glWaitSync),
7150 static const size_t numFunctions = sizeof glFunctions / sizeof(Function);
7151 static const Function *const glFunctionsEnd = glFunctions + numFunctions;
7154 needle.name = procname;
7156 if(procname && strncmp("gl", procname, 2) == 0)
7158 const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor());
7159 if(result != glFunctionsEnd && strcmp(procname, result->name) == 0)
7161 return (__eglMustCastToProperFunctionPointerType)result->address;