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.
15 // libGLESv3.cpp: Implements the exported OpenGL ES 3.0 functions.
20 #include "Framebuffer.h"
26 #include "TransformFeedback.h"
27 #include "VertexArray.h"
28 #include "common/debug.h"
30 #include <GLES3/gl3.h>
31 #include <GLES2/gl2ext.h>
37 typedef std::pair<GLenum, GLenum> InternalFormatTypePair;
38 typedef std::map<InternalFormatTypePair, GLenum> FormatMap;
40 // A helper function to insert data into the format map with fewer characters.
41 static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)
43 map[InternalFormatTypePair(internalformat, type)] = format;
46 static bool validImageSize(GLint level, GLsizei width, GLsizei height)
48 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
56 static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
58 GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);
59 if(validationError != GL_NONE)
61 return error(validationError, false);
67 if(colorbufferFormat != GL_ALPHA &&
68 colorbufferFormat != GL_RGBA &&
69 colorbufferFormat != GL_RGBA4 &&
70 colorbufferFormat != GL_RGB5_A1 &&
71 colorbufferFormat != GL_RGBA8)
73 return error(GL_INVALID_OPERATION, false);
78 if(colorbufferFormat != GL_RGB &&
79 colorbufferFormat != GL_RGB565 &&
80 colorbufferFormat != GL_RGB8 &&
81 colorbufferFormat != GL_RGBA &&
82 colorbufferFormat != GL_RGBA4 &&
83 colorbufferFormat != GL_RGB5_A1 &&
84 colorbufferFormat != GL_RGBA8)
86 return error(GL_INVALID_OPERATION, false);
89 case GL_LUMINANCE_ALPHA:
91 if(colorbufferFormat != GL_RGBA &&
92 colorbufferFormat != GL_RGBA4 &&
93 colorbufferFormat != GL_RGB5_A1 &&
94 colorbufferFormat != GL_RGBA8)
96 return error(GL_INVALID_OPERATION, false);
99 case GL_DEPTH_COMPONENT:
100 case GL_DEPTH_STENCIL:
101 return error(GL_INVALID_OPERATION, false);
103 return error(GL_INVALID_ENUM, false);
108 static FormatMap BuildFormatMap3D()
112 // Internal format | Format | Type
113 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
114 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
115 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
116 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
117 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
118 InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
119 InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
120 InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
121 InsertFormatMapping(map, GL_R8, GL_RED, GL_UNSIGNED_BYTE);
122 InsertFormatMapping(map, GL_R8_SNORM, GL_RED, GL_BYTE);
123 InsertFormatMapping(map, GL_R16F, GL_RED, GL_HALF_FLOAT);
124 InsertFormatMapping(map, GL_R16F, GL_RED, GL_FLOAT);
125 InsertFormatMapping(map, GL_R32F, GL_RED, GL_FLOAT);
126 InsertFormatMapping(map, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE);
127 InsertFormatMapping(map, GL_R8I, GL_RED_INTEGER, GL_BYTE);
128 InsertFormatMapping(map, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT);
129 InsertFormatMapping(map, GL_R16I, GL_RED_INTEGER, GL_SHORT);
130 InsertFormatMapping(map, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT);
131 InsertFormatMapping(map, GL_R32I, GL_RED_INTEGER, GL_INT);
132 InsertFormatMapping(map, GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
133 InsertFormatMapping(map, GL_RG8_SNORM, GL_RG, GL_BYTE);
134 InsertFormatMapping(map, GL_RG16F, GL_RG, GL_HALF_FLOAT);
135 InsertFormatMapping(map, GL_RG16F, GL_RG, GL_FLOAT);
136 InsertFormatMapping(map, GL_RG32F, GL_RG, GL_FLOAT);
137 InsertFormatMapping(map, GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE);
138 InsertFormatMapping(map, GL_RG8I, GL_RG_INTEGER, GL_BYTE);
139 InsertFormatMapping(map, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT);
140 InsertFormatMapping(map, GL_RG16I, GL_RG_INTEGER, GL_SHORT);
141 InsertFormatMapping(map, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT);
142 InsertFormatMapping(map, GL_RG32I, GL_RG_INTEGER, GL_INT);
143 InsertFormatMapping(map, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE);
144 InsertFormatMapping(map, GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE);
145 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);
146 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
147 InsertFormatMapping(map, GL_RGB8_SNORM, GL_RGB, GL_BYTE);
148 InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV);
149 InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT);
150 InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
151 InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV);
152 InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT);
153 InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_FLOAT);
154 InsertFormatMapping(map, GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
155 InsertFormatMapping(map, GL_RGB16F, GL_RGB, GL_FLOAT);
156 InsertFormatMapping(map, GL_RGB32F, GL_RGB, GL_FLOAT);
157 InsertFormatMapping(map, GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE);
158 InsertFormatMapping(map, GL_RGB8I, GL_RGB_INTEGER, GL_BYTE);
159 InsertFormatMapping(map, GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT);
160 InsertFormatMapping(map, GL_RGB16I, GL_RGB_INTEGER, GL_SHORT);
161 InsertFormatMapping(map, GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT);
162 InsertFormatMapping(map, GL_RGB32I, GL_RGB_INTEGER, GL_INT);
163 InsertFormatMapping(map, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
164 InsertFormatMapping(map, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE);
165 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);
166 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
167 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
168 InsertFormatMapping(map, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE);
169 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);
170 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
171 InsertFormatMapping(map, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
172 InsertFormatMapping(map, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
173 InsertFormatMapping(map, GL_RGBA16F, GL_RGBA, GL_FLOAT);
174 InsertFormatMapping(map, GL_RGBA32F, GL_RGBA, GL_FLOAT);
175 InsertFormatMapping(map, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE);
176 InsertFormatMapping(map, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE);
177 InsertFormatMapping(map, GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV);
178 InsertFormatMapping(map, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT);
179 InsertFormatMapping(map, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT);
180 InsertFormatMapping(map, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
181 InsertFormatMapping(map, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
183 InsertFormatMapping(map, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
184 InsertFormatMapping(map, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
185 InsertFormatMapping(map, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
186 InsertFormatMapping(map, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
187 InsertFormatMapping(map, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
188 InsertFormatMapping(map, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
189 InsertFormatMapping(map, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
194 static bool ValidateType3D(GLenum type)
198 case GL_UNSIGNED_BYTE:
200 case GL_UNSIGNED_SHORT:
202 case GL_UNSIGNED_INT:
206 case GL_UNSIGNED_SHORT_5_6_5:
207 case GL_UNSIGNED_SHORT_4_4_4_4:
208 case GL_UNSIGNED_SHORT_5_5_5_1:
209 case GL_UNSIGNED_INT_2_10_10_10_REV:
210 case GL_UNSIGNED_INT_10F_11F_11F_REV:
211 case GL_UNSIGNED_INT_5_9_9_9_REV:
212 case GL_UNSIGNED_INT_24_8:
213 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
221 static bool ValidateFormat3D(GLenum format)
229 case GL_DEPTH_COMPONENT:
230 case GL_DEPTH_STENCIL:
231 case GL_LUMINANCE_ALPHA:
237 case GL_RGBA_INTEGER:
245 static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)
247 static const FormatMap formatMap = BuildFormatMap3D();
248 FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));
249 if(iter != formatMap.end())
251 return iter->second == format;
256 typedef std::map<GLenum, GLenum> FormatMapStorage;
258 // A helper function to insert data into the format map with fewer characters.
259 static void InsertFormatStorageMapping(FormatMapStorage& map, GLenum internalformat, GLenum type)
261 map[internalformat] = type;
264 static FormatMapStorage BuildFormatMapStorage2D()
266 FormatMapStorage map;
268 // Internal format | Type
269 InsertFormatStorageMapping(map, GL_R8, GL_UNSIGNED_BYTE);
270 InsertFormatStorageMapping(map, GL_R8_SNORM, GL_UNSIGNED_BYTE);
271 InsertFormatStorageMapping(map, GL_R16F, GL_HALF_FLOAT);
272 InsertFormatStorageMapping(map, GL_R32F, GL_FLOAT);
273 InsertFormatStorageMapping(map, GL_R8UI, GL_UNSIGNED_BYTE);
274 InsertFormatStorageMapping(map, GL_R8I, GL_BYTE);
275 InsertFormatStorageMapping(map, GL_R16UI, GL_UNSIGNED_SHORT);
276 InsertFormatStorageMapping(map, GL_R16I, GL_SHORT);
277 InsertFormatStorageMapping(map, GL_R32UI, GL_UNSIGNED_INT);
278 InsertFormatStorageMapping(map, GL_R32I, GL_INT);
279 InsertFormatStorageMapping(map, GL_RG8, GL_UNSIGNED_BYTE);
280 InsertFormatStorageMapping(map, GL_RG8_SNORM, GL_BYTE);
281 InsertFormatStorageMapping(map, GL_RG16F, GL_HALF_FLOAT);
282 InsertFormatStorageMapping(map, GL_RG32F, GL_FLOAT);
283 InsertFormatStorageMapping(map, GL_RG8UI, GL_UNSIGNED_BYTE);
284 InsertFormatStorageMapping(map, GL_RG8I, GL_BYTE);
285 InsertFormatStorageMapping(map, GL_RG16UI, GL_UNSIGNED_SHORT);
286 InsertFormatStorageMapping(map, GL_RG16I, GL_SHORT);
287 InsertFormatStorageMapping(map, GL_RG32UI, GL_UNSIGNED_INT);
288 InsertFormatStorageMapping(map, GL_RG32I, GL_INT);
289 InsertFormatStorageMapping(map, GL_RGB8, GL_UNSIGNED_BYTE);
290 InsertFormatStorageMapping(map, GL_SRGB8, GL_UNSIGNED_BYTE);
291 InsertFormatStorageMapping(map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5);
292 InsertFormatStorageMapping(map, GL_RGB8_SNORM, GL_BYTE);
293 InsertFormatStorageMapping(map, GL_R11F_G11F_B10F, GL_UNSIGNED_INT_10F_11F_11F_REV);
294 InsertFormatStorageMapping(map, GL_RGB9_E5, GL_UNSIGNED_INT_5_9_9_9_REV);
295 InsertFormatStorageMapping(map, GL_RGB16F, GL_HALF_FLOAT);
296 InsertFormatStorageMapping(map, GL_RGB32F, GL_FLOAT);
297 InsertFormatStorageMapping(map, GL_RGB8UI, GL_UNSIGNED_BYTE);
298 InsertFormatStorageMapping(map, GL_RGB8I, GL_BYTE);
299 InsertFormatStorageMapping(map, GL_RGB16UI, GL_UNSIGNED_SHORT);
300 InsertFormatStorageMapping(map, GL_RGB16I, GL_SHORT);
301 InsertFormatStorageMapping(map, GL_RGB32UI, GL_UNSIGNED_INT);
302 InsertFormatStorageMapping(map, GL_RGB32I, GL_INT);
303 InsertFormatStorageMapping(map, GL_RGBA8, GL_UNSIGNED_BYTE);
304 InsertFormatStorageMapping(map, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE);
305 InsertFormatStorageMapping(map, GL_RGBA8_SNORM, GL_BYTE);
306 InsertFormatStorageMapping(map, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1);
307 InsertFormatStorageMapping(map, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4);
308 InsertFormatStorageMapping(map, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV);
309 InsertFormatStorageMapping(map, GL_RGBA16F, GL_HALF_FLOAT);
310 InsertFormatStorageMapping(map, GL_RGBA32F, GL_FLOAT);
311 InsertFormatStorageMapping(map, GL_RGBA8UI, GL_UNSIGNED_BYTE);
312 InsertFormatStorageMapping(map, GL_RGBA8I, GL_BYTE);
313 InsertFormatStorageMapping(map, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV);
314 InsertFormatStorageMapping(map, GL_RGBA16UI, GL_UNSIGNED_SHORT);
315 InsertFormatStorageMapping(map, GL_RGBA16I, GL_SHORT);
316 InsertFormatStorageMapping(map, GL_RGBA32UI, GL_UNSIGNED_INT);
317 InsertFormatStorageMapping(map, GL_RGBA32I, GL_INT);
319 InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT);
320 InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT);
321 InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT32F, GL_FLOAT);
322 InsertFormatStorageMapping(map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8);
323 InsertFormatStorageMapping(map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
328 static bool GetStorageType(GLenum internalformat, GLenum& type)
330 static const FormatMapStorage formatMap = BuildFormatMapStorage2D();
331 FormatMapStorage::const_iterator iter = formatMap.find(internalformat);
332 if(iter != formatMap.end())
340 static bool ValidateQueryTarget(GLenum target)
344 case GL_ANY_SAMPLES_PASSED:
345 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
346 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
355 bool ValidateTexParamParameters(GLenum pname, GLint param)
359 case GL_TEXTURE_WRAP_S:
360 case GL_TEXTURE_WRAP_T:
361 case GL_TEXTURE_WRAP_R:
365 case GL_CLAMP_TO_EDGE:
366 case GL_MIRRORED_REPEAT:
369 return error(GL_INVALID_ENUM, false);
372 case GL_TEXTURE_MIN_FILTER:
377 case GL_NEAREST_MIPMAP_NEAREST:
378 case GL_LINEAR_MIPMAP_NEAREST:
379 case GL_NEAREST_MIPMAP_LINEAR:
380 case GL_LINEAR_MIPMAP_LINEAR:
383 return error(GL_INVALID_ENUM, false);
387 case GL_TEXTURE_MAG_FILTER:
394 return error(GL_INVALID_ENUM, false);
398 case GL_TEXTURE_USAGE_ANGLE:
402 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
405 return error(GL_INVALID_ENUM, false);
409 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
410 // we assume the parameter passed to this validation method is truncated, not rounded
413 return error(GL_INVALID_VALUE, false);
417 case GL_TEXTURE_MIN_LOD:
418 case GL_TEXTURE_MAX_LOD:
419 // any value is permissible
422 case GL_TEXTURE_COMPARE_MODE:
423 // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
427 case GL_COMPARE_REF_TO_TEXTURE:
430 return error(GL_INVALID_ENUM, false);
434 case GL_TEXTURE_COMPARE_FUNC:
435 // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
448 return error(GL_INVALID_ENUM, false);
452 case GL_TEXTURE_SWIZZLE_R:
453 case GL_TEXTURE_SWIZZLE_G:
454 case GL_TEXTURE_SWIZZLE_B:
455 case GL_TEXTURE_SWIZZLE_A:
466 return error(GL_INVALID_ENUM, false);
470 case GL_TEXTURE_BASE_LEVEL:
471 case GL_TEXTURE_MAX_LEVEL:
474 return error(GL_INVALID_VALUE, false);
479 return error(GL_INVALID_ENUM, false);
483 static bool ValidateSamplerObjectParameter(GLenum pname)
487 case GL_TEXTURE_MIN_FILTER:
488 case GL_TEXTURE_MAG_FILTER:
489 case GL_TEXTURE_WRAP_S:
490 case GL_TEXTURE_WRAP_T:
491 case GL_TEXTURE_WRAP_R:
492 case GL_TEXTURE_MIN_LOD:
493 case GL_TEXTURE_MAX_LOD:
494 case GL_TEXTURE_COMPARE_MODE:
495 case GL_TEXTURE_COMPARE_FUNC:
496 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
506 GL_APICALL void GL_APIENTRY glReadBuffer(GLenum src)
508 TRACE("(GLenum src = 0x%X)", src);
510 es2::Context *context = es2::getContext();
514 GLuint readFramebufferName = context->getReadFramebufferName();
519 if(readFramebufferName != 0)
521 return error(GL_INVALID_OPERATION);
523 context->setFramebufferReadBuffer(src);
526 context->setFramebufferReadBuffer(src);
528 case GL_COLOR_ATTACHMENT0:
529 case GL_COLOR_ATTACHMENT1:
530 case GL_COLOR_ATTACHMENT2:
531 case GL_COLOR_ATTACHMENT3:
532 case GL_COLOR_ATTACHMENT4:
533 case GL_COLOR_ATTACHMENT5:
534 case GL_COLOR_ATTACHMENT6:
535 case GL_COLOR_ATTACHMENT7:
536 case GL_COLOR_ATTACHMENT8:
537 case GL_COLOR_ATTACHMENT9:
538 case GL_COLOR_ATTACHMENT10:
539 case GL_COLOR_ATTACHMENT11:
540 case GL_COLOR_ATTACHMENT12:
541 case GL_COLOR_ATTACHMENT13:
542 case GL_COLOR_ATTACHMENT14:
543 case GL_COLOR_ATTACHMENT15:
544 case GL_COLOR_ATTACHMENT16:
545 case GL_COLOR_ATTACHMENT17:
546 case GL_COLOR_ATTACHMENT18:
547 case GL_COLOR_ATTACHMENT19:
548 case GL_COLOR_ATTACHMENT20:
549 case GL_COLOR_ATTACHMENT21:
550 case GL_COLOR_ATTACHMENT22:
551 case GL_COLOR_ATTACHMENT23:
552 case GL_COLOR_ATTACHMENT24:
553 case GL_COLOR_ATTACHMENT25:
554 case GL_COLOR_ATTACHMENT26:
555 case GL_COLOR_ATTACHMENT27:
556 case GL_COLOR_ATTACHMENT28:
557 case GL_COLOR_ATTACHMENT29:
558 case GL_COLOR_ATTACHMENT30:
559 case GL_COLOR_ATTACHMENT31:
561 GLuint index = (src - GL_COLOR_ATTACHMENT0);
562 if(index >= MAX_COLOR_ATTACHMENTS)
564 return error(GL_INVALID_OPERATION);
566 if(readFramebufferName == 0)
568 return error(GL_INVALID_OPERATION);
570 context->setFramebufferReadBuffer(src);
574 return error(GL_INVALID_ENUM);
579 GL_APICALL void GL_APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices)
581 TRACE("(GLenum mode = 0x%X, GLuint start = %d, GLuint end = %d, "
582 "GLsizei count = %d, GLenum type = 0x%x, const void* indices = %p)",
583 mode, start, end, count, type, indices);
592 case GL_TRIANGLE_FAN:
593 case GL_TRIANGLE_STRIP:
596 return error(GL_INVALID_ENUM);
601 case GL_UNSIGNED_BYTE:
602 case GL_UNSIGNED_SHORT:
603 case GL_UNSIGNED_INT:
606 return error(GL_INVALID_ENUM);
609 if((count < 0) || (end < start))
611 return error(GL_INVALID_VALUE);
614 es2::Context *context = es2::getContext();
618 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
619 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
621 return error(GL_INVALID_OPERATION);
624 context->drawElements(mode, start, end, count, type, indices);
628 GL_APICALL void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *data)
630 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
631 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
632 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
633 target, level, internalformat, width, height, depth, border, format, type, data);
638 case GL_TEXTURE_2D_ARRAY:
641 return error(GL_INVALID_ENUM);
644 if(!ValidateType3D(type) || !ValidateFormat3D(format))
646 return error(GL_INVALID_ENUM);
649 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
651 return error(GL_INVALID_VALUE);
654 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
655 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
657 return error(GL_INVALID_VALUE);
662 return error(GL_INVALID_VALUE);
665 if(!ValidateInternalFormat3D(internalformat, format, type))
667 return error(GL_INVALID_OPERATION);
670 es2::Context *context = es2::getContext();
674 es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
678 return error(GL_INVALID_OPERATION);
681 GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
683 GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
684 if(validationError != GL_NONE)
686 return error(validationError);
689 texture->setImage(context, level, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
693 GL_APICALL void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data)
695 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
696 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
697 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
698 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
703 case GL_TEXTURE_2D_ARRAY:
706 return error(GL_INVALID_ENUM);
709 if(!ValidateType3D(type) || !ValidateFormat3D(format))
711 return error(GL_INVALID_ENUM);
714 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
716 return error(GL_INVALID_VALUE);
719 if((width < 0) || (height < 0) || (depth < 0) || (xoffset < 0) || (yoffset < 0) || (zoffset < 0))
721 return error(GL_INVALID_VALUE);
724 es2::Context *context = es2::getContext();
728 es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
730 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
732 GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
733 if(validationError == GL_NONE)
735 GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
736 if(validationError != GL_NONE)
738 return error(validationError);
741 texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
745 return error(validationError);
750 GL_APICALL void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
752 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
753 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
754 target, level, xoffset, yoffset, zoffset, x, y, width, height);
759 case GL_TEXTURE_2D_ARRAY:
762 return error(GL_INVALID_ENUM);
765 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
767 return error(GL_INVALID_VALUE);
770 if((width < 0) || (height < 0) || (xoffset < 0) || (yoffset < 0) || (zoffset < 0))
772 return error(GL_INVALID_VALUE);
775 es2::Context *context = es2::getContext();
779 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
781 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
783 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
786 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
788 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
790 return error(GL_INVALID_OPERATION);
793 GLenum colorbufferFormat = source->getFormat();
794 es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
796 GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
797 if(validationError != GL_NONE)
799 return error(validationError);
802 GLenum textureFormat = texture->getFormat(target, level);
804 if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
809 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
813 GL_APICALL void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
815 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
816 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
817 target, level, internalformat, width, height, depth, border, imageSize, data);
822 case GL_TEXTURE_2D_ARRAY:
825 return error(GL_INVALID_ENUM);
828 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
830 return error(GL_INVALID_VALUE);
833 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
834 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) || (border != 0) || (imageSize < 0))
836 return error(GL_INVALID_VALUE);
839 switch(internalformat)
841 case GL_DEPTH_COMPONENT:
842 case GL_DEPTH_COMPONENT16:
843 case GL_DEPTH_COMPONENT32_OES:
844 case GL_DEPTH_STENCIL:
845 case GL_DEPTH24_STENCIL8:
846 return error(GL_INVALID_OPERATION);
849 GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
850 if(validationError != GL_NONE)
852 return error(validationError);
857 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
859 return error(GL_INVALID_VALUE);
862 es2::Context *context = es2::getContext();
866 es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
870 return error(GL_INVALID_OPERATION);
873 GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
874 if(validationError != GL_NONE)
876 return error(validationError);
879 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
883 GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
885 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
886 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
887 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
888 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
893 case GL_TEXTURE_2D_ARRAY:
896 return error(GL_INVALID_ENUM);
899 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
901 return error(GL_INVALID_VALUE);
904 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
906 return error(GL_INVALID_VALUE);
909 GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
910 if(validationError != GL_NONE)
912 return error(validationError);
915 if(width == 0 || height == 0 || depth == 0)
920 es2::Context *context = es2::getContext();
924 es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
928 return error(GL_INVALID_OPERATION);
931 GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
932 if(validationError != GL_NONE)
934 return error(validationError);
937 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
941 GL_APICALL void GL_APIENTRY glGenQueries(GLsizei n, GLuint *ids)
943 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
947 return error(GL_INVALID_VALUE);
950 es2::Context *context = es2::getContext();
954 for(int i = 0; i < n; i++)
956 ids[i] = context->createQuery();
961 GL_APICALL void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids)
963 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
967 return error(GL_INVALID_VALUE);
970 es2::Context *context = es2::getContext();
974 for(int i = 0; i < n; i++)
976 context->deleteQuery(ids[i]);
981 GL_APICALL GLboolean GL_APIENTRY glIsQuery(GLuint id)
983 TRACE("(GLuint id = %d)", id);
990 es2::Context *context = es2::getContext();
994 es2::Query *queryObject = context->getQuery(id);
1005 GL_APICALL void GL_APIENTRY glBeginQuery(GLenum target, GLuint id)
1007 TRACE("(GLenum target = 0x%X, GLuint id = %d)", target, id);
1009 if(!ValidateQueryTarget(target))
1011 return error(GL_INVALID_ENUM);
1016 return error(GL_INVALID_OPERATION);
1019 es2::Context *context = es2::getContext();
1023 context->beginQuery(target, id);
1027 GL_APICALL void GL_APIENTRY glEndQuery(GLenum target)
1029 TRACE("(GLenum target = 0x%X)", target);
1031 if(!ValidateQueryTarget(target))
1033 return error(GL_INVALID_ENUM);
1036 es2::Context *context = es2::getContext();
1040 context->endQuery(target);
1044 GL_APICALL void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params)
1046 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)",
1047 target, pname, params);
1049 if(!ValidateQueryTarget(target) || (pname != GL_CURRENT_QUERY))
1051 return error(GL_INVALID_ENUM);
1054 es2::Context *context = es2::getContext();
1058 params[0] = context->getActiveQuery(target);
1062 GL_APICALL void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1064 TRACE("(GLuint id = %d, GLenum pname = 0x%X, GLint *params = %p)",
1069 case GL_QUERY_RESULT:
1070 case GL_QUERY_RESULT_AVAILABLE:
1073 return error(GL_INVALID_ENUM);
1076 es2::Context *context = es2::getContext();
1080 es2::Query *queryObject = context->getQuery(id);
1084 return error(GL_INVALID_OPERATION);
1087 if(context->getActiveQuery(queryObject->getType()) == id)
1089 return error(GL_INVALID_OPERATION);
1094 case GL_QUERY_RESULT:
1095 params[0] = queryObject->getResult();
1097 case GL_QUERY_RESULT_AVAILABLE:
1098 params[0] = queryObject->isResultAvailable();
1106 GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer(GLenum target)
1108 TRACE("(GLenum target = 0x%X)", target);
1110 es2::Context *context = es2::getContext();
1114 es2::Buffer *buffer = nullptr;
1115 if(!context->getBuffer(target, &buffer))
1117 return error(GL_INVALID_ENUM, GL_TRUE);
1122 // A null buffer means that "0" is bound to the requested buffer target
1123 return error(GL_INVALID_OPERATION, GL_TRUE);
1126 if(!buffer->isMapped())
1129 return error(GL_INVALID_OPERATION, GL_TRUE);
1132 return buffer->unmap() ? GL_TRUE : GL_FALSE;
1138 GL_APICALL void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params)
1140 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)",
1141 target, pname, params);
1143 if(pname != GL_BUFFER_MAP_POINTER)
1145 return error(GL_INVALID_ENUM);
1148 es2::Context *context = es2::getContext();
1152 es2::Buffer *buffer = nullptr;
1153 if(!context->getBuffer(target, &buffer))
1155 return error(GL_INVALID_ENUM);
1160 // A null buffer means that "0" is bound to the requested buffer target
1161 return error(GL_INVALID_OPERATION);
1164 *params = buffer->isMapped() ? (void*)(((const char*)buffer->data()) + buffer->offset()) : nullptr;
1168 GL_APICALL void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs)
1170 TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);
1172 if(n < 0 || n > MAX_DRAW_BUFFERS)
1174 return error(GL_INVALID_VALUE);
1177 es2::Context *context = es2::getContext();
1181 GLuint drawFramebufferName = context->getDrawFramebufferName();
1183 if((drawFramebufferName == 0) && (n != 1))
1185 return error(GL_INVALID_OPERATION);
1188 for(unsigned int i = 0; i < (unsigned)n; i++)
1193 if(drawFramebufferName != 0)
1195 return error(GL_INVALID_OPERATION);
1200 case GL_COLOR_ATTACHMENT0:
1201 case GL_COLOR_ATTACHMENT1:
1202 case GL_COLOR_ATTACHMENT2:
1203 case GL_COLOR_ATTACHMENT3:
1204 case GL_COLOR_ATTACHMENT4:
1205 case GL_COLOR_ATTACHMENT5:
1206 case GL_COLOR_ATTACHMENT6:
1207 case GL_COLOR_ATTACHMENT7:
1208 case GL_COLOR_ATTACHMENT8:
1209 case GL_COLOR_ATTACHMENT9:
1210 case GL_COLOR_ATTACHMENT10:
1211 case GL_COLOR_ATTACHMENT11:
1212 case GL_COLOR_ATTACHMENT12:
1213 case GL_COLOR_ATTACHMENT13:
1214 case GL_COLOR_ATTACHMENT14:
1215 case GL_COLOR_ATTACHMENT15:
1216 case GL_COLOR_ATTACHMENT16:
1217 case GL_COLOR_ATTACHMENT17:
1218 case GL_COLOR_ATTACHMENT18:
1219 case GL_COLOR_ATTACHMENT19:
1220 case GL_COLOR_ATTACHMENT20:
1221 case GL_COLOR_ATTACHMENT21:
1222 case GL_COLOR_ATTACHMENT22:
1223 case GL_COLOR_ATTACHMENT23:
1224 case GL_COLOR_ATTACHMENT24:
1225 case GL_COLOR_ATTACHMENT25:
1226 case GL_COLOR_ATTACHMENT26:
1227 case GL_COLOR_ATTACHMENT27:
1228 case GL_COLOR_ATTACHMENT28:
1229 case GL_COLOR_ATTACHMENT29:
1230 case GL_COLOR_ATTACHMENT30:
1231 case GL_COLOR_ATTACHMENT31:
1233 GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0);
1235 if(index >= MAX_COLOR_ATTACHMENTS)
1237 return error(GL_INVALID_OPERATION);
1242 return error(GL_INVALID_OPERATION);
1245 if(drawFramebufferName == 0)
1247 return error(GL_INVALID_OPERATION);
1252 return error(GL_INVALID_ENUM);
1256 context->setFramebufferDrawBuffers(n, bufs);
1260 GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
1262 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
1266 return error(GL_INVALID_VALUE);
1274 es2::Context *context = es2::getContext();
1278 es2::Program *program = context->getCurrentProgram();
1282 return error(GL_INVALID_OPERATION);
1285 if(!program->setUniformMatrix2x3fv(location, count, transpose, value))
1287 return error(GL_INVALID_OPERATION);
1292 GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
1294 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
1298 return error(GL_INVALID_VALUE);
1306 es2::Context *context = es2::getContext();
1310 es2::Program *program = context->getCurrentProgram();
1314 return error(GL_INVALID_OPERATION);
1317 if(!program->setUniformMatrix3x2fv(location, count, transpose, value))
1319 return error(GL_INVALID_OPERATION);
1324 GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
1326 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
1330 return error(GL_INVALID_VALUE);
1338 es2::Context *context = es2::getContext();
1342 es2::Program *program = context->getCurrentProgram();
1346 return error(GL_INVALID_OPERATION);
1349 if(!program->setUniformMatrix2x4fv(location, count, transpose, value))
1351 return error(GL_INVALID_OPERATION);
1356 GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
1358 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
1362 return error(GL_INVALID_VALUE);
1370 es2::Context *context = es2::getContext();
1374 es2::Program *program = context->getCurrentProgram();
1378 return error(GL_INVALID_OPERATION);
1381 if(!program->setUniformMatrix4x2fv(location, count, transpose, value))
1383 return error(GL_INVALID_OPERATION);
1388 GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
1390 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
1394 return error(GL_INVALID_VALUE);
1402 es2::Context *context = es2::getContext();
1406 es2::Program *program = context->getCurrentProgram();
1410 return error(GL_INVALID_OPERATION);
1413 if(!program->setUniformMatrix3x4fv(location, count, transpose, value))
1415 return error(GL_INVALID_OPERATION);
1420 GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
1422 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat *value = %p)", location, count, transpose, value);
1426 return error(GL_INVALID_VALUE);
1434 es2::Context *context = es2::getContext();
1438 es2::Program *program = context->getCurrentProgram();
1442 return error(GL_INVALID_OPERATION);
1445 if(!program->setUniformMatrix4x3fv(location, count, transpose, value))
1447 return error(GL_INVALID_OPERATION);
1452 GL_APICALL void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
1454 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
1455 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
1456 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
1457 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
1465 return error(GL_INVALID_ENUM);
1468 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1470 return error(GL_INVALID_VALUE);
1473 es2::Context *context = es2::getContext();
1477 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
1479 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
1480 return error(GL_INVALID_OPERATION);
1483 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter == GL_LINEAR, true);
1487 GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
1489 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %d, GLint level = %d, GLint layer = %d)",
1490 target, attachment, texture, level, layer);
1492 // GLES 3.0.4 spec, p.209, section 4.4.2
1493 // If texture is zero, any image or array of images attached to the attachment point
1494 // named by attachment is detached. Any additional parameters(level, textarget,
1495 // and / or layer) are ignored when texture is zero.
1496 if(texture != 0 && (layer < 0 || level < 0))
1498 return error(GL_INVALID_VALUE);
1501 es2::Context *context = es2::getContext();
1505 Texture* textureObject = context->getTexture(texture);
1506 GLenum textarget = GL_NONE;
1511 return error(GL_INVALID_VALUE);
1514 textarget = textureObject->getTarget();
1518 case GL_TEXTURE_2D_ARRAY:
1519 if(layer >= es2::IMPLEMENTATION_MAX_TEXTURE_SIZE || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
1521 return error(GL_INVALID_VALUE);
1525 return error(GL_INVALID_OPERATION);
1528 if(textureObject->isCompressed(textarget, level))
1530 return error(GL_INVALID_OPERATION);
1534 es2::Framebuffer *framebuffer = nullptr;
1537 case GL_DRAW_FRAMEBUFFER:
1538 case GL_FRAMEBUFFER:
1539 framebuffer = context->getDrawFramebuffer();
1541 case GL_READ_FRAMEBUFFER:
1542 framebuffer = context->getReadFramebuffer();
1545 return error(GL_INVALID_ENUM);
1550 return error(GL_INVALID_OPERATION);
1555 case GL_COLOR_ATTACHMENT0:
1556 case GL_COLOR_ATTACHMENT1:
1557 case GL_COLOR_ATTACHMENT2:
1558 case GL_COLOR_ATTACHMENT3:
1559 case GL_COLOR_ATTACHMENT4:
1560 case GL_COLOR_ATTACHMENT5:
1561 case GL_COLOR_ATTACHMENT6:
1562 case GL_COLOR_ATTACHMENT7:
1563 case GL_COLOR_ATTACHMENT8:
1564 case GL_COLOR_ATTACHMENT9:
1565 case GL_COLOR_ATTACHMENT10:
1566 case GL_COLOR_ATTACHMENT11:
1567 case GL_COLOR_ATTACHMENT12:
1568 case GL_COLOR_ATTACHMENT13:
1569 case GL_COLOR_ATTACHMENT14:
1570 case GL_COLOR_ATTACHMENT15:
1571 case GL_COLOR_ATTACHMENT16:
1572 case GL_COLOR_ATTACHMENT17:
1573 case GL_COLOR_ATTACHMENT18:
1574 case GL_COLOR_ATTACHMENT19:
1575 case GL_COLOR_ATTACHMENT20:
1576 case GL_COLOR_ATTACHMENT21:
1577 case GL_COLOR_ATTACHMENT22:
1578 case GL_COLOR_ATTACHMENT23:
1579 case GL_COLOR_ATTACHMENT24:
1580 case GL_COLOR_ATTACHMENT25:
1581 case GL_COLOR_ATTACHMENT26:
1582 case GL_COLOR_ATTACHMENT27:
1583 case GL_COLOR_ATTACHMENT28:
1584 case GL_COLOR_ATTACHMENT29:
1585 case GL_COLOR_ATTACHMENT30:
1586 case GL_COLOR_ATTACHMENT31:
1587 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level, layer);
1589 case GL_DEPTH_ATTACHMENT:
1590 framebuffer->setDepthbuffer(textarget, texture, level, layer);
1592 case GL_STENCIL_ATTACHMENT:
1593 framebuffer->setStencilbuffer(textarget, texture, level, layer);
1595 case GL_DEPTH_STENCIL_ATTACHMENT:
1596 framebuffer->setDepthbuffer(textarget, texture, level, layer);
1597 framebuffer->setStencilbuffer(textarget, texture, level, layer);
1600 return error(GL_INVALID_ENUM);
1605 GL_APICALL void *GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
1607 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = %X)",
1608 target, offset, length, access);
1610 if((offset < 0) || (length < 0))
1612 return error(GL_INVALID_VALUE, nullptr);
1615 if(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)))
1617 // Must be able to read or write the buffer
1618 return error(GL_INVALID_OPERATION, nullptr);
1620 else if((access & GL_MAP_READ_BIT) && (access & (GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT)))
1622 // GL_MAP_INVALIDATE_RANGE_BIT, GL_MAP_INVALIDATE_BUFFER_BIT and GL_MAP_UNSYNCHRONIZED_BIT can't be used with GL_MAP_READ_BIT
1623 return error(GL_INVALID_OPERATION, nullptr);
1625 else if((!(access & GL_MAP_WRITE_BIT)) && (access & GL_MAP_FLUSH_EXPLICIT_BIT))
1627 // GL_MAP_FLUSH_EXPLICIT_BIT can't be used without GL_MAP_WRITE_BIT
1628 return error(GL_INVALID_OPERATION, nullptr);
1631 es2::Context *context = es2::getContext();
1635 es2::Buffer *buffer = nullptr;
1636 if(!context->getBuffer(target, &buffer))
1638 return error(GL_INVALID_ENUM, nullptr);
1643 // A null buffer means that "0" is bound to the requested buffer target
1644 return error(GL_INVALID_OPERATION, nullptr);
1647 if(buffer->isMapped())
1649 // It is an invalid operation to map an already mapped buffer
1650 return error(GL_INVALID_OPERATION, nullptr);
1653 GLsizeiptr bufferSize = buffer->size();
1654 if((offset + length) > bufferSize)
1656 return error(GL_INVALID_VALUE, nullptr);
1659 if((access & ~(GL_MAP_READ_BIT |
1661 GL_MAP_INVALIDATE_RANGE_BIT |
1662 GL_MAP_INVALIDATE_BUFFER_BIT |
1663 GL_MAP_FLUSH_EXPLICIT_BIT |
1664 GL_MAP_UNSYNCHRONIZED_BIT)) != 0)
1666 return error(GL_INVALID_VALUE, nullptr);
1669 return buffer->mapRange(offset, length, access);
1675 GL_APICALL void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
1677 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)",
1678 target, offset, length);
1680 if((offset < 0) || (length < 0))
1682 return error(GL_INVALID_VALUE);
1685 es2::Context *context = es2::getContext();
1689 es2::Buffer *buffer = nullptr;
1690 if(!context->getBuffer(target, &buffer))
1692 return error(GL_INVALID_ENUM);
1697 // A null buffer means that "0" is bound to the requested buffer target
1698 return error(GL_INVALID_OPERATION);
1701 if(!buffer->isMapped())
1703 // Buffer must be mapped
1704 return error(GL_INVALID_OPERATION);
1707 GLsizeiptr bufferSize = buffer->length();
1708 if((offset + length) > bufferSize)
1710 return error(GL_INVALID_VALUE);
1713 if(!(buffer->usage() & GL_MAP_FLUSH_EXPLICIT_BIT))
1715 // Flush must be explicitly allowed
1716 return error(GL_INVALID_OPERATION);
1719 buffer->flushMappedRange(offset, length);
1723 GL_APICALL void GL_APIENTRY glBindVertexArray(GLuint array)
1725 TRACE("(GLuint array = %d)", array);
1727 es2::Context *context = es2::getContext();
1731 if(!context->isVertexArray(array))
1733 return error(GL_INVALID_OPERATION);
1736 context->bindVertexArray(array);
1740 GL_APICALL void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint *arrays)
1742 TRACE("(GLsizei n = %d, const GLuint *arrays = %p)", n, arrays);
1746 return error(GL_INVALID_VALUE);
1749 es2::Context *context = es2::getContext();
1753 for(int i = 0; i < n; i++)
1755 context->deleteVertexArray(arrays[i]);
1760 GL_APICALL void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint *arrays)
1762 TRACE("(GLsizei n = %d, const GLuint *arrays = %p)", n, arrays);
1766 return error(GL_INVALID_VALUE);
1769 es2::Context *context = es2::getContext();
1773 for(int i = 0; i < n; i++)
1775 arrays[i] = context->createVertexArray();
1780 GL_APICALL GLboolean GL_APIENTRY glIsVertexArray(GLuint array)
1782 TRACE("(GLuint array = %d)", array);
1789 es2::Context *context = es2::getContext();
1793 es2::VertexArray *arrayObject = context->getVertexArray(array);
1804 GL_APICALL void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint *data)
1806 TRACE("(GLenum target = 0x%X, GLuint index = %d, GLint* data = %p)",
1807 target, index, data);
1809 es2::Context *context = es2::getContext();
1813 if(!context->getTransformFeedbackiv(index, target, data) &&
1814 !context->getUniformBufferiv(index, target, data) &&
1815 !context->getIntegerv(target, data))
1818 unsigned int numParams = 0;
1819 if(!context->getQueryParameterInfo(target, &nativeType, &numParams))
1820 return error(GL_INVALID_ENUM);
1823 return; // it is known that target is valid, but there are no parameters to return
1825 if(nativeType == GL_BOOL)
1827 GLboolean *boolParams = nullptr;
1828 boolParams = new GLboolean[numParams];
1830 context->getBooleanv(target, boolParams);
1832 for(unsigned int i = 0; i < numParams; ++i)
1834 data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
1837 delete[] boolParams;
1839 else if(nativeType == GL_FLOAT)
1841 GLfloat *floatParams = nullptr;
1842 floatParams = new GLfloat[numParams];
1844 context->getFloatv(target, floatParams);
1846 for(unsigned int i = 0; i < numParams; ++i)
1848 if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)
1850 data[i] = convert_float_int(floatParams[i]);
1854 data[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
1858 delete[] floatParams;
1864 GL_APICALL void GL_APIENTRY glBeginTransformFeedback(GLenum primitiveMode)
1866 TRACE("(GLenum primitiveMode = 0x%X)", primitiveMode);
1868 switch(primitiveMode)
1875 return error(GL_INVALID_ENUM);
1878 es2::Context *context = es2::getContext();
1882 es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
1884 if(transformFeedbackObject)
1886 if(transformFeedbackObject->isActive())
1888 return error(GL_INVALID_OPERATION);
1890 transformFeedbackObject->begin(primitiveMode);
1894 return error(GL_INVALID_OPERATION);
1899 GL_APICALL void GL_APIENTRY glEndTransformFeedback(void)
1903 es2::Context *context = es2::getContext();
1907 es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
1909 if(transformFeedbackObject)
1911 if(!transformFeedbackObject->isActive())
1913 return error(GL_INVALID_OPERATION);
1915 transformFeedbackObject->end();
1919 return error(GL_INVALID_OPERATION);
1924 GL_APICALL void GL_APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
1926 TRACE("(GLenum target = 0x%X, GLuint index = %d, GLuint buffer = %d, GLintptr offset = %d, GLsizeiptr size = %d)",
1927 target, index, buffer, offset, size);
1929 if(buffer != 0 && size <= 0)
1931 return error(GL_INVALID_VALUE);
1934 es2::Context *context = es2::getContext();
1940 case GL_TRANSFORM_FEEDBACK_BUFFER:
1941 if(index >= MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
1943 return error(GL_INVALID_VALUE);
1945 if(size & 0x3 || offset & 0x3) // size and offset must be multiples of 4
1947 return error(GL_INVALID_VALUE);
1949 context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
1950 context->bindGenericTransformFeedbackBuffer(buffer);
1952 case GL_UNIFORM_BUFFER:
1953 if(index >= MAX_UNIFORM_BUFFER_BINDINGS)
1955 return error(GL_INVALID_VALUE);
1957 if(offset % UNIFORM_BUFFER_OFFSET_ALIGNMENT != 0)
1959 return error(GL_INVALID_VALUE);
1961 context->bindIndexedUniformBuffer(buffer, index, offset, size);
1962 context->bindGenericUniformBuffer(buffer);
1965 return error(GL_INVALID_ENUM);
1970 GL_APICALL void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
1972 TRACE("(GLenum target = 0x%X, GLuint index = %d, GLuint buffer = %d)",
1973 target, index, buffer);
1975 es2::Context *context = es2::getContext();
1981 case GL_TRANSFORM_FEEDBACK_BUFFER:
1982 if(index >= MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
1984 return error(GL_INVALID_VALUE);
1986 context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
1987 context->bindGenericTransformFeedbackBuffer(buffer);
1989 case GL_UNIFORM_BUFFER:
1990 if(index >= MAX_UNIFORM_BUFFER_BINDINGS)
1992 return error(GL_INVALID_VALUE);
1994 context->bindIndexedUniformBuffer(buffer, index, 0, 0);
1995 context->bindGenericUniformBuffer(buffer);
1998 return error(GL_INVALID_ENUM);
2003 GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode)
2005 TRACE("(GLuint program = %d, GLsizei count = %d, const GLchar *const*varyings = %p, GLenum bufferMode = 0x%X)",
2006 program, count, varyings, bufferMode);
2010 case GL_SEPARATE_ATTRIBS:
2011 if(count > MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
2013 return error(GL_INVALID_VALUE);
2015 case GL_INTERLEAVED_ATTRIBS:
2018 return error(GL_INVALID_ENUM);
2021 es2::Context *context = es2::getContext();
2025 es2::Program *programObject = context->getProgram(program);
2029 return error(GL_INVALID_VALUE);
2032 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
2036 GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name)
2038 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLsizei *size = %p, GLenum *type = %p, GLchar *name = %p)",
2039 program, index, bufSize, length, size, type, name);
2043 return error(GL_INVALID_VALUE);
2046 es2::Context *context = es2::getContext();
2050 es2::Program *programObject = context->getProgram(program);
2054 return error(GL_INVALID_VALUE);
2057 if(index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
2059 return error(GL_INVALID_VALUE);
2062 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
2066 GL_APICALL void GL_APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
2068 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLsizei *size = %p, GLenum *type = %p, GLchar *name = %p)",
2069 index, size, type, stride, pointer);
2071 if(index >= es2::MAX_VERTEX_ATTRIBS)
2073 return error(GL_INVALID_VALUE);
2076 if(size < 1 || size > 4 || stride < 0)
2078 return error(GL_INVALID_VALUE);
2084 case GL_UNSIGNED_BYTE:
2086 case GL_UNSIGNED_SHORT:
2088 case GL_UNSIGNED_INT:
2091 return error(GL_INVALID_ENUM);
2094 es2::Context *context = es2::getContext();
2098 es2::VertexArray* vertexArray = context->getCurrentVertexArray();
2099 if((context->getArrayBufferName() == 0) && vertexArray && (vertexArray->name != 0) && pointer)
2101 // GL_INVALID_OPERATION is generated if a non-zero vertex array object is bound, zero is bound
2102 // to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.
2103 return error(GL_INVALID_OPERATION);
2106 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, false, stride, pointer);
2110 GL_APICALL void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
2112 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint *params = %p)",
2113 index, pname, params);
2115 es2::Context *context = es2::getContext();
2119 if(index >= es2::MAX_VERTEX_ATTRIBS)
2121 return error(GL_INVALID_VALUE);
2124 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
2128 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2129 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
2131 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2132 *params = attribState.mSize;
2134 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2135 *params = attribState.mStride;
2137 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2138 *params = attribState.mType;
2140 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2141 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
2143 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2144 *params = attribState.mBoundBuffer.name();
2146 case GL_CURRENT_VERTEX_ATTRIB:
2148 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
2149 for(int i = 0; i < 4; ++i)
2151 params[i] = attrib.getCurrentValueI(i);
2155 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
2156 switch(attribState.mType)
2159 case GL_UNSIGNED_BYTE:
2161 case GL_UNSIGNED_SHORT:
2163 case GL_INT_2_10_10_10_REV:
2164 case GL_UNSIGNED_INT:
2173 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
2174 *params = attribState.mDivisor;
2176 default: return error(GL_INVALID_ENUM);
2181 GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
2183 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLuint *params = %p)",
2184 index, pname, params);
2186 es2::Context *context = es2::getContext();
2190 if(index >= es2::MAX_VERTEX_ATTRIBS)
2192 return error(GL_INVALID_VALUE);
2195 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
2199 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2200 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
2202 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2203 *params = attribState.mSize;
2205 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2206 *params = attribState.mStride;
2208 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2209 *params = attribState.mType;
2211 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2212 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
2214 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2215 *params = attribState.mBoundBuffer.name();
2217 case GL_CURRENT_VERTEX_ATTRIB:
2219 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
2220 for(int i = 0; i < 4; ++i)
2222 params[i] = attrib.getCurrentValueUI(i);
2226 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
2227 switch(attribState.mType)
2230 case GL_UNSIGNED_BYTE:
2232 case GL_UNSIGNED_SHORT:
2234 case GL_INT_2_10_10_10_REV:
2235 case GL_UNSIGNED_INT:
2244 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
2245 *params = attribState.mDivisor;
2247 default: return error(GL_INVALID_ENUM);
2252 GL_APICALL void GL_APIENTRY glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
2254 TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
2257 if(index >= es2::MAX_VERTEX_ATTRIBS)
2259 return error(GL_INVALID_VALUE);
2262 es2::Context *context = es2::getContext();
2266 GLint vals[4] = { x, y, z, w };
2267 context->setVertexAttrib(index, vals);
2271 GL_APICALL void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
2273 TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
2276 if(index >= es2::MAX_VERTEX_ATTRIBS)
2278 return error(GL_INVALID_VALUE);
2281 es2::Context *context = es2::getContext();
2285 GLuint vals[4] = { x, y, z, w };
2286 context->setVertexAttrib(index, vals);
2290 GL_APICALL void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint *v)
2292 TRACE("(GLuint index = %d, GLint *v = %p)", index, v);
2294 if(index >= es2::MAX_VERTEX_ATTRIBS)
2296 return error(GL_INVALID_VALUE);
2299 es2::Context *context = es2::getContext();
2303 context->setVertexAttrib(index, v);
2307 GL_APICALL void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint *v)
2309 TRACE("(GLuint index = %d, GLint *v = %p)", index, v);
2311 if(index >= es2::MAX_VERTEX_ATTRIBS)
2313 return error(GL_INVALID_VALUE);
2316 es2::Context *context = es2::getContext();
2320 context->setVertexAttrib(index, v);
2324 GL_APICALL void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint *params)
2326 TRACE("(GLuint program = %d, GLint location = %d, GLuint *params = %p)",
2327 program, location, params);
2329 es2::Context *context = es2::getContext();
2335 return error(GL_INVALID_VALUE);
2338 es2::Program *programObject = context->getProgram(program);
2340 if(!programObject || !programObject->isLinked())
2342 return error(GL_INVALID_OPERATION);
2347 return error(GL_INVALID_OPERATION);
2350 if(!programObject->getUniformuiv(location, nullptr, params))
2352 return error(GL_INVALID_OPERATION);
2357 GL_APICALL GLint GL_APIENTRY glGetFragDataLocation(GLuint program, const GLchar *name)
2359 TRACE("(GLuint program = %d, const GLchar *name = %p)", program, name);
2361 es2::Context *context = es2::getContext();
2365 es2::Program *programObject = context->getProgram(program);
2369 if(context->getShader(program))
2371 return error(GL_INVALID_OPERATION, -1);
2375 return error(GL_INVALID_VALUE, -1);
2379 if(!programObject->isLinked())
2381 return error(GL_INVALID_OPERATION, -1);
2384 return programObject->getFragDataLocation(name);
2390 GL_APICALL void GL_APIENTRY glUniform1ui(GLint location, GLuint v0)
2392 glUniform1uiv(location, 1, &v0);
2395 GL_APICALL void GL_APIENTRY glUniform2ui(GLint location, GLuint v0, GLuint v1)
2397 GLuint xy[2] = { v0, v1 };
2399 glUniform2uiv(location, 1, (GLuint*)&xy);
2402 GL_APICALL void GL_APIENTRY glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
2404 GLuint xyz[3] = { v0, v1, v2 };
2406 glUniform3uiv(location, 1, (GLuint*)&xyz);
2409 GL_APICALL void GL_APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
2411 GLuint xyzw[4] = { v0, v1, v2, v3 };
2413 glUniform4uiv(location, 1, (GLuint*)&xyzw);
2416 GL_APICALL void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint *value)
2418 TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",
2419 location, count, value);
2423 return error(GL_INVALID_VALUE);
2431 es2::Context *context = es2::getContext();
2435 es2::Program *program = context->getCurrentProgram();
2439 return error(GL_INVALID_OPERATION);
2442 if(!program->setUniform1uiv(location, count, value))
2444 return error(GL_INVALID_OPERATION);
2449 GL_APICALL void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint *value)
2451 TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",
2452 location, count, value);
2456 return error(GL_INVALID_VALUE);
2464 es2::Context *context = es2::getContext();
2468 es2::Program *program = context->getCurrentProgram();
2472 return error(GL_INVALID_OPERATION);
2475 if(!program->setUniform2uiv(location, count, value))
2477 return error(GL_INVALID_OPERATION);
2482 GL_APICALL void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint *value)
2484 TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",
2485 location, count, value);
2489 return error(GL_INVALID_VALUE);
2497 es2::Context *context = es2::getContext();
2501 es2::Program *program = context->getCurrentProgram();
2505 return error(GL_INVALID_OPERATION);
2508 if(!program->setUniform3uiv(location, count, value))
2510 return error(GL_INVALID_OPERATION);
2515 GL_APICALL void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint *value)
2517 TRACE("(GLint location = %d, GLsizei count = %d, const GLuint *value = %p)",
2518 location, count, value);
2522 return error(GL_INVALID_VALUE);
2530 es2::Context *context = es2::getContext();
2534 es2::Program *program = context->getCurrentProgram();
2538 return error(GL_INVALID_OPERATION);
2541 if(!program->setUniform4uiv(location, count, value))
2543 return error(GL_INVALID_OPERATION);
2548 GL_APICALL void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
2550 TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint *value = %p)",
2551 buffer, drawbuffer, value);
2553 es2::Context *context = es2::getContext();
2560 if(drawbuffer < 0 || drawbuffer >= MAX_DRAW_BUFFERS)
2562 return error(GL_INVALID_VALUE);
2566 context->clearColorBuffer(drawbuffer, value);
2572 return error(GL_INVALID_VALUE);
2576 context->clearStencilBuffer(value[0]);
2580 return error(GL_INVALID_ENUM);
2585 GL_APICALL void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
2587 TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint *value = %p)",
2588 buffer, drawbuffer, value);
2590 es2::Context *context = es2::getContext();
2597 if(drawbuffer < 0 || drawbuffer >= MAX_DRAW_BUFFERS)
2599 return error(GL_INVALID_VALUE);
2603 context->clearColorBuffer(drawbuffer, value);
2607 return error(GL_INVALID_ENUM);
2612 GL_APICALL void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
2614 TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat *value = %p)",
2615 buffer, drawbuffer, value);
2617 es2::Context *context = es2::getContext();
2624 if(drawbuffer < 0 || drawbuffer >= MAX_DRAW_BUFFERS)
2626 return error(GL_INVALID_VALUE);
2630 context->clearColorBuffer(drawbuffer, value);
2636 return error(GL_INVALID_VALUE);
2640 context->clearDepthBuffer(value[0]);
2644 return error(GL_INVALID_ENUM);
2649 GL_APICALL void GL_APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2651 TRACE("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth = %f, GLint stencil = %d)",
2652 buffer, drawbuffer, depth, stencil);
2654 es2::Context *context = es2::getContext();
2660 case GL_DEPTH_STENCIL:
2663 return error(GL_INVALID_VALUE);
2667 context->clearDepthBuffer(depth);
2668 context->clearStencilBuffer(stencil);
2672 return error(GL_INVALID_ENUM);
2677 GL_APICALL const GLubyte *GL_APIENTRY glGetStringi(GLenum name, GLuint index)
2679 TRACE("(GLenum name = 0x%X, GLuint index = %d)", name, index);
2681 es2::Context *context = es2::getContext();
2684 GLuint numExtensions;
2685 context->getExtensions(0, &numExtensions);
2687 if(index >= numExtensions)
2689 return error(GL_INVALID_VALUE, (GLubyte*)nullptr);
2695 return context->getExtensions(index);
2697 return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
2701 return (GLubyte*)nullptr;
2704 GL_APICALL void GL_APIENTRY glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
2706 TRACE("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)",
2707 readTarget, writeTarget, readOffset, writeOffset, size);
2709 if(readOffset < 0 || writeOffset < 0 || size < 0)
2711 return error(GL_INVALID_VALUE);
2714 es2::Context *context = es2::getContext();
2718 es2::Buffer *readBuffer = nullptr, *writeBuffer = nullptr;
2719 if(!context->getBuffer(readTarget, &readBuffer) || !context->getBuffer(writeTarget, &writeBuffer))
2721 return error(GL_INVALID_ENUM);
2723 if(!readBuffer || readBuffer->isMapped() || !writeBuffer || writeBuffer->isMapped())
2725 return error(GL_INVALID_OPERATION);
2727 if(readBuffer == writeBuffer)
2729 // If same buffer, check for overlap
2730 if(((readOffset >= writeOffset) && (readOffset < (writeOffset + size))) ||
2731 ((writeOffset >= readOffset) && (writeOffset < (readOffset + size))))
2733 return error(GL_INVALID_VALUE);
2737 if((static_cast<size_t>(readOffset + size) > readBuffer->size()) ||
2738 (static_cast<size_t>(writeOffset + size) > writeBuffer->size()))
2740 return error(GL_INVALID_VALUE);
2743 writeBuffer->bufferSubData(((char*)readBuffer->data()) + readOffset, size, writeOffset);
2747 GL_APICALL void GL_APIENTRY glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices)
2749 TRACE("(GLuint program = %d, GLsizei uniformCount = %d, const GLchar *const*uniformNames = %p, GLuint *uniformIndices = %p)",
2750 program, uniformCount, uniformNames, uniformIndices);
2752 if(uniformCount < 0)
2754 return error(GL_INVALID_VALUE);
2757 es2::Context *context = es2::getContext();
2761 es2::Program *programObject = context->getProgram(program);
2765 return error(GL_INVALID_OPERATION);
2768 if(!programObject->isLinked())
2770 for(int uniformId = 0; uniformId < uniformCount; uniformId++)
2772 uniformIndices[uniformId] = GL_INVALID_INDEX;
2777 for(int uniformId = 0; uniformId < uniformCount; uniformId++)
2779 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
2785 GL_APICALL void GL_APIENTRY glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params)
2787 TRACE("(GLuint program = %d, GLsizei uniformCount = %d, const GLchar *const*uniformNames = %p, GLenum pname = 0x%X, GLuint *uniformIndices = %p)",
2788 program, uniformCount, uniformIndices, pname, uniformIndices);
2792 case GL_UNIFORM_TYPE:
2793 case GL_UNIFORM_SIZE:
2794 case GL_UNIFORM_NAME_LENGTH:
2795 case GL_UNIFORM_BLOCK_INDEX:
2796 case GL_UNIFORM_OFFSET:
2797 case GL_UNIFORM_ARRAY_STRIDE:
2798 case GL_UNIFORM_MATRIX_STRIDE:
2799 case GL_UNIFORM_IS_ROW_MAJOR:
2802 return error(GL_INVALID_ENUM);
2805 if(uniformCount < 0)
2807 return error(GL_INVALID_VALUE);
2810 es2::Context *context = es2::getContext();
2814 es2::Program *programObject = context->getProgram(program);
2818 return error(GL_INVALID_OPERATION);
2821 for(int uniformId = 0; uniformId < uniformCount; uniformId++)
2823 const GLuint index = uniformIndices[uniformId];
2825 if(index >= programObject->getActiveUniformCount())
2827 return error(GL_INVALID_VALUE);
2831 for(int uniformId = 0; uniformId < uniformCount; uniformId++)
2833 const GLuint index = uniformIndices[uniformId];
2834 params[uniformId] = programObject->getActiveUniformi(index, pname);
2839 GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
2841 TRACE("(GLuint program = %d, const GLchar *uniformBlockName = %p)",
2842 program, uniformBlockName);
2844 es2::Context *context = es2::getContext();
2848 es2::Program *programObject = context->getProgram(program);
2852 return error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
2855 return programObject->getUniformBlockIndex(uniformBlockName);
2858 return GL_INVALID_INDEX;
2861 GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params)
2863 TRACE("(GLuint program = %d, GLuint uniformBlockIndex = %d, GLenum pname = 0x%X, GLint *params = %p)",
2864 program, uniformBlockIndex, pname, params);
2866 es2::Context *context = es2::getContext();
2870 es2::Program *programObject = context->getProgram(program);
2874 return error(GL_INVALID_OPERATION);
2879 case GL_UNIFORM_BLOCK_BINDING:
2880 *params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex));
2882 case GL_UNIFORM_BLOCK_DATA_SIZE:
2883 case GL_UNIFORM_BLOCK_NAME_LENGTH:
2884 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
2885 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
2886 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
2887 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
2888 programObject->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
2891 return error(GL_INVALID_ENUM);
2896 GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName)
2898 TRACE("(GLuint program = %d, GLuint uniformBlockIndex = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLchar *uniformBlockName = %p)",
2899 program, uniformBlockIndex, bufSize, length, uniformBlockName);
2903 return error(GL_INVALID_VALUE);
2906 es2::Context *context = es2::getContext();
2910 es2::Program *programObject = context->getProgram(program);
2914 return error(GL_INVALID_OPERATION);
2917 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
2921 GL_APICALL void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
2923 TRACE("(GLuint program = %d, GLuint uniformBlockIndex = %d, GLuint uniformBlockBinding = %d)",
2924 program, uniformBlockIndex, uniformBlockBinding);
2926 if(uniformBlockBinding >= MAX_UNIFORM_BUFFER_BINDINGS)
2928 return error(GL_INVALID_VALUE);
2931 es2::Context *context = es2::getContext();
2935 es2::Program *programObject = context->getProgram(program);
2939 return error(GL_INVALID_VALUE);
2942 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
2946 GL_APICALL void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
2948 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
2949 mode, first, count, instanceCount);
2958 case GL_TRIANGLE_FAN:
2959 case GL_TRIANGLE_STRIP:
2962 return error(GL_INVALID_ENUM);
2965 if(count < 0 || instanceCount < 0)
2967 return error(GL_INVALID_VALUE);
2970 es2::Context *context = es2::getContext();
2974 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
2975 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
2977 return error(GL_INVALID_OPERATION);
2980 context->drawArrays(mode, first, count, instanceCount);
2984 GL_APICALL void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
2986 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
2987 mode, count, type, indices, instanceCount);
2996 case GL_TRIANGLE_FAN:
2997 case GL_TRIANGLE_STRIP:
3000 return error(GL_INVALID_ENUM);
3005 case GL_UNSIGNED_BYTE:
3006 case GL_UNSIGNED_SHORT:
3007 case GL_UNSIGNED_INT:
3010 return error(GL_INVALID_ENUM);
3013 if(count < 0 || instanceCount < 0)
3015 return error(GL_INVALID_VALUE);
3018 es2::Context *context = es2::getContext();
3022 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
3023 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
3025 return error(GL_INVALID_OPERATION);
3028 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
3032 GL_APICALL GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)
3034 TRACE("(GLenum condition = 0x%X, GLbitfield flags = %X)", condition, flags);
3038 case GL_SYNC_GPU_COMMANDS_COMPLETE:
3041 return error(GL_INVALID_ENUM, nullptr);
3046 return error(GL_INVALID_VALUE, nullptr);
3049 es2::Context *context = es2::getContext();
3053 return context->createFenceSync(condition, flags);
3059 GL_APICALL GLboolean GL_APIENTRY glIsSync(GLsync sync)
3061 TRACE("(GLsync sync = %p)", sync);
3063 es2::Context *context = es2::getContext();
3067 es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
3078 GL_APICALL void GL_APIENTRY glDeleteSync(GLsync sync)
3080 TRACE("(GLsync sync = %p)", sync);
3087 es2::Context *context = es2::getContext();
3091 if(!context->getFenceSync(sync))
3093 return error(GL_INVALID_VALUE);
3096 context->deleteFenceSync(sync);
3100 GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
3102 TRACE("(GLsync sync = %p, GLbitfield flags = %X, GLuint64 timeout = %llu)", sync, flags, timeout);
3104 if((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
3106 return error(GL_INVALID_VALUE, GL_FALSE);
3109 es2::Context *context = es2::getContext();
3113 es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
3117 return fenceSyncObject->clientWait(flags, timeout);
3121 return error(GL_INVALID_VALUE, GL_FALSE);
3128 GL_APICALL void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
3130 TRACE("(GLsync sync = %p, GLbitfield flags = %X, GLuint64 timeout = %llu)", sync, flags, timeout);
3134 return error(GL_INVALID_VALUE);
3137 if(timeout != GL_TIMEOUT_IGNORED)
3139 return error(GL_INVALID_VALUE);
3142 es2::Context *context = es2::getContext();
3146 es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
3150 fenceSyncObject->serverWait(flags, timeout);
3154 return error(GL_INVALID_VALUE);
3159 GL_APICALL void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64 *data)
3161 TRACE("(GLenum pname = 0x%X, GLint64 *data = %p)", pname, data);
3163 es2::Context *context = es2::getContext();
3167 if(!(context->getIntegerv(pname, data)))
3170 unsigned int numParams = 0;
3171 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3172 return error(GL_INVALID_ENUM);
3175 return; // it is known that pname is valid, but there are no parameters to return
3177 if(nativeType == GL_BOOL)
3179 GLboolean *boolParams = nullptr;
3180 boolParams = new GLboolean[numParams];
3182 context->getBooleanv(pname, boolParams);
3184 for(unsigned int i = 0; i < numParams; ++i)
3186 data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
3189 delete[] boolParams;
3191 else if(nativeType == GL_FLOAT)
3193 GLfloat *floatParams = nullptr;
3194 floatParams = new GLfloat[numParams];
3196 context->getFloatv(pname, floatParams);
3198 for(unsigned int i = 0; i < numParams; ++i)
3200 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3202 data[i] = (GLint64)(convert_float_int(floatParams[i]));
3206 data[i] = (GLint64)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3210 delete[] floatParams;
3216 GL_APICALL void GL_APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
3218 TRACE("(GLsync sync = %p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei *length = %p, GLint *values = %p)",
3219 sync, pname, bufSize, length, values);
3223 return error(GL_INVALID_VALUE);
3226 es2::Context *context = es2::getContext();
3230 es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);
3231 if(!fenceSyncObject)
3233 return error(GL_INVALID_VALUE);
3236 fenceSyncObject->getSynciv(pname, length, values);
3240 GL_APICALL void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data)
3242 TRACE("(GLenum target = 0x%X, GLuint index = %d, GLint64 *data = %p)", target, index, data);
3244 es2::Context *context = es2::getContext();
3248 if(!context->getTransformFeedbackiv(index, target, data) &&
3249 !context->getUniformBufferiv(index, target, data) &&
3250 !context->getIntegerv(target, data))
3253 unsigned int numParams = 0;
3254 if(!context->getQueryParameterInfo(target, &nativeType, &numParams))
3255 return error(GL_INVALID_ENUM);
3258 return; // it is known that target is valid, but there are no parameters to return
3260 if(nativeType == GL_BOOL)
3262 GLboolean *boolParams = nullptr;
3263 boolParams = new GLboolean[numParams];
3265 context->getBooleanv(target, boolParams);
3267 for(unsigned int i = 0; i < numParams; ++i)
3269 data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
3272 delete[] boolParams;
3274 else if(nativeType == GL_FLOAT)
3276 GLfloat *floatParams = nullptr;
3277 floatParams = new GLfloat[numParams];
3279 context->getFloatv(target, floatParams);
3281 for(unsigned int i = 0; i < numParams; ++i)
3283 if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)
3285 data[i] = (GLint64)(convert_float_int(floatParams[i]));
3289 data[i] = (GLint64)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3293 delete[] floatParams;
3299 GL_APICALL void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
3301 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64 *params = %p)", target, pname, params);
3303 es2::Context *context = es2::getContext();
3307 es2::Buffer *buffer = nullptr;
3309 if(!context->getBuffer(target, &buffer))
3311 return error(GL_INVALID_ENUM);
3316 // A null buffer means that "0" is bound to the requested buffer target
3317 return error(GL_INVALID_OPERATION);
3322 case GL_BUFFER_USAGE:
3323 *params = buffer->usage();
3325 case GL_BUFFER_SIZE:
3326 *params = buffer->size();
3328 case GL_BUFFER_ACCESS_FLAGS:
3329 *params = buffer->access();
3331 case GL_BUFFER_MAPPED:
3332 *params = buffer->isMapped();
3334 case GL_BUFFER_MAP_LENGTH:
3335 *params = buffer->length();
3337 case GL_BUFFER_MAP_OFFSET:
3338 *params = buffer->offset();
3341 return error(GL_INVALID_ENUM);
3346 GL_APICALL void GL_APIENTRY glGenSamplers(GLsizei count, GLuint *samplers)
3348 TRACE("(GLsizei count = %d, GLuint *samplers = %p)", count, samplers);
3352 return error(GL_INVALID_VALUE);
3355 es2::Context *context = es2::getContext();
3359 for(int i = 0; i < count; i++)
3361 samplers[i] = context->createSampler();
3366 GL_APICALL void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint *samplers)
3368 TRACE("(GLsizei count = %d, GLuint *samplers = %p)", count, samplers);
3372 return error(GL_INVALID_VALUE);
3375 es2::Context *context = es2::getContext();
3379 for(int i = 0; i < count; i++)
3381 context->deleteSampler(samplers[i]);
3386 GL_APICALL GLboolean GL_APIENTRY glIsSampler(GLuint sampler)
3388 TRACE("(GLuint sampler = %d)", sampler);
3395 es2::Context *context = es2::getContext();
3399 if(context->isSampler(sampler))
3408 GL_APICALL void GL_APIENTRY glBindSampler(GLuint unit, GLuint sampler)
3410 TRACE("(GLuint unit = %d, GLuint sampler = %d)", unit, sampler);
3412 if(unit >= es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS)
3414 return error(GL_INVALID_VALUE);
3417 es2::Context *context = es2::getContext();
3421 if(sampler != 0 && !context->isSampler(sampler))
3423 return error(GL_INVALID_OPERATION);
3426 context->bindSampler(unit, sampler);
3430 GL_APICALL void GL_APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
3432 TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLint param = %d)",
3433 sampler, pname, param);
3435 glSamplerParameteriv(sampler, pname, ¶m);
3438 GL_APICALL void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
3440 TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, const GLint *param = %p)",
3441 sampler, pname, param);
3443 if(!ValidateSamplerObjectParameter(pname))
3445 return error(GL_INVALID_ENUM);
3448 if(!ValidateTexParamParameters(pname, *param))
3453 es2::Context *context = es2::getContext();
3457 if(!context->isSampler(sampler))
3459 return error(GL_INVALID_OPERATION);
3462 context->samplerParameteri(sampler, pname, *param);
3466 GL_APICALL void GL_APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
3468 TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLfloat param = %f)",
3469 sampler, pname, param);
3471 glSamplerParameterfv(sampler, pname, ¶m);
3474 GL_APICALL void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
3476 TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, const GLfloat *param = %p)",
3477 sampler, pname, param);
3479 if(!ValidateSamplerObjectParameter(pname))
3481 return error(GL_INVALID_ENUM);
3484 if(!ValidateTexParamParameters(pname, static_cast<GLint>(roundf(*param))))
3489 es2::Context *context = es2::getContext();
3493 if(!context->isSampler(sampler))
3495 return error(GL_INVALID_OPERATION);
3498 context->samplerParameterf(sampler, pname, *param);
3502 GL_APICALL void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
3504 TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLint *params = %p)",
3505 sampler, pname, params);
3507 if(!ValidateSamplerObjectParameter(pname))
3509 return error(GL_INVALID_ENUM);
3512 es2::Context *context = es2::getContext();
3516 if(!context->isSampler(sampler))
3518 return error(GL_INVALID_VALUE);
3521 *params = context->getSamplerParameteri(sampler, pname);
3525 GL_APICALL void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
3527 TRACE("(GLuint sampler = %d, GLenum pname = 0x%X, GLfloat *params = %p)",
3528 sampler, pname, params);
3530 if(!ValidateSamplerObjectParameter(pname))
3532 return error(GL_INVALID_ENUM);
3535 es2::Context *context = es2::getContext();
3539 if(!context->isSampler(sampler))
3541 return error(GL_INVALID_VALUE);
3544 *params = context->getSamplerParameterf(sampler, pname);
3548 GL_APICALL void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)
3550 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
3552 es2::Context *context = es2::getContext();
3556 if(index >= es2::MAX_VERTEX_ATTRIBS)
3558 return error(GL_INVALID_VALUE);
3561 context->setVertexAttribDivisor(index, divisor);
3565 GL_APICALL void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id)
3567 TRACE("(GLenum target = 0x%X, GLuint id = %d)", target, id);
3569 if(target != GL_TRANSFORM_FEEDBACK)
3571 return error(GL_INVALID_ENUM);
3574 es2::Context *context = es2::getContext();
3578 es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
3580 if(transformFeedbackObject && transformFeedbackObject->isActive() && !transformFeedbackObject->isPaused())
3582 return error(GL_INVALID_OPERATION);
3585 if(!context->isTransformFeedback(id))
3587 return error(GL_INVALID_OPERATION);
3590 context->bindTransformFeedback(id);
3594 GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids)
3596 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
3600 return error(GL_INVALID_VALUE);
3603 es2::Context *context = es2::getContext();
3607 for(int i = 0; i < n; i++)
3611 es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback(ids[i]);
3613 if(transformFeedbackObject && transformFeedbackObject->isActive())
3615 return error(GL_INVALID_OPERATION);
3618 context->deleteTransformFeedback(ids[i]);
3624 GL_APICALL void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint *ids)
3626 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
3630 return error(GL_INVALID_VALUE);
3633 es2::Context *context = es2::getContext();
3637 for(int i = 0; i < n; i++)
3639 ids[i] = context->createTransformFeedback();
3644 GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback(GLuint id)
3646 TRACE("(GLuint id = %d)", id);
3653 es2::Context *context = es2::getContext();
3657 es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback(id);
3659 if(transformFeedbackObject)
3668 GL_APICALL void GL_APIENTRY glPauseTransformFeedback(void)
3672 es2::Context *context = es2::getContext();
3676 es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
3678 if(transformFeedbackObject)
3680 if(!transformFeedbackObject->isActive() || transformFeedbackObject->isPaused())
3682 return error(GL_INVALID_OPERATION);
3684 transformFeedbackObject->setPaused(true);
3689 GL_APICALL void GL_APIENTRY glResumeTransformFeedback(void)
3693 es2::Context *context = es2::getContext();
3697 es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback();
3699 if(transformFeedbackObject)
3701 if(!transformFeedbackObject->isActive() || !transformFeedbackObject->isPaused())
3703 return error(GL_INVALID_OPERATION);
3705 transformFeedbackObject->setPaused(false);
3710 GL_APICALL void GL_APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)
3712 TRACE("(GLuint program = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLenum *binaryFormat = %p, void *binary = %p)",
3713 program, bufSize, length, binaryFormat, binary);
3717 return error(GL_INVALID_VALUE);
3723 GL_APICALL void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
3725 TRACE("(GLuint program = %d, GLenum binaryFormat = 0x%X, const void *binary = %p, GLsizei length = %d)",
3726 program, binaryFormat, binaryFormat, length);
3730 return error(GL_INVALID_VALUE);
3736 GL_APICALL void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value)
3738 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint value = %d)",
3739 program, pname, value);
3741 es2::Context *context = es2::getContext();
3745 es2::Program *programObject = context->getProgram(program);
3749 return error(GL_INVALID_OPERATION);
3754 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
3755 programObject->setBinaryRetrievable(value != GL_FALSE);
3758 return error(GL_INVALID_ENUM);
3763 GL_APICALL void GL_APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3765 TRACE("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = %p)",
3766 target, numAttachments, attachments);
3768 glInvalidateSubFramebuffer(target, numAttachments, attachments, 0, 0, std::numeric_limits<GLsizei>::max(), std::numeric_limits<GLsizei>::max());
3771 GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
3773 TRACE("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = %p, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
3774 target, numAttachments, attachments, x, y, width, height);
3776 es2::Context *context = es2::getContext();
3780 if(numAttachments < 0 || width < 0 || height < 0)
3782 return error(GL_INVALID_VALUE);
3785 es2::Framebuffer *framebuffer = nullptr;
3788 case GL_DRAW_FRAMEBUFFER:
3789 case GL_FRAMEBUFFER:
3790 framebuffer = context->getDrawFramebuffer();
3791 case GL_READ_FRAMEBUFFER:
3792 framebuffer = context->getReadFramebuffer();
3795 return error(GL_INVALID_ENUM);
3800 for(int i = 0; i < numAttachments; i++)
3802 switch(attachments[i])
3807 if(!framebuffer->isDefaultFramebuffer())
3809 return error(GL_INVALID_ENUM);
3812 case GL_DEPTH_ATTACHMENT:
3813 case GL_STENCIL_ATTACHMENT:
3814 case GL_DEPTH_STENCIL_ATTACHMENT:
3817 if(attachments[i] >= GL_COLOR_ATTACHMENT0 &&
3818 attachments[i] <= GL_COLOR_ATTACHMENT31)
3820 if(attachments[i] - GL_COLOR_ATTACHMENT0 >= MAX_DRAW_BUFFERS)
3822 return error(GL_INVALID_OPERATION);
3827 return error(GL_INVALID_ENUM);
3834 // UNIMPLEMENTED(); // It is valid for this function to be treated as a no-op
3838 GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
3840 TRACE("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3841 target, levels, internalformat, width, height);
3843 if(width < 1 || height < 1 || levels < 1)
3845 return error(GL_INVALID_VALUE);
3848 if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
3850 return error(GL_INVALID_OPERATION);
3854 if(!GetStorageType(internalformat, type))
3856 return error(GL_INVALID_ENUM);
3859 es2::Context *context = es2::getContext();
3867 es2::Texture2D *texture = context->getTexture2D();
3868 if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
3870 return error(GL_INVALID_OPERATION);
3873 for(int level = 0; level < levels; ++level)
3875 texture->setImage(context, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
3876 width = std::max(1, (width / 2));
3877 height = std::max(1, (height / 2));
3879 texture->makeImmutable(levels);
3882 case GL_TEXTURE_CUBE_MAP:
3884 es2::TextureCubeMap *texture = context->getTextureCubeMap();
3885 if(!texture || texture->name == 0 || texture->getImmutableFormat())
3887 return error(GL_INVALID_OPERATION);
3890 for(int level = 0; level < levels; ++level)
3892 for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)
3894 texture->setImage(context, face, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
3896 width = std::max(1, (width / 2));
3897 height = std::max(1, (height / 2));
3899 texture->makeImmutable(levels);
3903 return error(GL_INVALID_ENUM);
3908 GL_APICALL void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
3910 TRACE("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d)",
3911 target, levels, internalformat, width, height, depth);
3913 if(width < 1 || height < 1 || depth < 1 || levels < 1)
3915 return error(GL_INVALID_VALUE);
3919 if(!GetStorageType(internalformat, type))
3921 return error(GL_INVALID_ENUM);
3924 es2::Context *context = es2::getContext();
3932 if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(std::max(width, height), depth)) + 1))
3934 return error(GL_INVALID_OPERATION);
3937 es2::Texture3D *texture = context->getTexture3D();
3938 if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
3940 return error(GL_INVALID_OPERATION);
3943 for(int level = 0; level < levels; ++level)
3945 texture->setImage(context, level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
3946 width = std::max(1, (width / 2));
3947 height = std::max(1, (height / 2));
3948 depth = std::max(1, (depth / 2));
3950 texture->makeImmutable(levels);
3953 case GL_TEXTURE_2D_ARRAY:
3955 if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
3957 return error(GL_INVALID_OPERATION);
3960 es2::Texture3D *texture = context->getTexture2DArray();
3961 if(!texture || texture->name == 0 || texture->getImmutableFormat())
3963 return error(GL_INVALID_OPERATION);
3966 for(int level = 0; level < levels; ++level)
3968 for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)
3970 texture->setImage(context, level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
3972 width = std::max(1, (width / 2));
3973 height = std::max(1, (height / 2));
3975 texture->makeImmutable(levels);
3979 return error(GL_INVALID_ENUM);
3984 GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params)
3986 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, GLint *params = %p)",
3987 target, internalformat, pname, bufSize, params);
3991 return error(GL_INVALID_VALUE);
3999 if(!IsColorRenderable(internalformat, egl::getClientVersion(), false) &&
4000 !IsDepthRenderable(internalformat, egl::getClientVersion()) &&
4001 !IsStencilRenderable(internalformat, egl::getClientVersion()))
4003 return error(GL_INVALID_ENUM);
4008 case GL_RENDERBUFFER:
4011 return error(GL_INVALID_ENUM);
4014 // Integer types have no multisampling
4015 GLint numMultisampleCounts = NUM_MULTISAMPLE_COUNTS;
4016 switch(internalformat)
4043 numMultisampleCounts = 0;
4051 case GL_NUM_SAMPLE_COUNTS:
4052 *params = numMultisampleCounts;
4055 for(int i = 0; i < numMultisampleCounts && i < bufSize; i++)
4057 params[i] = multisampleCount[i];
4061 return error(GL_INVALID_ENUM);