blob: cec9e8831a476a36bbf880605c22d18b9a533876 [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2013 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
12
13#include "main.h"
14#include "mathutil.h"
15#include "utilities.h"
16#include "Buffer.h"
17#include "Context.h"
18#include "Fence.h"
19#include "Framebuffer.h"
20#include "Program.h"
21#include "Renderbuffer.h"
22#include "Shader.h"
23#include "Texture.h"
24#include "Query.h"
25#include "common/debug.h"
26#include "Common/Version.h"
27
John Bauman66b8ab22014-05-06 15:57:45 -040028#include <GLES2/gl2.h>
29#include <GLES2/gl2ext.h>
Alexis Hetufceb1832015-03-10 16:42:04 -040030#include <GLES3/gl3.h>
John Bauman66b8ab22014-05-06 15:57:45 -040031
John Bauman66b8ab22014-05-06 15:57:45 -040032#include <limits>
33
Greg Hartman6074f122015-04-08 09:57:16 -070034#ifdef ANDROID
35#include <cutils/log.h>
36#endif
37
Nicolas Capenseb195b62015-04-28 17:18:42 -070038namespace es2
39{
Nicolas Capensa2308052015-04-15 16:50:21 -040040
Alexis Hetub027aa92015-01-19 15:56:12 -050041typedef std::pair<GLenum, GLenum> InternalFormatTypePair;
42typedef std::map<InternalFormatTypePair, GLenum> FormatMap;
43
44// A helper function to insert data into the format map with fewer characters.
45static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)
46{
47 map[InternalFormatTypePair(internalformat, type)] = format;
48}
49
John Bauman66b8ab22014-05-06 15:57:45 -040050static bool validImageSize(GLint level, GLsizei width, GLsizei height)
51{
Nicolas Capensf160b172014-11-26 11:58:23 -050052 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
53 {
54 return false;
55 }
John Bauman66b8ab22014-05-06 15:57:45 -040056
Nicolas Capensf160b172014-11-26 11:58:23 -050057 return true;
John Bauman66b8ab22014-05-06 15:57:45 -040058}
59
Nicolas Capens14ee7622014-10-28 23:48:41 -040060static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)
John Bauman66b8ab22014-05-06 15:57:45 -040061{
Nicolas Capensf160b172014-11-26 11:58:23 -050062 if(!texture)
63 {
64 return error(GL_INVALID_OPERATION, false);
65 }
John Bauman66b8ab22014-05-06 15:57:45 -040066
Nicolas Capensf160b172014-11-26 11:58:23 -050067 if(compressed != texture->isCompressed(target, level))
68 {
69 return error(GL_INVALID_OPERATION, false);
70 }
John Bauman66b8ab22014-05-06 15:57:45 -040071
Nicolas Capensf160b172014-11-26 11:58:23 -050072 if(format != GL_NONE && format != texture->getFormat(target, level))
73 {
74 return error(GL_INVALID_OPERATION, false);
75 }
John Bauman66b8ab22014-05-06 15:57:45 -040076
Nicolas Capensf160b172014-11-26 11:58:23 -050077 if(compressed)
78 {
79 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
Alexis Hetub027aa92015-01-19 15:56:12 -050080 (height % 4 != 0 && height != texture->getHeight(target, 0)))
Nicolas Capensf160b172014-11-26 11:58:23 -050081 {
82 return error(GL_INVALID_OPERATION, false);
83 }
84 }
John Bauman66b8ab22014-05-06 15:57:45 -040085
Nicolas Capensf160b172014-11-26 11:58:23 -050086 if(xoffset + width > texture->getWidth(target, level) ||
Alexis Hetub027aa92015-01-19 15:56:12 -050087 yoffset + height > texture->getHeight(target, level))
Nicolas Capensf160b172014-11-26 11:58:23 -050088 {
89 return error(GL_INVALID_VALUE, false);
90 }
John Bauman66b8ab22014-05-06 15:57:45 -040091
Nicolas Capensf160b172014-11-26 11:58:23 -050092 return true;
John Bauman66b8ab22014-05-06 15:57:45 -040093}
94
Alexis Hetub027aa92015-01-19 15:56:12 -050095static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)
96{
97 if(!texture)
98 {
99 return error(GL_INVALID_OPERATION, false);
100 }
101
102 if(compressed != texture->isCompressed(target, level))
103 {
104 return error(GL_INVALID_OPERATION, false);
105 }
106
107 if(format != GL_NONE && format != texture->getFormat(target, level))
108 {
109 return error(GL_INVALID_OPERATION, false);
110 }
111
112 if(compressed)
113 {
114 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
115 (height % 4 != 0 && height != texture->getHeight(target, 0)) ||
116 (depth % 4 != 0 && depth != texture->getDepth(target, 0)))
117 {
118 return error(GL_INVALID_OPERATION, false);
119 }
120 }
121
122 if(xoffset + width > texture->getWidth(target, level) ||
123 yoffset + height > texture->getHeight(target, level) ||
124 zoffset + depth > texture->getDepth(target, level))
125 {
126 return error(GL_INVALID_VALUE, false);
127 }
128
129 return true;
130}
131
132static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
133{
134 // [OpenGL ES 2.0.24] table 3.9
135 switch(textureFormat)
136 {
137 case GL_ALPHA:
138 if(colorbufferFormat != GL_ALPHA &&
Nicolas Capenseb195b62015-04-28 17:18:42 -0700139 colorbufferFormat != GL_RGBA &&
140 colorbufferFormat != GL_RGBA4 &&
141 colorbufferFormat != GL_RGB5_A1 &&
142 colorbufferFormat != GL_RGBA8_OES)
Alexis Hetub027aa92015-01-19 15:56:12 -0500143 {
144 return error(GL_INVALID_OPERATION, false);
145 }
146 break;
147 case GL_LUMINANCE:
148 case GL_RGB:
149 if(colorbufferFormat != GL_RGB &&
Nicolas Capenseb195b62015-04-28 17:18:42 -0700150 colorbufferFormat != GL_RGB565 &&
151 colorbufferFormat != GL_RGB8_OES &&
152 colorbufferFormat != GL_RGBA &&
153 colorbufferFormat != GL_RGBA4 &&
154 colorbufferFormat != GL_RGB5_A1 &&
155 colorbufferFormat != GL_RGBA8_OES)
Alexis Hetub027aa92015-01-19 15:56:12 -0500156 {
157 return error(GL_INVALID_OPERATION, false);
158 }
159 break;
160 case GL_LUMINANCE_ALPHA:
161 case GL_RGBA:
162 if(colorbufferFormat != GL_RGBA &&
Nicolas Capenseb195b62015-04-28 17:18:42 -0700163 colorbufferFormat != GL_RGBA4 &&
164 colorbufferFormat != GL_RGB5_A1 &&
165 colorbufferFormat != GL_RGBA8_OES)
Alexis Hetub027aa92015-01-19 15:56:12 -0500166 {
167 return error(GL_INVALID_OPERATION, false);
168 }
169 break;
170 case GL_ETC1_RGB8_OES:
171 return error(GL_INVALID_OPERATION, false);
172 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
173 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
174 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
175 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
176 if(S3TC_SUPPORT)
177 {
178 return error(GL_INVALID_OPERATION, false);
179 }
180 else
181 {
182 return error(GL_INVALID_ENUM, false);
183 }
184 case GL_DEPTH_COMPONENT:
185 case GL_DEPTH_STENCIL_OES:
186 return error(GL_INVALID_OPERATION, false);
187 default:
188 return error(GL_INVALID_ENUM, false);
189 }
190 return true;
191}
192
193static FormatMap BuildFormatMap3D()
194{
195 FormatMap map;
196
197 // Internal format | Format | Type
198 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
199 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
200 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
201 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
202 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
203 InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
204 InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
205 InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
206 InsertFormatMapping(map, GL_R8_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE);
207 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
208 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
209 InsertFormatMapping(map, GL_R32F_EXT, GL_RED_EXT, GL_FLOAT);
210 InsertFormatMapping(map, GL_RG8_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE);
211 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
212 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
213 InsertFormatMapping(map, GL_RG32F_EXT, GL_RG_EXT, GL_FLOAT);
214 InsertFormatMapping(map, GL_RGB8_OES, GL_RGB, GL_UNSIGNED_BYTE);
215 InsertFormatMapping(map, GL_SRGB8_NV, GL_RGB, GL_UNSIGNED_BYTE);
216 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);
217 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
Alexis Hetu0300e3c2015-03-12 17:33:07 -0400218 InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
219 InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_FLOAT);
Alexis Hetub027aa92015-01-19 15:56:12 -0500220 InsertFormatMapping(map, GL_RGB32F_EXT, GL_RGB, GL_FLOAT);
221 InsertFormatMapping(map, GL_RGBA8_OES, GL_RGBA, GL_UNSIGNED_BYTE);
222 InsertFormatMapping(map, GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_BYTE);
223 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);
224 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
225 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
226 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);
227 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
228 InsertFormatMapping(map, GL_RGB10_A2_EXT, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
229 InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
230 InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_FLOAT);
231 InsertFormatMapping(map, GL_RGBA32F_EXT, GL_RGBA, GL_FLOAT);
232
233 return map;
234}
235
236static bool ValidateType3D(GLenum type)
237{
238 switch(type)
239 {
240 case GL_UNSIGNED_BYTE:
241 case GL_BYTE:
242 case GL_UNSIGNED_SHORT:
243 case GL_SHORT:
244 case GL_UNSIGNED_INT:
245 case GL_INT:
246 case GL_HALF_FLOAT_OES:
247 case GL_FLOAT:
248 case GL_UNSIGNED_SHORT_5_6_5:
249 case GL_UNSIGNED_SHORT_4_4_4_4:
250 case GL_UNSIGNED_SHORT_5_5_5_1:
251 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
252 return true;
253 default:
254 break;
255 }
256 return false;
257}
258
259static bool ValidateFormat3D(GLenum format)
260{
261 switch(format)
262 {
263 case GL_RED_EXT:
264 case GL_RG_EXT:
265 case GL_RGB:
266 case GL_RGBA:
267 case GL_DEPTH_COMPONENT:
268 case GL_DEPTH_STENCIL_OES:
269 case GL_LUMINANCE_ALPHA:
270 case GL_LUMINANCE:
271 case GL_ALPHA:
272 return true;
273 default:
274 break;
275 }
276 return false;
277}
278
279static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)
280{
281 static const FormatMap formatMap = BuildFormatMap3D();
282 FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));
283 if(iter != formatMap.end())
284 {
285 return iter->second == format;
286 }
287 return false;
288}
289
Nicolas Capenseb195b62015-04-28 17:18:42 -0700290void ActiveTexture(GLenum texture)
John Bauman66b8ab22014-05-06 15:57:45 -0400291{
Nicolas Capensf160b172014-11-26 11:58:23 -0500292 TRACE("(GLenum texture = 0x%X)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400293
Nicolas Capensf160b172014-11-26 11:58:23 -0500294 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400295
Nicolas Capensf160b172014-11-26 11:58:23 -0500296 if(context)
297 {
298 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
299 {
300 return error(GL_INVALID_ENUM);
301 }
John Bauman66b8ab22014-05-06 15:57:45 -0400302
Nicolas Capensf160b172014-11-26 11:58:23 -0500303 context->setActiveSampler(texture - GL_TEXTURE0);
304 }
John Bauman66b8ab22014-05-06 15:57:45 -0400305}
306
Nicolas Capenseb195b62015-04-28 17:18:42 -0700307void AttachShader(GLuint program, GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -0400308{
Nicolas Capensf160b172014-11-26 11:58:23 -0500309 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400310
Nicolas Capensf160b172014-11-26 11:58:23 -0500311 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400312
Nicolas Capensf160b172014-11-26 11:58:23 -0500313 if(context)
314 {
315 es2::Program *programObject = context->getProgram(program);
316 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400317
Nicolas Capensf160b172014-11-26 11:58:23 -0500318 if(!programObject)
319 {
320 if(context->getShader(program))
321 {
322 return error(GL_INVALID_OPERATION);
323 }
324 else
325 {
326 return error(GL_INVALID_VALUE);
327 }
328 }
John Bauman66b8ab22014-05-06 15:57:45 -0400329
Nicolas Capensf160b172014-11-26 11:58:23 -0500330 if(!shaderObject)
331 {
332 if(context->getProgram(shader))
333 {
334 return error(GL_INVALID_OPERATION);
335 }
336 else
337 {
338 return error(GL_INVALID_VALUE);
339 }
340 }
John Bauman66b8ab22014-05-06 15:57:45 -0400341
Nicolas Capensf160b172014-11-26 11:58:23 -0500342 if(!programObject->attachShader(shaderObject))
343 {
344 return error(GL_INVALID_OPERATION);
345 }
346 }
John Bauman66b8ab22014-05-06 15:57:45 -0400347}
348
Nicolas Capenseb195b62015-04-28 17:18:42 -0700349void BeginQueryEXT(GLenum target, GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -0400350{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500351 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
John Bauman66b8ab22014-05-06 15:57:45 -0400352
Nicolas Capensf160b172014-11-26 11:58:23 -0500353 switch(target)
354 {
355 case GL_ANY_SAMPLES_PASSED_EXT:
356 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
357 break;
358 default:
359 return error(GL_INVALID_ENUM);
360 }
John Bauman66b8ab22014-05-06 15:57:45 -0400361
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500362 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -0500363 {
364 return error(GL_INVALID_OPERATION);
365 }
John Bauman66b8ab22014-05-06 15:57:45 -0400366
Nicolas Capensf160b172014-11-26 11:58:23 -0500367 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400368
Nicolas Capensf160b172014-11-26 11:58:23 -0500369 if(context)
370 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500371 context->beginQuery(target, name);
Nicolas Capensf160b172014-11-26 11:58:23 -0500372 }
John Bauman66b8ab22014-05-06 15:57:45 -0400373}
374
Nicolas Capenseb195b62015-04-28 17:18:42 -0700375void BindAttribLocation(GLuint program, GLuint index, const GLchar* name)
John Bauman66b8ab22014-05-06 15:57:45 -0400376{
Nicolas Capensf160b172014-11-26 11:58:23 -0500377 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
John Bauman66b8ab22014-05-06 15:57:45 -0400378
Nicolas Capensf160b172014-11-26 11:58:23 -0500379 if(index >= es2::MAX_VERTEX_ATTRIBS)
380 {
381 return error(GL_INVALID_VALUE);
382 }
John Bauman66b8ab22014-05-06 15:57:45 -0400383
Nicolas Capensf160b172014-11-26 11:58:23 -0500384 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400385
Nicolas Capensf160b172014-11-26 11:58:23 -0500386 if(context)
387 {
388 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -0400389
Nicolas Capensf160b172014-11-26 11:58:23 -0500390 if(!programObject)
391 {
392 if(context->getShader(program))
393 {
394 return error(GL_INVALID_OPERATION);
395 }
396 else
397 {
398 return error(GL_INVALID_VALUE);
399 }
400 }
John Bauman66b8ab22014-05-06 15:57:45 -0400401
Nicolas Capensf160b172014-11-26 11:58:23 -0500402 if(strncmp(name, "gl_", 3) == 0)
403 {
404 return error(GL_INVALID_OPERATION);
405 }
John Bauman66b8ab22014-05-06 15:57:45 -0400406
Nicolas Capensf160b172014-11-26 11:58:23 -0500407 programObject->bindAttributeLocation(index, name);
408 }
John Bauman66b8ab22014-05-06 15:57:45 -0400409}
410
Nicolas Capenseb195b62015-04-28 17:18:42 -0700411void BindBuffer(GLenum target, GLuint buffer)
John Bauman66b8ab22014-05-06 15:57:45 -0400412{
Nicolas Capensf160b172014-11-26 11:58:23 -0500413 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400414
Nicolas Capensf160b172014-11-26 11:58:23 -0500415 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400416
Nicolas Capensf160b172014-11-26 11:58:23 -0500417 if(context)
418 {
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400419 egl::GLint clientVersion = egl::getClientVersion();
420
Nicolas Capensf160b172014-11-26 11:58:23 -0500421 switch(target)
422 {
423 case GL_ARRAY_BUFFER:
424 context->bindArrayBuffer(buffer);
425 return;
426 case GL_ELEMENT_ARRAY_BUFFER:
427 context->bindElementArrayBuffer(buffer);
428 return;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400429 case GL_COPY_READ_BUFFER:
430 if(clientVersion >= 3)
431 {
432 context->bindCopyReadBuffer(buffer);
433 return;
434 }
435 else return error(GL_INVALID_ENUM);
436 case GL_COPY_WRITE_BUFFER:
437 if(clientVersion >= 3)
438 {
439 context->bindCopyWriteBuffer(buffer);
440 return;
441 }
442 else return error(GL_INVALID_ENUM);
443 case GL_PIXEL_PACK_BUFFER:
444 if(clientVersion >= 3)
445 {
446 context->bindPixelPackBuffer(buffer);
447 return;
448 }
449 else return error(GL_INVALID_ENUM);
450 case GL_PIXEL_UNPACK_BUFFER:
451 if(clientVersion >= 3)
452 {
453 context->bindPixelUnpackBuffer(buffer);
454 return;
455 }
456 else return error(GL_INVALID_ENUM);
457 case GL_TRANSFORM_FEEDBACK_BUFFER:
458 if(clientVersion >= 3)
459 {
Alexis Hetubcac6ff2015-04-22 08:29:22 -0400460 context->bindTransformFeedbackBuffer(buffer);
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400461 return;
462 }
463 else return error(GL_INVALID_ENUM);
464 case GL_UNIFORM_BUFFER:
465 if(clientVersion >= 3)
466 {
467 context->bindUniformBuffer(buffer);
468 return;
469 }
470 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -0500471 default:
472 return error(GL_INVALID_ENUM);
473 }
474 }
John Bauman66b8ab22014-05-06 15:57:45 -0400475}
476
Nicolas Capenseb195b62015-04-28 17:18:42 -0700477void BindFramebuffer(GLenum target, GLuint framebuffer)
John Bauman66b8ab22014-05-06 15:57:45 -0400478{
Nicolas Capensf160b172014-11-26 11:58:23 -0500479 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400480
Nicolas Capensf160b172014-11-26 11:58:23 -0500481 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
482 {
483 return error(GL_INVALID_ENUM);
484 }
John Bauman66b8ab22014-05-06 15:57:45 -0400485
Nicolas Capensf160b172014-11-26 11:58:23 -0500486 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400487
Nicolas Capensf160b172014-11-26 11:58:23 -0500488 if(context)
489 {
490 if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
491 {
492 context->bindReadFramebuffer(framebuffer);
493 }
Nicolas Capens08e90f02014-11-21 12:49:12 -0500494
Nicolas Capensf160b172014-11-26 11:58:23 -0500495 if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
496 {
497 context->bindDrawFramebuffer(framebuffer);
498 }
499 }
John Bauman66b8ab22014-05-06 15:57:45 -0400500}
501
Nicolas Capenseb195b62015-04-28 17:18:42 -0700502void BindRenderbuffer(GLenum target, GLuint renderbuffer)
John Bauman66b8ab22014-05-06 15:57:45 -0400503{
Nicolas Capensf160b172014-11-26 11:58:23 -0500504 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400505
Nicolas Capensf160b172014-11-26 11:58:23 -0500506 if(target != GL_RENDERBUFFER)
507 {
508 return error(GL_INVALID_ENUM);
509 }
John Bauman66b8ab22014-05-06 15:57:45 -0400510
Nicolas Capensf160b172014-11-26 11:58:23 -0500511 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400512
Nicolas Capensf160b172014-11-26 11:58:23 -0500513 if(context)
514 {
515 if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))
516 {
517 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
518 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
519 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
520 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
521 return error(GL_INVALID_OPERATION);
522 }
Alexis Hetu42a584d2014-11-07 14:23:33 -0500523
Nicolas Capensf160b172014-11-26 11:58:23 -0500524 context->bindRenderbuffer(renderbuffer);
525 }
John Bauman66b8ab22014-05-06 15:57:45 -0400526}
527
Nicolas Capenseb195b62015-04-28 17:18:42 -0700528void BindTexture(GLenum target, GLuint texture)
John Bauman66b8ab22014-05-06 15:57:45 -0400529{
Nicolas Capensf160b172014-11-26 11:58:23 -0500530 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400531
Nicolas Capensf160b172014-11-26 11:58:23 -0500532 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400533
Nicolas Capensf160b172014-11-26 11:58:23 -0500534 if(context)
535 {
536 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400537
Nicolas Capensf160b172014-11-26 11:58:23 -0500538 if(textureObject && textureObject->getTarget() != target && texture != 0)
539 {
540 return error(GL_INVALID_OPERATION);
541 }
John Bauman66b8ab22014-05-06 15:57:45 -0400542
Alexis Hetued306182015-04-02 12:02:28 -0400543 egl::GLint clientVersion = context->getClientVersion();
544
Nicolas Capensf160b172014-11-26 11:58:23 -0500545 switch(target)
546 {
547 case GL_TEXTURE_2D:
548 context->bindTexture2D(texture);
549 return;
550 case GL_TEXTURE_CUBE_MAP:
551 context->bindTextureCubeMap(texture);
552 return;
553 case GL_TEXTURE_EXTERNAL_OES:
554 context->bindTextureExternal(texture);
555 return;
Alexis Hetued306182015-04-02 12:02:28 -0400556 case GL_TEXTURE_2D_ARRAY:
557 if(clientVersion < 3)
558 {
559 return error(GL_INVALID_ENUM);
560 }
561 else
562 {
563 UNIMPLEMENTED();
564 context->bindTexture3D(texture);
565 break;
566 }
Alexis Hetub027aa92015-01-19 15:56:12 -0500567 case GL_TEXTURE_3D_OES:
568 context->bindTexture3D(texture);
569 return;
Nicolas Capensf160b172014-11-26 11:58:23 -0500570 default:
571 return error(GL_INVALID_ENUM);
572 }
573 }
John Bauman66b8ab22014-05-06 15:57:45 -0400574}
575
Nicolas Capenseb195b62015-04-28 17:18:42 -0700576void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400577{
Nicolas Capensf160b172014-11-26 11:58:23 -0500578 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
579 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400580
Nicolas Capensf160b172014-11-26 11:58:23 -0500581 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400582
Nicolas Capensf160b172014-11-26 11:58:23 -0500583 if(context)
584 {
585 context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));
586 }
John Bauman66b8ab22014-05-06 15:57:45 -0400587}
588
Nicolas Capenseb195b62015-04-28 17:18:42 -0700589void BlendEquation(GLenum mode)
John Bauman66b8ab22014-05-06 15:57:45 -0400590{
Nicolas Capensf160b172014-11-26 11:58:23 -0500591 glBlendEquationSeparate(mode, mode);
John Bauman66b8ab22014-05-06 15:57:45 -0400592}
593
Nicolas Capenseb195b62015-04-28 17:18:42 -0700594void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400595{
Nicolas Capensf160b172014-11-26 11:58:23 -0500596 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400597
Nicolas Capensf160b172014-11-26 11:58:23 -0500598 switch(modeRGB)
599 {
600 case GL_FUNC_ADD:
601 case GL_FUNC_SUBTRACT:
602 case GL_FUNC_REVERSE_SUBTRACT:
603 case GL_MIN_EXT:
604 case GL_MAX_EXT:
605 break;
606 default:
607 return error(GL_INVALID_ENUM);
608 }
John Bauman66b8ab22014-05-06 15:57:45 -0400609
Nicolas Capensf160b172014-11-26 11:58:23 -0500610 switch(modeAlpha)
611 {
612 case GL_FUNC_ADD:
613 case GL_FUNC_SUBTRACT:
614 case GL_FUNC_REVERSE_SUBTRACT:
615 case GL_MIN_EXT:
616 case GL_MAX_EXT:
617 break;
618 default:
619 return error(GL_INVALID_ENUM);
620 }
John Bauman66b8ab22014-05-06 15:57:45 -0400621
Nicolas Capensf160b172014-11-26 11:58:23 -0500622 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400623
Nicolas Capensf160b172014-11-26 11:58:23 -0500624 if(context)
625 {
626 context->setBlendEquation(modeRGB, modeAlpha);
627 }
John Bauman66b8ab22014-05-06 15:57:45 -0400628}
629
Nicolas Capenseb195b62015-04-28 17:18:42 -0700630void BlendFunc(GLenum sfactor, GLenum dfactor)
John Bauman66b8ab22014-05-06 15:57:45 -0400631{
Nicolas Capensf160b172014-11-26 11:58:23 -0500632 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
John Bauman66b8ab22014-05-06 15:57:45 -0400633}
634
Nicolas Capenseb195b62015-04-28 17:18:42 -0700635void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400636{
Nicolas Capensf160b172014-11-26 11:58:23 -0500637 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
638 srcRGB, dstRGB, srcAlpha, dstAlpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400639
Nicolas Capensf160b172014-11-26 11:58:23 -0500640 switch(srcRGB)
641 {
642 case GL_ZERO:
643 case GL_ONE:
644 case GL_SRC_COLOR:
645 case GL_ONE_MINUS_SRC_COLOR:
646 case GL_DST_COLOR:
647 case GL_ONE_MINUS_DST_COLOR:
648 case GL_SRC_ALPHA:
649 case GL_ONE_MINUS_SRC_ALPHA:
650 case GL_DST_ALPHA:
651 case GL_ONE_MINUS_DST_ALPHA:
652 case GL_CONSTANT_COLOR:
653 case GL_ONE_MINUS_CONSTANT_COLOR:
654 case GL_CONSTANT_ALPHA:
655 case GL_ONE_MINUS_CONSTANT_ALPHA:
656 case GL_SRC_ALPHA_SATURATE:
657 break;
658 default:
659 return error(GL_INVALID_ENUM);
660 }
John Bauman66b8ab22014-05-06 15:57:45 -0400661
Nicolas Capensf160b172014-11-26 11:58:23 -0500662 switch(dstRGB)
663 {
664 case GL_ZERO:
665 case GL_ONE:
666 case GL_SRC_COLOR:
667 case GL_ONE_MINUS_SRC_COLOR:
668 case GL_DST_COLOR:
669 case GL_ONE_MINUS_DST_COLOR:
670 case GL_SRC_ALPHA:
671 case GL_ONE_MINUS_SRC_ALPHA:
672 case GL_DST_ALPHA:
673 case GL_ONE_MINUS_DST_ALPHA:
674 case GL_CONSTANT_COLOR:
675 case GL_ONE_MINUS_CONSTANT_COLOR:
676 case GL_CONSTANT_ALPHA:
677 case GL_ONE_MINUS_CONSTANT_ALPHA:
678 break;
679 default:
680 return error(GL_INVALID_ENUM);
681 }
John Bauman66b8ab22014-05-06 15:57:45 -0400682
Nicolas Capensf160b172014-11-26 11:58:23 -0500683 switch(srcAlpha)
684 {
685 case GL_ZERO:
686 case GL_ONE:
687 case GL_SRC_COLOR:
688 case GL_ONE_MINUS_SRC_COLOR:
689 case GL_DST_COLOR:
690 case GL_ONE_MINUS_DST_COLOR:
691 case GL_SRC_ALPHA:
692 case GL_ONE_MINUS_SRC_ALPHA:
693 case GL_DST_ALPHA:
694 case GL_ONE_MINUS_DST_ALPHA:
695 case GL_CONSTANT_COLOR:
696 case GL_ONE_MINUS_CONSTANT_COLOR:
697 case GL_CONSTANT_ALPHA:
698 case GL_ONE_MINUS_CONSTANT_ALPHA:
699 case GL_SRC_ALPHA_SATURATE:
700 break;
701 default:
702 return error(GL_INVALID_ENUM);
703 }
John Bauman66b8ab22014-05-06 15:57:45 -0400704
Nicolas Capensf160b172014-11-26 11:58:23 -0500705 switch(dstAlpha)
706 {
707 case GL_ZERO:
708 case GL_ONE:
709 case GL_SRC_COLOR:
710 case GL_ONE_MINUS_SRC_COLOR:
711 case GL_DST_COLOR:
712 case GL_ONE_MINUS_DST_COLOR:
713 case GL_SRC_ALPHA:
714 case GL_ONE_MINUS_SRC_ALPHA:
715 case GL_DST_ALPHA:
716 case GL_ONE_MINUS_DST_ALPHA:
717 case GL_CONSTANT_COLOR:
718 case GL_ONE_MINUS_CONSTANT_COLOR:
719 case GL_CONSTANT_ALPHA:
720 case GL_ONE_MINUS_CONSTANT_ALPHA:
721 break;
722 default:
723 return error(GL_INVALID_ENUM);
724 }
John Bauman66b8ab22014-05-06 15:57:45 -0400725
Nicolas Capensf160b172014-11-26 11:58:23 -0500726 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400727
Nicolas Capensf160b172014-11-26 11:58:23 -0500728 if(context)
729 {
730 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
731 }
John Bauman66b8ab22014-05-06 15:57:45 -0400732}
733
Nicolas Capenseb195b62015-04-28 17:18:42 -0700734void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
Nicolas Capens54b721d2014-12-12 12:50:04 -0500735{
736 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
Nicolas Capens4cadfe32014-12-10 22:26:26 -0500737
Nicolas Capens4be33702015-04-28 15:13:30 -0700738 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
Nicolas Capensf160b172014-11-26 11:58:23 -0500739 target, size, data, usage);
John Bauman66b8ab22014-05-06 15:57:45 -0400740
Nicolas Capensf160b172014-11-26 11:58:23 -0500741 if(size < 0)
742 {
743 return error(GL_INVALID_VALUE);
744 }
John Bauman66b8ab22014-05-06 15:57:45 -0400745
Alexis Hetued306182015-04-02 12:02:28 -0400746 egl::GLint clientVersion = egl::getClientVersion();
747
Nicolas Capensf160b172014-11-26 11:58:23 -0500748 switch(usage)
749 {
750 case GL_STREAM_DRAW:
751 case GL_STATIC_DRAW:
752 case GL_DYNAMIC_DRAW:
753 break;
Alexis Hetued306182015-04-02 12:02:28 -0400754 case GL_STREAM_READ:
755 case GL_STREAM_COPY:
756 case GL_STATIC_READ:
757 case GL_STATIC_COPY:
758 case GL_DYNAMIC_READ:
759 case GL_DYNAMIC_COPY:
760 if(clientVersion < 3)
761 {
762 return error(GL_INVALID_ENUM);
763 }
764 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500765 default:
766 return error(GL_INVALID_ENUM);
767 }
John Bauman66b8ab22014-05-06 15:57:45 -0400768
Nicolas Capensf160b172014-11-26 11:58:23 -0500769 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400770
Nicolas Capensf160b172014-11-26 11:58:23 -0500771 if(context)
772 {
773 es2::Buffer *buffer;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400774 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -0500775 {
Nicolas Capensf160b172014-11-26 11:58:23 -0500776 return error(GL_INVALID_ENUM);
777 }
John Bauman66b8ab22014-05-06 15:57:45 -0400778
Nicolas Capensf160b172014-11-26 11:58:23 -0500779 if(!buffer)
780 {
Alexis Hetued306182015-04-02 12:02:28 -0400781 // A null buffer means that "0" is bound to the requested buffer target
Nicolas Capensf160b172014-11-26 11:58:23 -0500782 return error(GL_INVALID_OPERATION);
783 }
John Bauman66b8ab22014-05-06 15:57:45 -0400784
Nicolas Capensf160b172014-11-26 11:58:23 -0500785 buffer->bufferData(data, size, usage);
786 }
John Bauman66b8ab22014-05-06 15:57:45 -0400787}
788
Nicolas Capenseb195b62015-04-28 17:18:42 -0700789void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
Nicolas Capens54b721d2014-12-12 12:50:04 -0500790{
791 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
792 offset = static_cast<GLint>(offset);
Nicolas Capens4cadfe32014-12-10 22:26:26 -0500793
Nicolas Capens4be33702015-04-28 15:13:30 -0700794 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -0500795 target, offset, size, data);
John Bauman66b8ab22014-05-06 15:57:45 -0400796
Nicolas Capensf160b172014-11-26 11:58:23 -0500797 if(size < 0 || offset < 0)
798 {
799 return error(GL_INVALID_VALUE);
800 }
John Bauman66b8ab22014-05-06 15:57:45 -0400801
Nicolas Capensf160b172014-11-26 11:58:23 -0500802 if(data == NULL)
803 {
804 return;
805 }
John Bauman66b8ab22014-05-06 15:57:45 -0400806
Nicolas Capensf160b172014-11-26 11:58:23 -0500807 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400808
Nicolas Capensf160b172014-11-26 11:58:23 -0500809 if(context)
810 {
811 es2::Buffer *buffer;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400812 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -0500813 {
Nicolas Capensf160b172014-11-26 11:58:23 -0500814 return error(GL_INVALID_ENUM);
815 }
John Bauman66b8ab22014-05-06 15:57:45 -0400816
Nicolas Capensf160b172014-11-26 11:58:23 -0500817 if(!buffer)
818 {
Alexis Hetued306182015-04-02 12:02:28 -0400819 // A null buffer means that "0" is bound to the requested buffer target
Nicolas Capensf160b172014-11-26 11:58:23 -0500820 return error(GL_INVALID_OPERATION);
821 }
John Bauman66b8ab22014-05-06 15:57:45 -0400822
Nicolas Capensf160b172014-11-26 11:58:23 -0500823 if((size_t)size + offset > buffer->size())
John Bauman66b8ab22014-05-06 15:57:45 -0400824 {
825 return error(GL_INVALID_VALUE);
826 }
827
Nicolas Capensf160b172014-11-26 11:58:23 -0500828 buffer->bufferSubData(data, size, offset);
829 }
830}
John Bauman66b8ab22014-05-06 15:57:45 -0400831
Nicolas Capenseb195b62015-04-28 17:18:42 -0700832GLenum CheckFramebufferStatus(GLenum target)
Nicolas Capensf160b172014-11-26 11:58:23 -0500833{
834 TRACE("(GLenum target = 0x%X)", target);
835
836 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
837 {
838 return error(GL_INVALID_ENUM, 0);
839 }
840
841 es2::Context *context = es2::getContext();
842
843 if(context)
844 {
845 es2::Framebuffer *framebuffer = NULL;
846 if(target == GL_READ_FRAMEBUFFER_ANGLE)
847 {
848 framebuffer = context->getReadFramebuffer();
849 }
850 else
851 {
852 framebuffer = context->getDrawFramebuffer();
853 }
854
855 return framebuffer->completeness();
856 }
857
858 return 0;
859}
860
Nicolas Capenseb195b62015-04-28 17:18:42 -0700861void Clear(GLbitfield mask)
Nicolas Capensf160b172014-11-26 11:58:23 -0500862{
863 TRACE("(GLbitfield mask = %X)", mask);
864
865 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
866 {
867 return error(GL_INVALID_VALUE);
868 }
869
870 es2::Context *context = es2::getContext();
871
872 if(context)
873 {
874 context->clear(mask);
875 }
John Bauman66b8ab22014-05-06 15:57:45 -0400876}
877
Nicolas Capenseb195b62015-04-28 17:18:42 -0700878void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400879{
Nicolas Capensf160b172014-11-26 11:58:23 -0500880 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
881 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400882
Nicolas Capensf160b172014-11-26 11:58:23 -0500883 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400884
Nicolas Capensf160b172014-11-26 11:58:23 -0500885 if(context)
886 {
887 context->setClearColor(red, green, blue, alpha);
888 }
John Bauman66b8ab22014-05-06 15:57:45 -0400889}
890
Nicolas Capenseb195b62015-04-28 17:18:42 -0700891void ClearDepthf(GLclampf depth)
John Bauman66b8ab22014-05-06 15:57:45 -0400892{
Nicolas Capensf160b172014-11-26 11:58:23 -0500893 TRACE("(GLclampf depth = %f)", depth);
John Bauman66b8ab22014-05-06 15:57:45 -0400894
Nicolas Capensf160b172014-11-26 11:58:23 -0500895 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400896
Nicolas Capensf160b172014-11-26 11:58:23 -0500897 if(context)
898 {
899 context->setClearDepth(depth);
900 }
John Bauman66b8ab22014-05-06 15:57:45 -0400901}
902
Nicolas Capenseb195b62015-04-28 17:18:42 -0700903void ClearStencil(GLint s)
John Bauman66b8ab22014-05-06 15:57:45 -0400904{
Nicolas Capensf160b172014-11-26 11:58:23 -0500905 TRACE("(GLint s = %d)", s);
John Bauman66b8ab22014-05-06 15:57:45 -0400906
Nicolas Capensf160b172014-11-26 11:58:23 -0500907 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400908
Nicolas Capensf160b172014-11-26 11:58:23 -0500909 if(context)
910 {
911 context->setClearStencil(s);
912 }
John Bauman66b8ab22014-05-06 15:57:45 -0400913}
914
Nicolas Capenseb195b62015-04-28 17:18:42 -0700915void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400916{
Nicolas Capensf160b172014-11-26 11:58:23 -0500917 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
918 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400919
Nicolas Capensf160b172014-11-26 11:58:23 -0500920 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400921
Nicolas Capensf160b172014-11-26 11:58:23 -0500922 if(context)
923 {
924 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
925 }
John Bauman66b8ab22014-05-06 15:57:45 -0400926}
927
Nicolas Capenseb195b62015-04-28 17:18:42 -0700928void CompileShader(GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -0400929{
Nicolas Capensf160b172014-11-26 11:58:23 -0500930 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400931
Nicolas Capensf160b172014-11-26 11:58:23 -0500932 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400933
Nicolas Capensf160b172014-11-26 11:58:23 -0500934 if(context)
935 {
936 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400937
Nicolas Capensf160b172014-11-26 11:58:23 -0500938 if(!shaderObject)
939 {
940 if(context->getProgram(shader))
941 {
942 return error(GL_INVALID_OPERATION);
943 }
944 else
945 {
946 return error(GL_INVALID_VALUE);
947 }
948 }
John Bauman66b8ab22014-05-06 15:57:45 -0400949
Nicolas Capensf160b172014-11-26 11:58:23 -0500950 shaderObject->compile();
951 }
John Bauman66b8ab22014-05-06 15:57:45 -0400952}
953
Nicolas Capenseb195b62015-04-28 17:18:42 -0700954void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
955 GLint border, GLsizei imageSize, const GLvoid* data)
John Bauman66b8ab22014-05-06 15:57:45 -0400956{
Nicolas Capensf160b172014-11-26 11:58:23 -0500957 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -0700958 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -0500959 target, level, internalformat, width, height, border, imageSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -0400960
Nicolas Capensf160b172014-11-26 11:58:23 -0500961 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
962 {
963 return error(GL_INVALID_VALUE);
964 }
John Bauman66b8ab22014-05-06 15:57:45 -0400965
Alexis Hetued306182015-04-02 12:02:28 -0400966 egl::GLint clientVersion = egl::getClientVersion();
967
Nicolas Capensf160b172014-11-26 11:58:23 -0500968 switch(internalformat)
969 {
Nicolas Capens22658242014-11-29 00:31:41 -0500970 case GL_ETC1_RGB8_OES:
971 break;
Alexis Hetued306182015-04-02 12:02:28 -0400972 case GL_COMPRESSED_R11_EAC:
973 case GL_COMPRESSED_SIGNED_R11_EAC:
974 case GL_COMPRESSED_RG11_EAC:
975 case GL_COMPRESSED_SIGNED_RG11_EAC:
976 case GL_COMPRESSED_RGB8_ETC2:
977 case GL_COMPRESSED_SRGB8_ETC2:
978 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
979 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
980 case GL_COMPRESSED_RGBA8_ETC2_EAC:
981 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
982 if(clientVersion >= 3)
983 {
984 break;
985 }
986 return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -0500987 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
988 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
989 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
990 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
991 if(!S3TC_SUPPORT)
992 {
993 return error(GL_INVALID_ENUM);
994 }
995 break;
996 case GL_DEPTH_COMPONENT:
997 case GL_DEPTH_COMPONENT16:
998 case GL_DEPTH_COMPONENT32_OES:
999 case GL_DEPTH_STENCIL_OES:
1000 case GL_DEPTH24_STENCIL8_OES:
1001 return error(GL_INVALID_OPERATION);
1002 default:
1003 return error(GL_INVALID_ENUM);
1004 }
John Bauman66b8ab22014-05-06 15:57:45 -04001005
Nicolas Capensf160b172014-11-26 11:58:23 -05001006 if(border != 0)
1007 {
1008 return error(GL_INVALID_VALUE);
1009 }
John Bauman66b8ab22014-05-06 15:57:45 -04001010
Nicolas Capensf160b172014-11-26 11:58:23 -05001011 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001012
Nicolas Capensf160b172014-11-26 11:58:23 -05001013 if(context)
1014 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001015 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001016 {
1017 return error(GL_INVALID_VALUE);
1018 }
John Bauman66b8ab22014-05-06 15:57:45 -04001019
Nicolas Capensf160b172014-11-26 11:58:23 -05001020 switch(target)
1021 {
1022 case GL_TEXTURE_2D:
1023 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1024 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
1025 {
1026 return error(GL_INVALID_VALUE);
1027 }
1028 break;
1029 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1030 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1031 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1032 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1033 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1034 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1035 if(width != height)
1036 {
1037 return error(GL_INVALID_VALUE);
1038 }
John Bauman66b8ab22014-05-06 15:57:45 -04001039
Nicolas Capensf160b172014-11-26 11:58:23 -05001040 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1041 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1042 {
1043 return error(GL_INVALID_VALUE);
1044 }
1045 break;
1046 default:
1047 return error(GL_INVALID_ENUM);
1048 }
John Bauman66b8ab22014-05-06 15:57:45 -04001049
Nicolas Capensdeda34b2015-04-28 15:21:53 -07001050 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
Nicolas Capensf160b172014-11-26 11:58:23 -05001051 {
1052 return error(GL_INVALID_VALUE);
1053 }
John Bauman66b8ab22014-05-06 15:57:45 -04001054
Nicolas Capensf160b172014-11-26 11:58:23 -05001055 if(target == GL_TEXTURE_2D)
1056 {
1057 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001058
Nicolas Capensf160b172014-11-26 11:58:23 -05001059 if(!texture)
1060 {
1061 return error(GL_INVALID_OPERATION);
1062 }
John Bauman66b8ab22014-05-06 15:57:45 -04001063
Nicolas Capensf160b172014-11-26 11:58:23 -05001064 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
1065 }
1066 else
1067 {
1068 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001069
Nicolas Capensf160b172014-11-26 11:58:23 -05001070 if(!texture)
1071 {
1072 return error(GL_INVALID_OPERATION);
1073 }
John Bauman66b8ab22014-05-06 15:57:45 -04001074
Nicolas Capensf160b172014-11-26 11:58:23 -05001075 switch(target)
1076 {
1077 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1078 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1079 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1080 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1081 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1082 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1083 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
1084 break;
1085 default: UNREACHABLE();
1086 }
1087 }
1088 }
John Bauman66b8ab22014-05-06 15:57:45 -04001089}
1090
Nicolas Capenseb195b62015-04-28 17:18:42 -07001091void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
1092 GLenum format, GLsizei imageSize, const GLvoid* data)
John Bauman66b8ab22014-05-06 15:57:45 -04001093{
Nicolas Capensf160b172014-11-26 11:58:23 -05001094 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1095 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07001096 "GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05001097 target, level, xoffset, yoffset, width, height, format, imageSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04001098
Nicolas Capensf160b172014-11-26 11:58:23 -05001099 if(!es2::IsTextureTarget(target))
1100 {
1101 return error(GL_INVALID_ENUM);
1102 }
John Bauman66b8ab22014-05-06 15:57:45 -04001103
Nicolas Capensf160b172014-11-26 11:58:23 -05001104 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
1105 {
1106 return error(GL_INVALID_VALUE);
1107 }
John Bauman66b8ab22014-05-06 15:57:45 -04001108
Alexis Hetued306182015-04-02 12:02:28 -04001109 egl::GLint clientVersion = egl::getClientVersion();
1110
Nicolas Capensf160b172014-11-26 11:58:23 -05001111 switch(format)
1112 {
Nicolas Capens22658242014-11-29 00:31:41 -05001113 case GL_ETC1_RGB8_OES:
1114 break;
Alexis Hetued306182015-04-02 12:02:28 -04001115 case GL_COMPRESSED_R11_EAC:
1116 case GL_COMPRESSED_SIGNED_R11_EAC:
1117 case GL_COMPRESSED_RG11_EAC:
1118 case GL_COMPRESSED_SIGNED_RG11_EAC:
1119 case GL_COMPRESSED_RGB8_ETC2:
1120 case GL_COMPRESSED_SRGB8_ETC2:
1121 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1122 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1123 case GL_COMPRESSED_RGBA8_ETC2_EAC:
1124 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1125 if(clientVersion >= 3)
1126 {
1127 break;
1128 }
1129 return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05001130 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1131 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1132 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1133 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1134 if(!S3TC_SUPPORT)
1135 {
1136 return error(GL_INVALID_ENUM);
1137 }
1138 break;
1139 default:
1140 return error(GL_INVALID_ENUM);
1141 }
John Bauman66b8ab22014-05-06 15:57:45 -04001142
Nicolas Capensf160b172014-11-26 11:58:23 -05001143 if(width == 0 || height == 0 || data == NULL)
1144 {
1145 return;
1146 }
John Bauman66b8ab22014-05-06 15:57:45 -04001147
Nicolas Capensf160b172014-11-26 11:58:23 -05001148 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001149
Nicolas Capensf160b172014-11-26 11:58:23 -05001150 if(context)
1151 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001152 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001153 {
1154 return error(GL_INVALID_VALUE);
1155 }
John Bauman66b8ab22014-05-06 15:57:45 -04001156
Nicolas Capensdeda34b2015-04-28 15:21:53 -07001157 if(imageSize != egl::ComputeCompressedSize(width, height, format))
Nicolas Capensf160b172014-11-26 11:58:23 -05001158 {
1159 return error(GL_INVALID_VALUE);
1160 }
John Bauman66b8ab22014-05-06 15:57:45 -04001161
Nicolas Capensf160b172014-11-26 11:58:23 -05001162 if(xoffset % 4 != 0 || yoffset % 4 != 0)
1163 {
1164 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
1165 return error(GL_INVALID_OPERATION);
1166 }
John Bauman66b8ab22014-05-06 15:57:45 -04001167
Nicolas Capensf160b172014-11-26 11:58:23 -05001168 if(target == GL_TEXTURE_2D)
1169 {
1170 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001171
Nicolas Capensf160b172014-11-26 11:58:23 -05001172 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
1173 {
1174 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
1175 }
1176 }
1177 else if(es2::IsCubemapTextureTarget(target))
1178 {
1179 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001180
Nicolas Capensf160b172014-11-26 11:58:23 -05001181 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
1182 {
1183 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
1184 }
1185 }
1186 else
1187 {
1188 UNREACHABLE();
1189 }
1190 }
John Bauman66b8ab22014-05-06 15:57:45 -04001191}
1192
Nicolas Capenseb195b62015-04-28 17:18:42 -07001193void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
John Bauman66b8ab22014-05-06 15:57:45 -04001194{
Nicolas Capensf160b172014-11-26 11:58:23 -05001195 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
1196 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
1197 target, level, internalformat, x, y, width, height, border);
John Bauman66b8ab22014-05-06 15:57:45 -04001198
Nicolas Capensf160b172014-11-26 11:58:23 -05001199 if(!validImageSize(level, width, height))
1200 {
1201 return error(GL_INVALID_VALUE);
1202 }
John Bauman66b8ab22014-05-06 15:57:45 -04001203
Nicolas Capensf160b172014-11-26 11:58:23 -05001204 if(border != 0)
1205 {
1206 return error(GL_INVALID_VALUE);
1207 }
John Bauman66b8ab22014-05-06 15:57:45 -04001208
Nicolas Capensf160b172014-11-26 11:58:23 -05001209 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001210
Nicolas Capensf160b172014-11-26 11:58:23 -05001211 if(context)
1212 {
1213 switch(target)
1214 {
1215 case GL_TEXTURE_2D:
1216 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1217 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
1218 {
1219 return error(GL_INVALID_VALUE);
1220 }
1221 break;
1222 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1223 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1224 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1225 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1226 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1227 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1228 if(width != height)
1229 {
1230 return error(GL_INVALID_VALUE);
1231 }
John Bauman66b8ab22014-05-06 15:57:45 -04001232
Nicolas Capensf160b172014-11-26 11:58:23 -05001233 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1234 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1235 {
1236 return error(GL_INVALID_VALUE);
1237 }
1238 break;
1239 default:
1240 return error(GL_INVALID_ENUM);
1241 }
John Bauman66b8ab22014-05-06 15:57:45 -04001242
Nicolas Capensf160b172014-11-26 11:58:23 -05001243 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
John Bauman66b8ab22014-05-06 15:57:45 -04001244
Nicolas Capensf160b172014-11-26 11:58:23 -05001245 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1246 {
1247 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1248 }
John Bauman66b8ab22014-05-06 15:57:45 -04001249
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001250 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capensf160b172014-11-26 11:58:23 -05001251 {
1252 return error(GL_INVALID_OPERATION);
1253 }
John Bauman66b8ab22014-05-06 15:57:45 -04001254
Nicolas Capensf160b172014-11-26 11:58:23 -05001255 es2::Renderbuffer *source = framebuffer->getColorbuffer();
1256 GLenum colorbufferFormat = source->getFormat();
John Bauman66b8ab22014-05-06 15:57:45 -04001257
Alexis Hetub027aa92015-01-19 15:56:12 -05001258 if(!validateColorBufferFormat(internalformat, colorbufferFormat))
Nicolas Capensf160b172014-11-26 11:58:23 -05001259 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001260 return;
Nicolas Capensf160b172014-11-26 11:58:23 -05001261 }
John Bauman66b8ab22014-05-06 15:57:45 -04001262
Nicolas Capensf160b172014-11-26 11:58:23 -05001263 if(target == GL_TEXTURE_2D)
1264 {
1265 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001266
Nicolas Capensf160b172014-11-26 11:58:23 -05001267 if(!texture)
1268 {
1269 return error(GL_INVALID_OPERATION);
1270 }
John Bauman66b8ab22014-05-06 15:57:45 -04001271
Nicolas Capensf160b172014-11-26 11:58:23 -05001272 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1273 }
1274 else if(es2::IsCubemapTextureTarget(target))
1275 {
1276 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001277
Nicolas Capensf160b172014-11-26 11:58:23 -05001278 if(!texture)
1279 {
1280 return error(GL_INVALID_OPERATION);
1281 }
John Bauman66b8ab22014-05-06 15:57:45 -04001282
Nicolas Capensf160b172014-11-26 11:58:23 -05001283 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1284 }
1285 else UNREACHABLE();
1286 }
John Bauman66b8ab22014-05-06 15:57:45 -04001287}
1288
Nicolas Capenseb195b62015-04-28 17:18:42 -07001289void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04001290{
Nicolas Capensf160b172014-11-26 11:58:23 -05001291 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1292 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1293 target, level, xoffset, yoffset, x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04001294
Nicolas Capensf160b172014-11-26 11:58:23 -05001295 if(!es2::IsTextureTarget(target))
1296 {
1297 return error(GL_INVALID_ENUM);
1298 }
John Bauman66b8ab22014-05-06 15:57:45 -04001299
Nicolas Capensf160b172014-11-26 11:58:23 -05001300 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1301 {
1302 return error(GL_INVALID_VALUE);
1303 }
John Bauman66b8ab22014-05-06 15:57:45 -04001304
Nicolas Capensf160b172014-11-26 11:58:23 -05001305 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1306 {
1307 return error(GL_INVALID_VALUE);
1308 }
John Bauman66b8ab22014-05-06 15:57:45 -04001309
Nicolas Capensf160b172014-11-26 11:58:23 -05001310 if(width == 0 || height == 0)
1311 {
1312 return;
1313 }
John Bauman66b8ab22014-05-06 15:57:45 -04001314
Nicolas Capensf160b172014-11-26 11:58:23 -05001315 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001316
Nicolas Capensf160b172014-11-26 11:58:23 -05001317 if(context)
1318 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001319 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001320 {
1321 return error(GL_INVALID_VALUE);
1322 }
John Bauman66b8ab22014-05-06 15:57:45 -04001323
Nicolas Capensf160b172014-11-26 11:58:23 -05001324 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
John Bauman66b8ab22014-05-06 15:57:45 -04001325
Nicolas Capensf160b172014-11-26 11:58:23 -05001326 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1327 {
1328 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1329 }
John Bauman66b8ab22014-05-06 15:57:45 -04001330
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001331 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capensf160b172014-11-26 11:58:23 -05001332 {
1333 return error(GL_INVALID_OPERATION);
1334 }
John Bauman66b8ab22014-05-06 15:57:45 -04001335
Nicolas Capensf160b172014-11-26 11:58:23 -05001336 es2::Renderbuffer *source = framebuffer->getColorbuffer();
1337 GLenum colorbufferFormat = source->getFormat();
1338 es2::Texture *texture = NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04001339
Nicolas Capensf160b172014-11-26 11:58:23 -05001340 if(target == GL_TEXTURE_2D)
1341 {
1342 texture = context->getTexture2D();
1343 }
1344 else if(es2::IsCubemapTextureTarget(target))
1345 {
1346 texture = context->getTextureCubeMap();
1347 }
1348 else UNREACHABLE();
John Bauman66b8ab22014-05-06 15:57:45 -04001349
Nicolas Capensf160b172014-11-26 11:58:23 -05001350 if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
1351 {
1352 return;
1353 }
1354
1355 GLenum textureFormat = texture->getFormat(target, level);
1356
Alexis Hetub027aa92015-01-19 15:56:12 -05001357 if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
Nicolas Capensf160b172014-11-26 11:58:23 -05001358 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001359 return;
Nicolas Capensf160b172014-11-26 11:58:23 -05001360 }
John Bauman66b8ab22014-05-06 15:57:45 -04001361
Alexis Hetub027aa92015-01-19 15:56:12 -05001362 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
Nicolas Capensf160b172014-11-26 11:58:23 -05001363 }
John Bauman66b8ab22014-05-06 15:57:45 -04001364}
1365
Nicolas Capenseb195b62015-04-28 17:18:42 -07001366GLuint CreateProgram(void)
John Bauman66b8ab22014-05-06 15:57:45 -04001367{
Nicolas Capensf160b172014-11-26 11:58:23 -05001368 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04001369
Nicolas Capensf160b172014-11-26 11:58:23 -05001370 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001371
Nicolas Capensf160b172014-11-26 11:58:23 -05001372 if(context)
1373 {
1374 return context->createProgram();
1375 }
John Bauman66b8ab22014-05-06 15:57:45 -04001376
Nicolas Capensf160b172014-11-26 11:58:23 -05001377 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -04001378}
1379
Nicolas Capenseb195b62015-04-28 17:18:42 -07001380GLuint CreateShader(GLenum type)
John Bauman66b8ab22014-05-06 15:57:45 -04001381{
Nicolas Capensf160b172014-11-26 11:58:23 -05001382 TRACE("(GLenum type = 0x%X)", type);
John Bauman66b8ab22014-05-06 15:57:45 -04001383
Nicolas Capensf160b172014-11-26 11:58:23 -05001384 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001385
Nicolas Capensf160b172014-11-26 11:58:23 -05001386 if(context)
1387 {
1388 switch(type)
1389 {
1390 case GL_FRAGMENT_SHADER:
1391 case GL_VERTEX_SHADER:
1392 return context->createShader(type);
1393 default:
1394 return error(GL_INVALID_ENUM, 0);
1395 }
1396 }
John Bauman66b8ab22014-05-06 15:57:45 -04001397
Nicolas Capensf160b172014-11-26 11:58:23 -05001398 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -04001399}
1400
Nicolas Capenseb195b62015-04-28 17:18:42 -07001401void CullFace(GLenum mode)
John Bauman66b8ab22014-05-06 15:57:45 -04001402{
Nicolas Capensf160b172014-11-26 11:58:23 -05001403 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04001404
Nicolas Capensf160b172014-11-26 11:58:23 -05001405 switch(mode)
1406 {
1407 case GL_FRONT:
1408 case GL_BACK:
1409 case GL_FRONT_AND_BACK:
1410 {
1411 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001412
Nicolas Capensf160b172014-11-26 11:58:23 -05001413 if(context)
1414 {
1415 context->setCullMode(mode);
1416 }
1417 }
1418 break;
1419 default:
1420 return error(GL_INVALID_ENUM);
1421 }
John Bauman66b8ab22014-05-06 15:57:45 -04001422}
1423
Nicolas Capenseb195b62015-04-28 17:18:42 -07001424void DeleteBuffers(GLsizei n, const GLuint* buffers)
John Bauman66b8ab22014-05-06 15:57:45 -04001425{
Nicolas Capens4be33702015-04-28 15:13:30 -07001426 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001427
Nicolas Capensf160b172014-11-26 11:58:23 -05001428 if(n < 0)
1429 {
1430 return error(GL_INVALID_VALUE);
1431 }
John Bauman66b8ab22014-05-06 15:57:45 -04001432
Nicolas Capensf160b172014-11-26 11:58:23 -05001433 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001434
Nicolas Capensf160b172014-11-26 11:58:23 -05001435 if(context)
1436 {
1437 for(int i = 0; i < n; i++)
1438 {
1439 context->deleteBuffer(buffers[i]);
1440 }
1441 }
John Bauman66b8ab22014-05-06 15:57:45 -04001442}
1443
Nicolas Capenseb195b62015-04-28 17:18:42 -07001444void DeleteFencesNV(GLsizei n, const GLuint* fences)
John Bauman66b8ab22014-05-06 15:57:45 -04001445{
Nicolas Capens4be33702015-04-28 15:13:30 -07001446 TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04001447
Nicolas Capensf160b172014-11-26 11:58:23 -05001448 if(n < 0)
1449 {
1450 return error(GL_INVALID_VALUE);
1451 }
John Bauman66b8ab22014-05-06 15:57:45 -04001452
Nicolas Capensf160b172014-11-26 11:58:23 -05001453 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001454
Nicolas Capensf160b172014-11-26 11:58:23 -05001455 if(context)
1456 {
1457 for(int i = 0; i < n; i++)
1458 {
1459 context->deleteFence(fences[i]);
1460 }
1461 }
John Bauman66b8ab22014-05-06 15:57:45 -04001462}
1463
Nicolas Capenseb195b62015-04-28 17:18:42 -07001464void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
John Bauman66b8ab22014-05-06 15:57:45 -04001465{
Nicolas Capens4be33702015-04-28 15:13:30 -07001466 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001467
Nicolas Capensf160b172014-11-26 11:58:23 -05001468 if(n < 0)
1469 {
1470 return error(GL_INVALID_VALUE);
1471 }
John Bauman66b8ab22014-05-06 15:57:45 -04001472
Nicolas Capensf160b172014-11-26 11:58:23 -05001473 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001474
Nicolas Capensf160b172014-11-26 11:58:23 -05001475 if(context)
1476 {
1477 for(int i = 0; i < n; i++)
1478 {
1479 if(framebuffers[i] != 0)
1480 {
1481 context->deleteFramebuffer(framebuffers[i]);
1482 }
1483 }
1484 }
John Bauman66b8ab22014-05-06 15:57:45 -04001485}
1486
Nicolas Capenseb195b62015-04-28 17:18:42 -07001487void DeleteProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04001488{
Nicolas Capensf160b172014-11-26 11:58:23 -05001489 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04001490
Nicolas Capensf160b172014-11-26 11:58:23 -05001491 if(program == 0)
1492 {
1493 return;
1494 }
John Bauman66b8ab22014-05-06 15:57:45 -04001495
Nicolas Capensf160b172014-11-26 11:58:23 -05001496 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001497
Nicolas Capensf160b172014-11-26 11:58:23 -05001498 if(context)
1499 {
1500 if(!context->getProgram(program))
1501 {
1502 if(context->getShader(program))
1503 {
1504 return error(GL_INVALID_OPERATION);
1505 }
1506 else
1507 {
1508 return error(GL_INVALID_VALUE);
1509 }
1510 }
John Bauman66b8ab22014-05-06 15:57:45 -04001511
Nicolas Capensf160b172014-11-26 11:58:23 -05001512 context->deleteProgram(program);
1513 }
John Bauman66b8ab22014-05-06 15:57:45 -04001514}
1515
Nicolas Capenseb195b62015-04-28 17:18:42 -07001516void DeleteQueriesEXT(GLsizei n, const GLuint *ids)
John Bauman66b8ab22014-05-06 15:57:45 -04001517{
Nicolas Capens4be33702015-04-28 15:13:30 -07001518 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04001519
Nicolas Capensf160b172014-11-26 11:58:23 -05001520 if(n < 0)
1521 {
1522 return error(GL_INVALID_VALUE);
1523 }
John Bauman66b8ab22014-05-06 15:57:45 -04001524
Nicolas Capensf160b172014-11-26 11:58:23 -05001525 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001526
Nicolas Capensf160b172014-11-26 11:58:23 -05001527 if(context)
1528 {
1529 for(int i = 0; i < n; i++)
1530 {
1531 context->deleteQuery(ids[i]);
1532 }
1533 }
John Bauman66b8ab22014-05-06 15:57:45 -04001534}
1535
Nicolas Capenseb195b62015-04-28 17:18:42 -07001536void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
John Bauman66b8ab22014-05-06 15:57:45 -04001537{
Nicolas Capens4be33702015-04-28 15:13:30 -07001538 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001539
Nicolas Capensf160b172014-11-26 11:58:23 -05001540 if(n < 0)
1541 {
1542 return error(GL_INVALID_VALUE);
1543 }
John Bauman66b8ab22014-05-06 15:57:45 -04001544
Nicolas Capensf160b172014-11-26 11:58:23 -05001545 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001546
Nicolas Capensf160b172014-11-26 11:58:23 -05001547 if(context)
1548 {
1549 for(int i = 0; i < n; i++)
1550 {
1551 context->deleteRenderbuffer(renderbuffers[i]);
1552 }
1553 }
John Bauman66b8ab22014-05-06 15:57:45 -04001554}
1555
Nicolas Capenseb195b62015-04-28 17:18:42 -07001556void DeleteShader(GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -04001557{
Nicolas Capensf160b172014-11-26 11:58:23 -05001558 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04001559
Nicolas Capensf160b172014-11-26 11:58:23 -05001560 if(shader == 0)
1561 {
1562 return;
1563 }
John Bauman66b8ab22014-05-06 15:57:45 -04001564
Nicolas Capensf160b172014-11-26 11:58:23 -05001565 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001566
Nicolas Capensf160b172014-11-26 11:58:23 -05001567 if(context)
1568 {
1569 if(!context->getShader(shader))
1570 {
1571 if(context->getProgram(shader))
1572 {
1573 return error(GL_INVALID_OPERATION);
1574 }
1575 else
1576 {
1577 return error(GL_INVALID_VALUE);
1578 }
1579 }
John Bauman66b8ab22014-05-06 15:57:45 -04001580
Nicolas Capensf160b172014-11-26 11:58:23 -05001581 context->deleteShader(shader);
1582 }
John Bauman66b8ab22014-05-06 15:57:45 -04001583}
1584
Nicolas Capenseb195b62015-04-28 17:18:42 -07001585void DeleteTextures(GLsizei n, const GLuint* textures)
John Bauman66b8ab22014-05-06 15:57:45 -04001586{
Nicolas Capens4be33702015-04-28 15:13:30 -07001587 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04001588
Nicolas Capensf160b172014-11-26 11:58:23 -05001589 if(n < 0)
1590 {
1591 return error(GL_INVALID_VALUE);
1592 }
John Bauman66b8ab22014-05-06 15:57:45 -04001593
Nicolas Capensf160b172014-11-26 11:58:23 -05001594 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001595
Nicolas Capensf160b172014-11-26 11:58:23 -05001596 if(context)
1597 {
1598 for(int i = 0; i < n; i++)
1599 {
1600 if(textures[i] != 0)
1601 {
1602 context->deleteTexture(textures[i]);
1603 }
1604 }
1605 }
John Bauman66b8ab22014-05-06 15:57:45 -04001606}
1607
Nicolas Capenseb195b62015-04-28 17:18:42 -07001608void DepthFunc(GLenum func)
John Bauman66b8ab22014-05-06 15:57:45 -04001609{
Nicolas Capensf160b172014-11-26 11:58:23 -05001610 TRACE("(GLenum func = 0x%X)", func);
John Bauman66b8ab22014-05-06 15:57:45 -04001611
Nicolas Capensf160b172014-11-26 11:58:23 -05001612 switch(func)
1613 {
1614 case GL_NEVER:
1615 case GL_ALWAYS:
1616 case GL_LESS:
1617 case GL_LEQUAL:
1618 case GL_EQUAL:
1619 case GL_GREATER:
1620 case GL_GEQUAL:
1621 case GL_NOTEQUAL:
1622 break;
1623 default:
1624 return error(GL_INVALID_ENUM);
1625 }
John Bauman66b8ab22014-05-06 15:57:45 -04001626
Nicolas Capensf160b172014-11-26 11:58:23 -05001627 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001628
Nicolas Capensf160b172014-11-26 11:58:23 -05001629 if(context)
1630 {
1631 context->setDepthFunc(func);
1632 }
John Bauman66b8ab22014-05-06 15:57:45 -04001633}
1634
Nicolas Capenseb195b62015-04-28 17:18:42 -07001635void DepthMask(GLboolean flag)
John Bauman66b8ab22014-05-06 15:57:45 -04001636{
Nicolas Capensf160b172014-11-26 11:58:23 -05001637 TRACE("(GLboolean flag = %d)", flag);
John Bauman66b8ab22014-05-06 15:57:45 -04001638
Nicolas Capensf160b172014-11-26 11:58:23 -05001639 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001640
Nicolas Capensf160b172014-11-26 11:58:23 -05001641 if(context)
1642 {
1643 context->setDepthMask(flag != GL_FALSE);
1644 }
John Bauman66b8ab22014-05-06 15:57:45 -04001645}
1646
Nicolas Capenseb195b62015-04-28 17:18:42 -07001647void DepthRangef(GLclampf zNear, GLclampf zFar)
John Bauman66b8ab22014-05-06 15:57:45 -04001648{
Nicolas Capensf160b172014-11-26 11:58:23 -05001649 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
John Bauman66b8ab22014-05-06 15:57:45 -04001650
Nicolas Capensf160b172014-11-26 11:58:23 -05001651 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001652
Nicolas Capensf160b172014-11-26 11:58:23 -05001653 if(context)
1654 {
1655 context->setDepthRange(zNear, zFar);
1656 }
John Bauman66b8ab22014-05-06 15:57:45 -04001657}
1658
Nicolas Capenseb195b62015-04-28 17:18:42 -07001659void DetachShader(GLuint program, GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -04001660{
Nicolas Capensf160b172014-11-26 11:58:23 -05001661 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
John Bauman66b8ab22014-05-06 15:57:45 -04001662
Nicolas Capensf160b172014-11-26 11:58:23 -05001663 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001664
Nicolas Capensf160b172014-11-26 11:58:23 -05001665 if(context)
1666 {
John Bauman66b8ab22014-05-06 15:57:45 -04001667
Nicolas Capensf160b172014-11-26 11:58:23 -05001668 es2::Program *programObject = context->getProgram(program);
1669 es2::Shader *shaderObject = context->getShader(shader);
Nicolas Capens08e90f02014-11-21 12:49:12 -05001670
Nicolas Capensf160b172014-11-26 11:58:23 -05001671 if(!programObject)
1672 {
1673 es2::Shader *shaderByProgramHandle;
1674 shaderByProgramHandle = context->getShader(program);
1675 if(!shaderByProgramHandle)
1676 {
1677 return error(GL_INVALID_VALUE);
1678 }
1679 else
1680 {
1681 return error(GL_INVALID_OPERATION);
1682 }
1683 }
John Bauman66b8ab22014-05-06 15:57:45 -04001684
Nicolas Capensf160b172014-11-26 11:58:23 -05001685 if(!shaderObject)
1686 {
1687 es2::Program *programByShaderHandle = context->getProgram(shader);
1688 if(!programByShaderHandle)
1689 {
1690 return error(GL_INVALID_VALUE);
1691 }
1692 else
1693 {
1694 return error(GL_INVALID_OPERATION);
1695 }
1696 }
John Bauman66b8ab22014-05-06 15:57:45 -04001697
Nicolas Capensf160b172014-11-26 11:58:23 -05001698 if(!programObject->detachShader(shaderObject))
1699 {
1700 return error(GL_INVALID_OPERATION);
1701 }
1702 }
John Bauman66b8ab22014-05-06 15:57:45 -04001703}
1704
Nicolas Capenseb195b62015-04-28 17:18:42 -07001705void Disable(GLenum cap)
John Bauman66b8ab22014-05-06 15:57:45 -04001706{
Nicolas Capensf160b172014-11-26 11:58:23 -05001707 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04001708
Nicolas Capensf160b172014-11-26 11:58:23 -05001709 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001710
Nicolas Capensf160b172014-11-26 11:58:23 -05001711 if(context)
1712 {
1713 switch(cap)
1714 {
1715 case GL_CULL_FACE: context->setCullFace(false); break;
1716 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1717 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1718 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1719 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1720 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1721 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1722 case GL_BLEND: context->setBlend(false); break;
1723 case GL_DITHER: context->setDither(false); break;
Alexis Hetufceb1832015-03-10 16:42:04 -04001724 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndex(false); break;
1725 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscard(false); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05001726 default:
1727 return error(GL_INVALID_ENUM);
1728 }
1729 }
John Bauman66b8ab22014-05-06 15:57:45 -04001730}
1731
Nicolas Capenseb195b62015-04-28 17:18:42 -07001732void DisableVertexAttribArray(GLuint index)
John Bauman66b8ab22014-05-06 15:57:45 -04001733{
Nicolas Capensf160b172014-11-26 11:58:23 -05001734 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04001735
Nicolas Capensf160b172014-11-26 11:58:23 -05001736 if(index >= es2::MAX_VERTEX_ATTRIBS)
1737 {
1738 return error(GL_INVALID_VALUE);
1739 }
John Bauman66b8ab22014-05-06 15:57:45 -04001740
Nicolas Capensf160b172014-11-26 11:58:23 -05001741 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001742
Nicolas Capensf160b172014-11-26 11:58:23 -05001743 if(context)
1744 {
1745 context->setEnableVertexAttribArray(index, false);
1746 }
John Bauman66b8ab22014-05-06 15:57:45 -04001747}
1748
Nicolas Capenseb195b62015-04-28 17:18:42 -07001749void DrawArrays(GLenum mode, GLint first, GLsizei count)
John Bauman66b8ab22014-05-06 15:57:45 -04001750{
Nicolas Capensf160b172014-11-26 11:58:23 -05001751 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
John Bauman66b8ab22014-05-06 15:57:45 -04001752
Alexis Hetued306182015-04-02 12:02:28 -04001753 switch(mode)
1754 {
1755 case GL_POINTS:
1756 case GL_LINES:
1757 case GL_LINE_LOOP:
1758 case GL_LINE_STRIP:
1759 case GL_TRIANGLES:
1760 case GL_TRIANGLE_FAN:
1761 case GL_TRIANGLE_STRIP:
1762 break;
1763 default:
1764 return error(GL_INVALID_ENUM);
1765 }
1766
Nicolas Capensf160b172014-11-26 11:58:23 -05001767 if(count < 0 || first < 0)
1768 {
1769 return error(GL_INVALID_VALUE);
1770 }
John Bauman66b8ab22014-05-06 15:57:45 -04001771
Nicolas Capensf160b172014-11-26 11:58:23 -05001772 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001773
Nicolas Capensf160b172014-11-26 11:58:23 -05001774 if(context)
1775 {
Alexis Hetubcac6ff2015-04-22 08:29:22 -04001776 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1777 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1778 {
1779 return error(GL_INVALID_OPERATION);
1780 }
1781
Nicolas Capensf160b172014-11-26 11:58:23 -05001782 context->drawArrays(mode, first, count);
1783 }
John Bauman66b8ab22014-05-06 15:57:45 -04001784}
1785
Nicolas Capenseb195b62015-04-28 17:18:42 -07001786void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
John Bauman66b8ab22014-05-06 15:57:45 -04001787{
Nicolas Capens4be33702015-04-28 15:13:30 -07001788 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05001789 mode, count, type, indices);
John Bauman66b8ab22014-05-06 15:57:45 -04001790
Alexis Hetued306182015-04-02 12:02:28 -04001791 switch(mode)
1792 {
1793 case GL_POINTS:
1794 case GL_LINES:
1795 case GL_LINE_LOOP:
1796 case GL_LINE_STRIP:
1797 case GL_TRIANGLES:
1798 case GL_TRIANGLE_FAN:
1799 case GL_TRIANGLE_STRIP:
1800 break;
1801 default:
1802 return error(GL_INVALID_ENUM);
1803 }
1804
Nicolas Capensf160b172014-11-26 11:58:23 -05001805 if(count < 0)
1806 {
1807 return error(GL_INVALID_VALUE);
1808 }
John Bauman66b8ab22014-05-06 15:57:45 -04001809
Nicolas Capensf160b172014-11-26 11:58:23 -05001810 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001811
Nicolas Capensf160b172014-11-26 11:58:23 -05001812 if(context)
1813 {
Alexis Hetubcac6ff2015-04-22 08:29:22 -04001814 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1815 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1816 {
1817 return error(GL_INVALID_OPERATION);
1818 }
1819
Nicolas Capensf160b172014-11-26 11:58:23 -05001820 switch(type)
1821 {
1822 case GL_UNSIGNED_BYTE:
1823 case GL_UNSIGNED_SHORT:
1824 case GL_UNSIGNED_INT:
1825 break;
1826 default:
1827 return error(GL_INVALID_ENUM);
1828 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05001829
Nicolas Capens22d07662015-04-25 11:34:50 -07001830 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices);
Nicolas Capensf160b172014-11-26 11:58:23 -05001831 }
John Bauman66b8ab22014-05-06 15:57:45 -04001832}
1833
Nicolas Capenseb195b62015-04-28 17:18:42 -07001834void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Alexis Hetue8af6d12015-04-17 16:58:45 -04001835{
1836 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1837 mode, first, count, instanceCount);
1838
1839 switch(mode)
1840 {
1841 case GL_POINTS:
1842 case GL_LINES:
1843 case GL_LINE_LOOP:
1844 case GL_LINE_STRIP:
1845 case GL_TRIANGLES:
1846 case GL_TRIANGLE_FAN:
1847 case GL_TRIANGLE_STRIP:
1848 break;
1849 default:
1850 return error(GL_INVALID_ENUM);
1851 }
1852
1853 if(count < 0 || instanceCount < 0)
1854 {
1855 return error(GL_INVALID_VALUE);
1856 }
1857
1858 es2::Context *context = es2::getContext();
1859
1860 if(context)
1861 {
1862 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1863 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1864 {
1865 return error(GL_INVALID_OPERATION);
1866 }
1867
1868 context->drawArrays(mode, first, count, instanceCount);
1869 }
1870}
1871
Nicolas Capenseb195b62015-04-28 17:18:42 -07001872void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
Alexis Hetue8af6d12015-04-17 16:58:45 -04001873{
Nicolas Capens4be33702015-04-28 15:13:30 -07001874 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
Alexis Hetue8af6d12015-04-17 16:58:45 -04001875 mode, count, type, indices, instanceCount);
1876
1877 switch(mode)
1878 {
1879 case GL_POINTS:
1880 case GL_LINES:
1881 case GL_LINE_LOOP:
1882 case GL_LINE_STRIP:
1883 case GL_TRIANGLES:
1884 case GL_TRIANGLE_FAN:
1885 case GL_TRIANGLE_STRIP:
1886 break;
1887 default:
1888 return error(GL_INVALID_ENUM);
1889 }
1890
1891 switch(type)
1892 {
1893 case GL_UNSIGNED_BYTE:
1894 case GL_UNSIGNED_SHORT:
1895 case GL_UNSIGNED_INT:
1896 break;
1897 default:
1898 return error(GL_INVALID_ENUM);
1899 }
1900
1901 if(count < 0 || instanceCount < 0)
1902 {
1903 return error(GL_INVALID_VALUE);
1904 }
1905
1906 es2::Context *context = es2::getContext();
1907
1908 if(context)
1909 {
1910 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1911 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1912 {
1913 return error(GL_INVALID_OPERATION);
1914 }
1915
Nicolas Capens22d07662015-04-25 11:34:50 -07001916 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
Alexis Hetue8af6d12015-04-17 16:58:45 -04001917 }
1918}
1919
Nicolas Capenseb195b62015-04-28 17:18:42 -07001920void VertexAttribDivisorEXT(GLuint index, GLuint divisor)
Alexis Hetue8af6d12015-04-17 16:58:45 -04001921{
1922 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1923
1924 es2::Context *context = es2::getContext();
1925
1926 if(context)
1927 {
1928 if(index >= es2::MAX_VERTEX_ATTRIBS)
1929 {
1930 return error(GL_INVALID_VALUE);
1931 }
1932
1933 context->setVertexAttribDivisor(index, divisor);
1934 }
1935}
1936
Nicolas Capenseb195b62015-04-28 17:18:42 -07001937void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Alexis Hetub4d557d2015-04-24 17:25:10 -04001938{
1939 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1940 mode, first, count, instanceCount);
1941
1942 switch(mode)
1943 {
1944 case GL_POINTS:
1945 case GL_LINES:
1946 case GL_LINE_LOOP:
1947 case GL_LINE_STRIP:
1948 case GL_TRIANGLES:
1949 case GL_TRIANGLE_FAN:
1950 case GL_TRIANGLE_STRIP:
1951 break;
1952 default:
1953 return error(GL_INVALID_ENUM);
1954 }
1955
1956 if(count < 0 || instanceCount < 0)
1957 {
1958 return error(GL_INVALID_VALUE);
1959 }
1960
1961 es2::Context *context = es2::getContext();
1962
1963 if(context)
1964 {
1965 if(!context->hasZeroDivisor())
1966 {
1967 return error(GL_INVALID_OPERATION);
1968 }
1969
1970 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1971 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1972 {
1973 return error(GL_INVALID_OPERATION);
1974 }
1975
1976 context->drawArrays(mode, first, count, instanceCount);
1977 }
1978}
1979
Nicolas Capenseb195b62015-04-28 17:18:42 -07001980void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
Alexis Hetub4d557d2015-04-24 17:25:10 -04001981{
Nicolas Capens4be33702015-04-28 15:13:30 -07001982 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
Alexis Hetub4d557d2015-04-24 17:25:10 -04001983 mode, count, type, indices, instanceCount);
1984
1985 switch(mode)
1986 {
1987 case GL_POINTS:
1988 case GL_LINES:
1989 case GL_LINE_LOOP:
1990 case GL_LINE_STRIP:
1991 case GL_TRIANGLES:
1992 case GL_TRIANGLE_FAN:
1993 case GL_TRIANGLE_STRIP:
1994 break;
1995 default:
1996 return error(GL_INVALID_ENUM);
1997 }
1998
1999 switch(type)
2000 {
2001 case GL_UNSIGNED_BYTE:
2002 case GL_UNSIGNED_SHORT:
2003 case GL_UNSIGNED_INT:
2004 break;
2005 default:
2006 return error(GL_INVALID_ENUM);
2007 }
2008
2009 if(count < 0 || instanceCount < 0)
2010 {
2011 return error(GL_INVALID_VALUE);
2012 }
2013
2014 es2::Context *context = es2::getContext();
2015
2016 if(context)
2017 {
2018 if(!context->hasZeroDivisor())
2019 {
2020 return error(GL_INVALID_OPERATION);
2021 }
2022
2023 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
2024 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
2025 {
2026 return error(GL_INVALID_OPERATION);
2027 }
2028
Nicolas Capens0416e5c2015-04-28 15:30:28 -07002029 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
Alexis Hetub4d557d2015-04-24 17:25:10 -04002030 }
2031}
2032
Nicolas Capenseb195b62015-04-28 17:18:42 -07002033void VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
Alexis Hetub4d557d2015-04-24 17:25:10 -04002034{
2035 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
2036
2037 es2::Context *context = es2::getContext();
2038
2039 if(context)
2040 {
2041 if(index >= MAX_VERTEX_ATTRIBS)
2042 {
2043 return error(GL_INVALID_VALUE);
2044 }
2045
2046 context->setVertexAttribDivisor(index, divisor);
2047 }
2048}
2049
Nicolas Capenseb195b62015-04-28 17:18:42 -07002050void Enable(GLenum cap)
John Bauman66b8ab22014-05-06 15:57:45 -04002051{
Nicolas Capensf160b172014-11-26 11:58:23 -05002052 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04002053
Nicolas Capensf160b172014-11-26 11:58:23 -05002054 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002055
Nicolas Capensf160b172014-11-26 11:58:23 -05002056 if(context)
2057 {
2058 switch(cap)
2059 {
2060 case GL_CULL_FACE: context->setCullFace(true); break;
2061 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
2062 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
2063 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
2064 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
2065 case GL_STENCIL_TEST: context->setStencilTest(true); break;
2066 case GL_DEPTH_TEST: context->setDepthTest(true); break;
2067 case GL_BLEND: context->setBlend(true); break;
2068 case GL_DITHER: context->setDither(true); break;
Alexis Hetufceb1832015-03-10 16:42:04 -04002069 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndex(true); break;
2070 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscard(true); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05002071 default:
2072 return error(GL_INVALID_ENUM);
2073 }
2074 }
John Bauman66b8ab22014-05-06 15:57:45 -04002075}
2076
Nicolas Capenseb195b62015-04-28 17:18:42 -07002077void EnableVertexAttribArray(GLuint index)
John Bauman66b8ab22014-05-06 15:57:45 -04002078{
Nicolas Capensf160b172014-11-26 11:58:23 -05002079 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04002080
Nicolas Capensf160b172014-11-26 11:58:23 -05002081 if(index >= es2::MAX_VERTEX_ATTRIBS)
2082 {
2083 return error(GL_INVALID_VALUE);
2084 }
John Bauman66b8ab22014-05-06 15:57:45 -04002085
Nicolas Capensf160b172014-11-26 11:58:23 -05002086 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002087
Nicolas Capensf160b172014-11-26 11:58:23 -05002088 if(context)
2089 {
2090 context->setEnableVertexAttribArray(index, true);
2091 }
John Bauman66b8ab22014-05-06 15:57:45 -04002092}
2093
Nicolas Capenseb195b62015-04-28 17:18:42 -07002094void EndQueryEXT(GLenum target)
John Bauman66b8ab22014-05-06 15:57:45 -04002095{
Nicolas Capensf160b172014-11-26 11:58:23 -05002096 TRACE("GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04002097
Nicolas Capensf160b172014-11-26 11:58:23 -05002098 switch(target)
2099 {
2100 case GL_ANY_SAMPLES_PASSED_EXT:
2101 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
2102 break;
2103 default:
2104 return error(GL_INVALID_ENUM);
2105 }
John Bauman66b8ab22014-05-06 15:57:45 -04002106
Nicolas Capensf160b172014-11-26 11:58:23 -05002107 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002108
Nicolas Capensf160b172014-11-26 11:58:23 -05002109 if(context)
2110 {
2111 context->endQuery(target);
2112 }
John Bauman66b8ab22014-05-06 15:57:45 -04002113}
2114
Nicolas Capenseb195b62015-04-28 17:18:42 -07002115void FinishFenceNV(GLuint fence)
John Bauman66b8ab22014-05-06 15:57:45 -04002116{
Nicolas Capensf160b172014-11-26 11:58:23 -05002117 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002118
Nicolas Capensf160b172014-11-26 11:58:23 -05002119 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002120
Nicolas Capensf160b172014-11-26 11:58:23 -05002121 if(context)
2122 {
2123 es2::Fence* fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002124
Nicolas Capensf160b172014-11-26 11:58:23 -05002125 if(fenceObject == NULL)
2126 {
2127 return error(GL_INVALID_OPERATION);
2128 }
John Bauman66b8ab22014-05-06 15:57:45 -04002129
Nicolas Capensf160b172014-11-26 11:58:23 -05002130 fenceObject->finishFence();
2131 }
John Bauman66b8ab22014-05-06 15:57:45 -04002132}
2133
Nicolas Capenseb195b62015-04-28 17:18:42 -07002134void Finish(void)
John Bauman66b8ab22014-05-06 15:57:45 -04002135{
Nicolas Capensf160b172014-11-26 11:58:23 -05002136 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002137
Nicolas Capensf160b172014-11-26 11:58:23 -05002138 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002139
Nicolas Capensf160b172014-11-26 11:58:23 -05002140 if(context)
2141 {
2142 context->finish();
2143 }
John Bauman66b8ab22014-05-06 15:57:45 -04002144}
2145
Nicolas Capenseb195b62015-04-28 17:18:42 -07002146void Flush(void)
John Bauman66b8ab22014-05-06 15:57:45 -04002147{
Nicolas Capensf160b172014-11-26 11:58:23 -05002148 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002149
Nicolas Capensf160b172014-11-26 11:58:23 -05002150 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002151
Nicolas Capensf160b172014-11-26 11:58:23 -05002152 if(context)
2153 {
2154 context->flush();
2155 }
John Bauman66b8ab22014-05-06 15:57:45 -04002156}
2157
Nicolas Capenseb195b62015-04-28 17:18:42 -07002158void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
John Bauman66b8ab22014-05-06 15:57:45 -04002159{
Nicolas Capensf160b172014-11-26 11:58:23 -05002160 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
2161 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04002162
Nicolas Capensf160b172014-11-26 11:58:23 -05002163 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
2164 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
2165 {
2166 return error(GL_INVALID_ENUM);
2167 }
John Bauman66b8ab22014-05-06 15:57:45 -04002168
Nicolas Capensf160b172014-11-26 11:58:23 -05002169 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002170
Nicolas Capensf160b172014-11-26 11:58:23 -05002171 if(context)
2172 {
2173 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002174 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002175 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2176 {
2177 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002178 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002179 }
2180 else
2181 {
2182 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002183 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002184 }
John Bauman66b8ab22014-05-06 15:57:45 -04002185
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002186 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capensf160b172014-11-26 11:58:23 -05002187 {
2188 return error(GL_INVALID_OPERATION);
2189 }
John Bauman66b8ab22014-05-06 15:57:45 -04002190
Nicolas Capensf160b172014-11-26 11:58:23 -05002191 switch(attachment)
2192 {
2193 case GL_COLOR_ATTACHMENT0:
2194 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2195 break;
2196 case GL_DEPTH_ATTACHMENT:
2197 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2198 break;
2199 case GL_STENCIL_ATTACHMENT:
2200 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2201 break;
2202 default:
2203 return error(GL_INVALID_ENUM);
2204 }
2205 }
John Bauman66b8ab22014-05-06 15:57:45 -04002206}
2207
Nicolas Capenseb195b62015-04-28 17:18:42 -07002208void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
John Bauman66b8ab22014-05-06 15:57:45 -04002209{
Nicolas Capensf160b172014-11-26 11:58:23 -05002210 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
2211 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
John Bauman66b8ab22014-05-06 15:57:45 -04002212
Nicolas Capensf160b172014-11-26 11:58:23 -05002213 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2214 {
2215 return error(GL_INVALID_ENUM);
2216 }
John Bauman66b8ab22014-05-06 15:57:45 -04002217
Nicolas Capensf160b172014-11-26 11:58:23 -05002218 switch(attachment)
2219 {
2220 case GL_COLOR_ATTACHMENT0:
2221 case GL_DEPTH_ATTACHMENT:
2222 case GL_STENCIL_ATTACHMENT:
2223 break;
2224 default:
2225 return error(GL_INVALID_ENUM);
2226 }
John Bauman66b8ab22014-05-06 15:57:45 -04002227
Nicolas Capensf160b172014-11-26 11:58:23 -05002228 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002229
Nicolas Capensf160b172014-11-26 11:58:23 -05002230 if(context)
2231 {
2232 if(texture == 0)
2233 {
2234 textarget = GL_NONE;
2235 }
2236 else
2237 {
2238 es2::Texture *tex = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04002239
Nicolas Capensf160b172014-11-26 11:58:23 -05002240 if(tex == NULL)
2241 {
2242 return error(GL_INVALID_OPERATION);
2243 }
John Bauman66b8ab22014-05-06 15:57:45 -04002244
Nicolas Capensf160b172014-11-26 11:58:23 -05002245 if(tex->isCompressed(textarget, level))
2246 {
2247 return error(GL_INVALID_OPERATION);
2248 }
John Bauman66b8ab22014-05-06 15:57:45 -04002249
Nicolas Capensf160b172014-11-26 11:58:23 -05002250 switch(textarget)
2251 {
2252 case GL_TEXTURE_2D:
2253 if(tex->getTarget() != GL_TEXTURE_2D)
2254 {
2255 return error(GL_INVALID_OPERATION);
2256 }
2257 break;
2258 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2259 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2260 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2261 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2262 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2263 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2264 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2265 {
2266 return error(GL_INVALID_OPERATION);
2267 }
2268 break;
2269 default:
2270 return error(GL_INVALID_ENUM);
2271 }
John Bauman66b8ab22014-05-06 15:57:45 -04002272
Nicolas Capensf160b172014-11-26 11:58:23 -05002273 if(level != 0)
2274 {
2275 return error(GL_INVALID_VALUE);
2276 }
2277 }
John Bauman66b8ab22014-05-06 15:57:45 -04002278
Nicolas Capensf160b172014-11-26 11:58:23 -05002279 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002280 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002281 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2282 {
2283 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002284 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002285 }
2286 else
2287 {
2288 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002289 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002290 }
John Bauman66b8ab22014-05-06 15:57:45 -04002291
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002292 if(framebufferName == 0 || !framebuffer)
Nicolas Capensf160b172014-11-26 11:58:23 -05002293 {
2294 return error(GL_INVALID_OPERATION);
2295 }
John Bauman66b8ab22014-05-06 15:57:45 -04002296
Nicolas Capensf160b172014-11-26 11:58:23 -05002297 switch(attachment)
2298 {
2299 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2300 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2301 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2302 }
2303 }
John Bauman66b8ab22014-05-06 15:57:45 -04002304}
2305
Nicolas Capenseb195b62015-04-28 17:18:42 -07002306void FrontFace(GLenum mode)
John Bauman66b8ab22014-05-06 15:57:45 -04002307{
Nicolas Capensf160b172014-11-26 11:58:23 -05002308 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04002309
Nicolas Capensf160b172014-11-26 11:58:23 -05002310 switch(mode)
2311 {
2312 case GL_CW:
2313 case GL_CCW:
2314 {
2315 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002316
Nicolas Capensf160b172014-11-26 11:58:23 -05002317 if(context)
2318 {
2319 context->setFrontFace(mode);
2320 }
2321 }
2322 break;
2323 default:
2324 return error(GL_INVALID_ENUM);
2325 }
John Bauman66b8ab22014-05-06 15:57:45 -04002326}
2327
Nicolas Capenseb195b62015-04-28 17:18:42 -07002328void GenBuffers(GLsizei n, GLuint* buffers)
John Bauman66b8ab22014-05-06 15:57:45 -04002329{
Nicolas Capens4be33702015-04-28 15:13:30 -07002330 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002331
Nicolas Capensf160b172014-11-26 11:58:23 -05002332 if(n < 0)
2333 {
2334 return error(GL_INVALID_VALUE);
2335 }
John Bauman66b8ab22014-05-06 15:57:45 -04002336
Nicolas Capensf160b172014-11-26 11:58:23 -05002337 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002338
Nicolas Capensf160b172014-11-26 11:58:23 -05002339 if(context)
2340 {
2341 for(int i = 0; i < n; i++)
2342 {
2343 buffers[i] = context->createBuffer();
2344 }
2345 }
John Bauman66b8ab22014-05-06 15:57:45 -04002346}
2347
Nicolas Capenseb195b62015-04-28 17:18:42 -07002348void GenerateMipmap(GLenum target)
John Bauman66b8ab22014-05-06 15:57:45 -04002349{
Nicolas Capensf160b172014-11-26 11:58:23 -05002350 TRACE("(GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04002351
Nicolas Capensf160b172014-11-26 11:58:23 -05002352 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002353
Nicolas Capensf160b172014-11-26 11:58:23 -05002354 if(context)
2355 {
Alexis Hetued306182015-04-02 12:02:28 -04002356 es2::Texture *texture = nullptr;
2357
2358 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04002359
Nicolas Capensf160b172014-11-26 11:58:23 -05002360 switch(target)
2361 {
2362 case GL_TEXTURE_2D:
2363 texture = context->getTexture2D();
2364 break;
2365 case GL_TEXTURE_CUBE_MAP:
2366 texture = context->getTextureCubeMap();
2367 break;
Alexis Hetued306182015-04-02 12:02:28 -04002368 case GL_TEXTURE_2D_ARRAY:
2369 if(clientVersion < 3)
2370 {
2371 return error(GL_INVALID_ENUM);
2372 }
2373 else
2374 {
2375 UNIMPLEMENTED();
2376 texture = context->getTexture3D();
2377 break;
2378 }
2379 case GL_TEXTURE_3D_OES:
2380 texture = context->getTexture3D();
2381 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05002382 default:
2383 return error(GL_INVALID_ENUM);
2384 }
John Bauman66b8ab22014-05-06 15:57:45 -04002385
Nicolas Capensf160b172014-11-26 11:58:23 -05002386 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2387 {
2388 return error(GL_INVALID_OPERATION);
2389 }
John Bauman66b8ab22014-05-06 15:57:45 -04002390
Nicolas Capensf160b172014-11-26 11:58:23 -05002391 texture->generateMipmaps();
2392 }
John Bauman66b8ab22014-05-06 15:57:45 -04002393}
2394
Nicolas Capenseb195b62015-04-28 17:18:42 -07002395void GenFencesNV(GLsizei n, GLuint* fences)
John Bauman66b8ab22014-05-06 15:57:45 -04002396{
Nicolas Capens4be33702015-04-28 15:13:30 -07002397 TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04002398
Nicolas Capensf160b172014-11-26 11:58:23 -05002399 if(n < 0)
2400 {
2401 return error(GL_INVALID_VALUE);
2402 }
John Bauman66b8ab22014-05-06 15:57:45 -04002403
Nicolas Capensf160b172014-11-26 11:58:23 -05002404 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002405
Nicolas Capensf160b172014-11-26 11:58:23 -05002406 if(context)
2407 {
2408 for(int i = 0; i < n; i++)
2409 {
2410 fences[i] = context->createFence();
2411 }
2412 }
John Bauman66b8ab22014-05-06 15:57:45 -04002413}
2414
Nicolas Capenseb195b62015-04-28 17:18:42 -07002415void GenFramebuffers(GLsizei n, GLuint* framebuffers)
John Bauman66b8ab22014-05-06 15:57:45 -04002416{
Nicolas Capens4be33702015-04-28 15:13:30 -07002417 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002418
Nicolas Capensf160b172014-11-26 11:58:23 -05002419 if(n < 0)
2420 {
2421 return error(GL_INVALID_VALUE);
2422 }
John Bauman66b8ab22014-05-06 15:57:45 -04002423
Nicolas Capensf160b172014-11-26 11:58:23 -05002424 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002425
Nicolas Capensf160b172014-11-26 11:58:23 -05002426 if(context)
2427 {
2428 for(int i = 0; i < n; i++)
2429 {
2430 framebuffers[i] = context->createFramebuffer();
2431 }
2432 }
John Bauman66b8ab22014-05-06 15:57:45 -04002433}
2434
Nicolas Capenseb195b62015-04-28 17:18:42 -07002435void GenQueriesEXT(GLsizei n, GLuint* ids)
John Bauman66b8ab22014-05-06 15:57:45 -04002436{
Nicolas Capens4be33702015-04-28 15:13:30 -07002437 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04002438
Nicolas Capensf160b172014-11-26 11:58:23 -05002439 if(n < 0)
2440 {
2441 return error(GL_INVALID_VALUE);
2442 }
John Bauman66b8ab22014-05-06 15:57:45 -04002443
Nicolas Capensf160b172014-11-26 11:58:23 -05002444 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002445
Nicolas Capensf160b172014-11-26 11:58:23 -05002446 if(context)
2447 {
2448 for(int i = 0; i < n; i++)
2449 {
2450 ids[i] = context->createQuery();
2451 }
2452 }
John Bauman66b8ab22014-05-06 15:57:45 -04002453}
2454
Nicolas Capenseb195b62015-04-28 17:18:42 -07002455void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
John Bauman66b8ab22014-05-06 15:57:45 -04002456{
Nicolas Capens4be33702015-04-28 15:13:30 -07002457 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002458
Nicolas Capensf160b172014-11-26 11:58:23 -05002459 if(n < 0)
2460 {
2461 return error(GL_INVALID_VALUE);
2462 }
John Bauman66b8ab22014-05-06 15:57:45 -04002463
Nicolas Capensf160b172014-11-26 11:58:23 -05002464 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002465
Nicolas Capensf160b172014-11-26 11:58:23 -05002466 if(context)
2467 {
2468 for(int i = 0; i < n; i++)
2469 {
2470 renderbuffers[i] = context->createRenderbuffer();
2471 }
2472 }
John Bauman66b8ab22014-05-06 15:57:45 -04002473}
2474
Nicolas Capenseb195b62015-04-28 17:18:42 -07002475void GenTextures(GLsizei n, GLuint* textures)
John Bauman66b8ab22014-05-06 15:57:45 -04002476{
Nicolas Capens4be33702015-04-28 15:13:30 -07002477 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04002478
Nicolas Capensf160b172014-11-26 11:58:23 -05002479 if(n < 0)
2480 {
2481 return error(GL_INVALID_VALUE);
2482 }
John Bauman66b8ab22014-05-06 15:57:45 -04002483
Nicolas Capensf160b172014-11-26 11:58:23 -05002484 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002485
Nicolas Capensf160b172014-11-26 11:58:23 -05002486 if(context)
2487 {
2488 for(int i = 0; i < n; i++)
2489 {
2490 textures[i] = context->createTexture();
2491 }
2492 }
John Bauman66b8ab22014-05-06 15:57:45 -04002493}
2494
Nicolas Capenseb195b62015-04-28 17:18:42 -07002495void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
John Bauman66b8ab22014-05-06 15:57:45 -04002496{
Nicolas Capens4be33702015-04-28 15:13:30 -07002497 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
2498 "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002499 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002500
Nicolas Capensf160b172014-11-26 11:58:23 -05002501 if(bufsize < 0)
2502 {
2503 return error(GL_INVALID_VALUE);
2504 }
John Bauman66b8ab22014-05-06 15:57:45 -04002505
Nicolas Capensf160b172014-11-26 11:58:23 -05002506 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002507
Nicolas Capensf160b172014-11-26 11:58:23 -05002508 if(context)
2509 {
2510 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002511
Nicolas Capensf160b172014-11-26 11:58:23 -05002512 if(!programObject)
2513 {
2514 if(context->getShader(program))
2515 {
2516 return error(GL_INVALID_OPERATION);
2517 }
2518 else
2519 {
2520 return error(GL_INVALID_VALUE);
2521 }
2522 }
John Bauman66b8ab22014-05-06 15:57:45 -04002523
Nicolas Capensf160b172014-11-26 11:58:23 -05002524 if(index >= (GLuint)programObject->getActiveAttributeCount())
2525 {
2526 return error(GL_INVALID_VALUE);
2527 }
John Bauman66b8ab22014-05-06 15:57:45 -04002528
Nicolas Capensf160b172014-11-26 11:58:23 -05002529 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2530 }
John Bauman66b8ab22014-05-06 15:57:45 -04002531}
2532
Nicolas Capenseb195b62015-04-28 17:18:42 -07002533void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
John Bauman66b8ab22014-05-06 15:57:45 -04002534{
Nicolas Capensf160b172014-11-26 11:58:23 -05002535 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07002536 "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002537 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002538
Nicolas Capensf160b172014-11-26 11:58:23 -05002539 if(bufsize < 0)
2540 {
2541 return error(GL_INVALID_VALUE);
2542 }
John Bauman66b8ab22014-05-06 15:57:45 -04002543
Nicolas Capensf160b172014-11-26 11:58:23 -05002544 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002545
Nicolas Capensf160b172014-11-26 11:58:23 -05002546 if(context)
2547 {
2548 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002549
Nicolas Capensf160b172014-11-26 11:58:23 -05002550 if(!programObject)
2551 {
2552 if(context->getShader(program))
2553 {
2554 return error(GL_INVALID_OPERATION);
2555 }
2556 else
2557 {
2558 return error(GL_INVALID_VALUE);
2559 }
2560 }
John Bauman66b8ab22014-05-06 15:57:45 -04002561
Nicolas Capensf160b172014-11-26 11:58:23 -05002562 if(index >= (GLuint)programObject->getActiveUniformCount())
2563 {
2564 return error(GL_INVALID_VALUE);
2565 }
John Bauman66b8ab22014-05-06 15:57:45 -04002566
Nicolas Capensf160b172014-11-26 11:58:23 -05002567 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2568 }
John Bauman66b8ab22014-05-06 15:57:45 -04002569}
2570
Nicolas Capenseb195b62015-04-28 17:18:42 -07002571void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
John Bauman66b8ab22014-05-06 15:57:45 -04002572{
Nicolas Capens4be33702015-04-28 15:13:30 -07002573 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002574 program, maxcount, count, shaders);
John Bauman66b8ab22014-05-06 15:57:45 -04002575
Nicolas Capensf160b172014-11-26 11:58:23 -05002576 if(maxcount < 0)
2577 {
2578 return error(GL_INVALID_VALUE);
2579 }
John Bauman66b8ab22014-05-06 15:57:45 -04002580
Nicolas Capensf160b172014-11-26 11:58:23 -05002581 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002582
Nicolas Capensf160b172014-11-26 11:58:23 -05002583 if(context)
2584 {
2585 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002586
Nicolas Capensf160b172014-11-26 11:58:23 -05002587 if(!programObject)
2588 {
2589 if(context->getShader(program))
2590 {
2591 return error(GL_INVALID_OPERATION);
2592 }
2593 else
2594 {
2595 return error(GL_INVALID_VALUE);
2596 }
2597 }
John Bauman66b8ab22014-05-06 15:57:45 -04002598
Nicolas Capensf160b172014-11-26 11:58:23 -05002599 return programObject->getAttachedShaders(maxcount, count, shaders);
2600 }
John Bauman66b8ab22014-05-06 15:57:45 -04002601}
2602
Nicolas Capenseb195b62015-04-28 17:18:42 -07002603int GetAttribLocation(GLuint program, const GLchar* name)
John Bauman66b8ab22014-05-06 15:57:45 -04002604{
Nicolas Capensf160b172014-11-26 11:58:23 -05002605 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002606
Nicolas Capensf160b172014-11-26 11:58:23 -05002607 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002608
Nicolas Capensf160b172014-11-26 11:58:23 -05002609 if(context)
2610 {
John Bauman66b8ab22014-05-06 15:57:45 -04002611
Nicolas Capensf160b172014-11-26 11:58:23 -05002612 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002613
Nicolas Capensf160b172014-11-26 11:58:23 -05002614 if(!programObject)
2615 {
2616 if(context->getShader(program))
2617 {
2618 return error(GL_INVALID_OPERATION, -1);
2619 }
2620 else
2621 {
2622 return error(GL_INVALID_VALUE, -1);
2623 }
2624 }
John Bauman66b8ab22014-05-06 15:57:45 -04002625
Nicolas Capensf160b172014-11-26 11:58:23 -05002626 if(!programObject->isLinked())
2627 {
2628 return error(GL_INVALID_OPERATION, -1);
2629 }
John Bauman66b8ab22014-05-06 15:57:45 -04002630
Nicolas Capensf160b172014-11-26 11:58:23 -05002631 return programObject->getAttributeLocation(name);
2632 }
John Bauman66b8ab22014-05-06 15:57:45 -04002633
Nicolas Capensf160b172014-11-26 11:58:23 -05002634 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04002635}
2636
Nicolas Capenseb195b62015-04-28 17:18:42 -07002637void GetBooleanv(GLenum pname, GLboolean* params)
John Bauman66b8ab22014-05-06 15:57:45 -04002638{
Nicolas Capens4be33702015-04-28 15:13:30 -07002639 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002640
Nicolas Capensf160b172014-11-26 11:58:23 -05002641 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002642
Nicolas Capensf160b172014-11-26 11:58:23 -05002643 if(context)
2644 {
2645 if(!(context->getBooleanv(pname, params)))
2646 {
2647 GLenum nativeType;
2648 unsigned int numParams = 0;
2649 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2650 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002651
Nicolas Capensf160b172014-11-26 11:58:23 -05002652 if(numParams == 0)
2653 return; // it is known that the pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04002654
Nicolas Capensf160b172014-11-26 11:58:23 -05002655 if(nativeType == GL_FLOAT)
2656 {
2657 GLfloat *floatParams = NULL;
2658 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002659
Nicolas Capensf160b172014-11-26 11:58:23 -05002660 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002661
Nicolas Capensf160b172014-11-26 11:58:23 -05002662 for(unsigned int i = 0; i < numParams; ++i)
2663 {
2664 if(floatParams[i] == 0.0f)
2665 params[i] = GL_FALSE;
2666 else
2667 params[i] = GL_TRUE;
2668 }
John Bauman66b8ab22014-05-06 15:57:45 -04002669
Nicolas Capensf160b172014-11-26 11:58:23 -05002670 delete [] floatParams;
2671 }
2672 else if(nativeType == GL_INT)
2673 {
2674 GLint *intParams = NULL;
2675 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002676
Nicolas Capensf160b172014-11-26 11:58:23 -05002677 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002678
Nicolas Capensf160b172014-11-26 11:58:23 -05002679 for(unsigned int i = 0; i < numParams; ++i)
2680 {
2681 if(intParams[i] == 0)
2682 params[i] = GL_FALSE;
2683 else
2684 params[i] = GL_TRUE;
2685 }
John Bauman66b8ab22014-05-06 15:57:45 -04002686
Nicolas Capensf160b172014-11-26 11:58:23 -05002687 delete [] intParams;
2688 }
2689 }
2690 }
John Bauman66b8ab22014-05-06 15:57:45 -04002691}
2692
Nicolas Capenseb195b62015-04-28 17:18:42 -07002693void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04002694{
Nicolas Capens4be33702015-04-28 15:13:30 -07002695 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002696
Nicolas Capensf160b172014-11-26 11:58:23 -05002697 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002698
Nicolas Capensf160b172014-11-26 11:58:23 -05002699 if(context)
2700 {
2701 es2::Buffer *buffer;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -04002702 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -05002703 {
Nicolas Capensf160b172014-11-26 11:58:23 -05002704 return error(GL_INVALID_ENUM);
2705 }
John Bauman66b8ab22014-05-06 15:57:45 -04002706
Nicolas Capensf160b172014-11-26 11:58:23 -05002707 if(!buffer)
2708 {
2709 // A null buffer means that "0" is bound to the requested buffer target
2710 return error(GL_INVALID_OPERATION);
2711 }
John Bauman66b8ab22014-05-06 15:57:45 -04002712
Alexis Hetued306182015-04-02 12:02:28 -04002713 egl::GLint clientVersion = context->getClientVersion();
2714
Nicolas Capensf160b172014-11-26 11:58:23 -05002715 switch(pname)
2716 {
2717 case GL_BUFFER_USAGE:
2718 *params = buffer->usage();
2719 break;
2720 case GL_BUFFER_SIZE:
2721 *params = buffer->size();
2722 break;
Alexis Hetued306182015-04-02 12:02:28 -04002723 case GL_BUFFER_ACCESS_FLAGS:
2724 if(clientVersion >= 3)
2725 {
2726 *params = buffer->access();
2727 break;
2728 }
2729 else return error(GL_INVALID_ENUM);
2730 case GL_BUFFER_MAPPED:
2731 if(clientVersion >= 3)
2732 {
2733 *params = buffer->isMapped();
2734 break;
2735 }
2736 else return error(GL_INVALID_ENUM);
2737 case GL_BUFFER_MAP_LENGTH:
2738 if(clientVersion >= 3)
2739 {
2740 *params = buffer->length();
2741 break;
2742 }
2743 else return error(GL_INVALID_ENUM);
2744 case GL_BUFFER_MAP_OFFSET:
2745 if(clientVersion >= 3)
2746 {
2747 *params = buffer->offset();
2748 break;
2749 }
2750 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05002751 default:
2752 return error(GL_INVALID_ENUM);
2753 }
2754 }
John Bauman66b8ab22014-05-06 15:57:45 -04002755}
2756
Nicolas Capenseb195b62015-04-28 17:18:42 -07002757GLenum GetError(void)
John Bauman66b8ab22014-05-06 15:57:45 -04002758{
Nicolas Capensf160b172014-11-26 11:58:23 -05002759 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002760
Nicolas Capensf160b172014-11-26 11:58:23 -05002761 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002762
Nicolas Capensf160b172014-11-26 11:58:23 -05002763 if(context)
2764 {
2765 return context->getError();
2766 }
John Bauman66b8ab22014-05-06 15:57:45 -04002767
Nicolas Capensf160b172014-11-26 11:58:23 -05002768 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002769}
2770
Nicolas Capenseb195b62015-04-28 17:18:42 -07002771void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04002772{
Nicolas Capens4be33702015-04-28 15:13:30 -07002773 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002774
Nicolas Capensf160b172014-11-26 11:58:23 -05002775 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002776
Nicolas Capensf160b172014-11-26 11:58:23 -05002777 if(context)
2778 {
2779 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002780
Nicolas Capensf160b172014-11-26 11:58:23 -05002781 if(fenceObject == NULL)
2782 {
2783 return error(GL_INVALID_OPERATION);
2784 }
John Bauman66b8ab22014-05-06 15:57:45 -04002785
Nicolas Capensf160b172014-11-26 11:58:23 -05002786 fenceObject->getFenceiv(pname, params);
2787 }
John Bauman66b8ab22014-05-06 15:57:45 -04002788}
2789
Nicolas Capenseb195b62015-04-28 17:18:42 -07002790void GetFloatv(GLenum pname, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04002791{
Nicolas Capens4be33702015-04-28 15:13:30 -07002792 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002793
Nicolas Capensf160b172014-11-26 11:58:23 -05002794 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002795
Nicolas Capensf160b172014-11-26 11:58:23 -05002796 if(context)
2797 {
2798 if(!(context->getFloatv(pname, params)))
2799 {
2800 GLenum nativeType;
2801 unsigned int numParams = 0;
2802 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2803 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002804
Nicolas Capensf160b172014-11-26 11:58:23 -05002805 if(numParams == 0)
2806 return; // it is known that the pname is valid, but that there are no parameters to return.
John Bauman66b8ab22014-05-06 15:57:45 -04002807
Nicolas Capensf160b172014-11-26 11:58:23 -05002808 if(nativeType == GL_BOOL)
2809 {
2810 GLboolean *boolParams = NULL;
2811 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002812
Nicolas Capensf160b172014-11-26 11:58:23 -05002813 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002814
Nicolas Capensf160b172014-11-26 11:58:23 -05002815 for(unsigned int i = 0; i < numParams; ++i)
2816 {
2817 if(boolParams[i] == GL_FALSE)
2818 params[i] = 0.0f;
2819 else
2820 params[i] = 1.0f;
2821 }
John Bauman66b8ab22014-05-06 15:57:45 -04002822
Nicolas Capensf160b172014-11-26 11:58:23 -05002823 delete [] boolParams;
2824 }
2825 else if(nativeType == GL_INT)
2826 {
2827 GLint *intParams = NULL;
2828 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002829
Nicolas Capensf160b172014-11-26 11:58:23 -05002830 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002831
Nicolas Capensf160b172014-11-26 11:58:23 -05002832 for(unsigned int i = 0; i < numParams; ++i)
2833 {
2834 params[i] = (GLfloat)intParams[i];
2835 }
John Bauman66b8ab22014-05-06 15:57:45 -04002836
Nicolas Capensf160b172014-11-26 11:58:23 -05002837 delete [] intParams;
2838 }
2839 }
2840 }
John Bauman66b8ab22014-05-06 15:57:45 -04002841}
2842
Nicolas Capenseb195b62015-04-28 17:18:42 -07002843void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04002844{
Nicolas Capens4be33702015-04-28 15:13:30 -07002845 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002846 target, attachment, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002847
Nicolas Capensf160b172014-11-26 11:58:23 -05002848 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002849
Nicolas Capensf160b172014-11-26 11:58:23 -05002850 if(context)
2851 {
2852 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2853 {
2854 return error(GL_INVALID_ENUM);
2855 }
John Bauman66b8ab22014-05-06 15:57:45 -04002856
Nicolas Capensf160b172014-11-26 11:58:23 -05002857 es2::Framebuffer *framebuffer = NULL;
2858 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2859 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002860 if(context->getReadFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002861 {
2862 return error(GL_INVALID_OPERATION);
2863 }
John Bauman66b8ab22014-05-06 15:57:45 -04002864
Nicolas Capensf160b172014-11-26 11:58:23 -05002865 framebuffer = context->getReadFramebuffer();
2866 }
2867 else
2868 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002869 if(context->getDrawFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002870 {
2871 return error(GL_INVALID_OPERATION);
2872 }
John Bauman66b8ab22014-05-06 15:57:45 -04002873
Nicolas Capensf160b172014-11-26 11:58:23 -05002874 framebuffer = context->getDrawFramebuffer();
2875 }
John Bauman66b8ab22014-05-06 15:57:45 -04002876
Nicolas Capensf160b172014-11-26 11:58:23 -05002877 GLenum attachmentType;
2878 GLuint attachmentHandle;
2879 switch(attachment)
2880 {
2881 case GL_COLOR_ATTACHMENT0:
2882 attachmentType = framebuffer->getColorbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002883 attachmentHandle = framebuffer->getColorbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002884 break;
2885 case GL_DEPTH_ATTACHMENT:
2886 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002887 attachmentHandle = framebuffer->getDepthbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002888 break;
2889 case GL_STENCIL_ATTACHMENT:
2890 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002891 attachmentHandle = framebuffer->getStencilbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002892 break;
2893 default:
2894 return error(GL_INVALID_ENUM);
2895 }
John Bauman66b8ab22014-05-06 15:57:45 -04002896
Nicolas Capensf160b172014-11-26 11:58:23 -05002897 GLenum attachmentObjectType; // Type category
2898 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2899 {
2900 attachmentObjectType = attachmentType;
2901 }
2902 else if(es2::IsTextureTarget(attachmentType))
2903 {
2904 attachmentObjectType = GL_TEXTURE;
2905 }
2906 else UNREACHABLE();
John Bauman66b8ab22014-05-06 15:57:45 -04002907
Nicolas Capensf160b172014-11-26 11:58:23 -05002908 switch(pname)
2909 {
2910 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2911 *params = attachmentObjectType;
2912 break;
2913 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2914 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2915 {
2916 *params = attachmentHandle;
2917 }
2918 else
2919 {
2920 return error(GL_INVALID_ENUM);
2921 }
2922 break;
2923 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2924 if(attachmentObjectType == GL_TEXTURE)
2925 {
2926 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2927 }
2928 else
2929 {
2930 return error(GL_INVALID_ENUM);
2931 }
2932 break;
2933 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2934 if(attachmentObjectType == GL_TEXTURE)
2935 {
2936 if(es2::IsCubemapTextureTarget(attachmentType))
2937 {
2938 *params = attachmentType;
2939 }
2940 else
2941 {
2942 *params = 0;
2943 }
2944 }
2945 else
2946 {
2947 return error(GL_INVALID_ENUM);
2948 }
2949 break;
2950 default:
2951 return error(GL_INVALID_ENUM);
2952 }
2953 }
John Bauman66b8ab22014-05-06 15:57:45 -04002954}
2955
Nicolas Capenseb195b62015-04-28 17:18:42 -07002956GLenum GetGraphicsResetStatusEXT(void)
John Bauman66b8ab22014-05-06 15:57:45 -04002957{
Nicolas Capensf160b172014-11-26 11:58:23 -05002958 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002959
Nicolas Capensf160b172014-11-26 11:58:23 -05002960 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002961}
2962
Nicolas Capenseb195b62015-04-28 17:18:42 -07002963void GetIntegerv(GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04002964{
Nicolas Capens4be33702015-04-28 15:13:30 -07002965 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002966
Nicolas Capensf160b172014-11-26 11:58:23 -05002967 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002968
Nicolas Capens7ae353d2015-03-13 17:59:58 -04002969 if(!context)
2970 {
Greg Hartman6074f122015-04-08 09:57:16 -07002971 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
2972 #ifdef __ANDROID__
2973 ALOGI("expected_badness glGetIntegerv() called without current context.");
2974 #else
2975 ERR("glGetIntegerv() called without current context.");
2976 #endif
Nicolas Capens7ae353d2015-03-13 17:59:58 -04002977
2978 // This is not spec compliant! When there is no current GL context, functions should
2979 // have no side effects. Google Maps queries these values before creating a context,
2980 // so we need this as a bug-compatible workaround.
2981 switch(pname)
2982 {
2983 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return;
2984 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return;
2985 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
2986 case GL_STENCIL_BITS: *params = 8; return;
2987 case GL_ALIASED_LINE_WIDTH_RANGE:
2988 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
2989 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
2990 return;
2991 }
2992 }
2993
Nicolas Capensf160b172014-11-26 11:58:23 -05002994 if(context)
2995 {
2996 if(!(context->getIntegerv(pname, params)))
2997 {
2998 GLenum nativeType;
2999 unsigned int numParams = 0;
3000 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3001 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04003002
Nicolas Capensf160b172014-11-26 11:58:23 -05003003 if(numParams == 0)
3004 return; // it is known that pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04003005
Nicolas Capensf160b172014-11-26 11:58:23 -05003006 if(nativeType == GL_BOOL)
3007 {
3008 GLboolean *boolParams = NULL;
3009 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04003010
Nicolas Capensf160b172014-11-26 11:58:23 -05003011 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04003012
Nicolas Capensf160b172014-11-26 11:58:23 -05003013 for(unsigned int i = 0; i < numParams; ++i)
3014 {
Alexis Hetued306182015-04-02 12:02:28 -04003015 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
Nicolas Capensf160b172014-11-26 11:58:23 -05003016 }
John Bauman66b8ab22014-05-06 15:57:45 -04003017
Nicolas Capensf160b172014-11-26 11:58:23 -05003018 delete [] boolParams;
3019 }
3020 else if(nativeType == GL_FLOAT)
3021 {
3022 GLfloat *floatParams = NULL;
3023 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04003024
Nicolas Capensf160b172014-11-26 11:58:23 -05003025 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04003026
Nicolas Capensf160b172014-11-26 11:58:23 -05003027 for(unsigned int i = 0; i < numParams; ++i)
3028 {
3029 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3030 {
Alexis Hetued306182015-04-02 12:02:28 -04003031 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) * 0.5f);
Nicolas Capensf160b172014-11-26 11:58:23 -05003032 }
3033 else
3034 {
3035 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3036 }
3037 }
John Bauman66b8ab22014-05-06 15:57:45 -04003038
Nicolas Capensf160b172014-11-26 11:58:23 -05003039 delete [] floatParams;
3040 }
3041 }
3042 }
John Bauman66b8ab22014-05-06 15:57:45 -04003043}
3044
Nicolas Capenseb195b62015-04-28 17:18:42 -07003045void GetProgramiv(GLuint program, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003046{
Nicolas Capens4be33702015-04-28 15:13:30 -07003047 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003048
Nicolas Capensf160b172014-11-26 11:58:23 -05003049 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003050
Nicolas Capensf160b172014-11-26 11:58:23 -05003051 if(context)
3052 {
3053 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003054
Nicolas Capensf160b172014-11-26 11:58:23 -05003055 if(!programObject)
3056 {
3057 return error(GL_INVALID_VALUE);
3058 }
John Bauman66b8ab22014-05-06 15:57:45 -04003059
Nicolas Capensf160b172014-11-26 11:58:23 -05003060 switch(pname)
3061 {
3062 case GL_DELETE_STATUS:
3063 *params = programObject->isFlaggedForDeletion();
3064 return;
3065 case GL_LINK_STATUS:
3066 *params = programObject->isLinked();
3067 return;
3068 case GL_VALIDATE_STATUS:
3069 *params = programObject->isValidated();
3070 return;
3071 case GL_INFO_LOG_LENGTH:
3072 *params = programObject->getInfoLogLength();
3073 return;
3074 case GL_ATTACHED_SHADERS:
3075 *params = programObject->getAttachedShadersCount();
3076 return;
3077 case GL_ACTIVE_ATTRIBUTES:
3078 *params = programObject->getActiveAttributeCount();
3079 return;
3080 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
3081 *params = programObject->getActiveAttributeMaxLength();
3082 return;
3083 case GL_ACTIVE_UNIFORMS:
3084 *params = programObject->getActiveUniformCount();
3085 return;
3086 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
3087 *params = programObject->getActiveUniformMaxLength();
3088 return;
3089 default:
3090 return error(GL_INVALID_ENUM);
3091 }
3092 }
John Bauman66b8ab22014-05-06 15:57:45 -04003093}
3094
Nicolas Capenseb195b62015-04-28 17:18:42 -07003095void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
John Bauman66b8ab22014-05-06 15:57:45 -04003096{
Nicolas Capens4be33702015-04-28 15:13:30 -07003097 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003098 program, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04003099
Nicolas Capensf160b172014-11-26 11:58:23 -05003100 if(bufsize < 0)
3101 {
3102 return error(GL_INVALID_VALUE);
3103 }
John Bauman66b8ab22014-05-06 15:57:45 -04003104
Nicolas Capensf160b172014-11-26 11:58:23 -05003105 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003106
Nicolas Capensf160b172014-11-26 11:58:23 -05003107 if(context)
3108 {
3109 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003110
Nicolas Capensf160b172014-11-26 11:58:23 -05003111 if(!programObject)
3112 {
3113 return error(GL_INVALID_VALUE);
3114 }
John Bauman66b8ab22014-05-06 15:57:45 -04003115
Nicolas Capensf160b172014-11-26 11:58:23 -05003116 programObject->getInfoLog(bufsize, length, infolog);
3117 }
John Bauman66b8ab22014-05-06 15:57:45 -04003118}
3119
Nicolas Capenseb195b62015-04-28 17:18:42 -07003120void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04003121{
Nicolas Capens4be33702015-04-28 15:13:30 -07003122 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003123
Nicolas Capensf160b172014-11-26 11:58:23 -05003124 switch(pname)
3125 {
3126 case GL_CURRENT_QUERY_EXT:
3127 break;
3128 default:
3129 return error(GL_INVALID_ENUM);
3130 }
John Bauman66b8ab22014-05-06 15:57:45 -04003131
Nicolas Capensf160b172014-11-26 11:58:23 -05003132 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003133
Nicolas Capensf160b172014-11-26 11:58:23 -05003134 if(context)
3135 {
3136 params[0] = context->getActiveQuery(target);
3137 }
John Bauman66b8ab22014-05-06 15:57:45 -04003138}
3139
Nicolas Capenseb195b62015-04-28 17:18:42 -07003140void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04003141{
Nicolas Capens4be33702015-04-28 15:13:30 -07003142 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003143
Nicolas Capensf160b172014-11-26 11:58:23 -05003144 switch(pname)
3145 {
3146 case GL_QUERY_RESULT_EXT:
3147 case GL_QUERY_RESULT_AVAILABLE_EXT:
3148 break;
3149 default:
3150 return error(GL_INVALID_ENUM);
3151 }
John Bauman66b8ab22014-05-06 15:57:45 -04003152
Nicolas Capensf160b172014-11-26 11:58:23 -05003153 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003154
Nicolas Capensf160b172014-11-26 11:58:23 -05003155 if(context)
3156 {
Alexis Hetu8e32f7b2015-04-28 09:59:09 -04003157 es2::Query *queryObject = context->getQuery(name);
John Bauman66b8ab22014-05-06 15:57:45 -04003158
Nicolas Capensf160b172014-11-26 11:58:23 -05003159 if(!queryObject)
3160 {
3161 return error(GL_INVALID_OPERATION);
3162 }
John Bauman66b8ab22014-05-06 15:57:45 -04003163
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003164 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capensf160b172014-11-26 11:58:23 -05003165 {
3166 return error(GL_INVALID_OPERATION);
3167 }
John Bauman66b8ab22014-05-06 15:57:45 -04003168
Nicolas Capensf160b172014-11-26 11:58:23 -05003169 switch(pname)
3170 {
3171 case GL_QUERY_RESULT_EXT:
3172 params[0] = queryObject->getResult();
3173 break;
3174 case GL_QUERY_RESULT_AVAILABLE_EXT:
3175 params[0] = queryObject->isResultAvailable();
3176 break;
3177 default:
3178 ASSERT(false);
3179 }
3180 }
John Bauman66b8ab22014-05-06 15:57:45 -04003181}
3182
Nicolas Capenseb195b62015-04-28 17:18:42 -07003183void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003184{
Nicolas Capens4be33702015-04-28 15:13:30 -07003185 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003186
Nicolas Capensf160b172014-11-26 11:58:23 -05003187 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003188
Nicolas Capensf160b172014-11-26 11:58:23 -05003189 if(context)
3190 {
3191 if(target != GL_RENDERBUFFER)
3192 {
3193 return error(GL_INVALID_ENUM);
3194 }
John Bauman66b8ab22014-05-06 15:57:45 -04003195
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003196 if(context->getRenderbufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05003197 {
3198 return error(GL_INVALID_OPERATION);
3199 }
John Bauman66b8ab22014-05-06 15:57:45 -04003200
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003201 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
John Bauman66b8ab22014-05-06 15:57:45 -04003202
Nicolas Capensf160b172014-11-26 11:58:23 -05003203 switch(pname)
3204 {
3205 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3206 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3207 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
3208 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3209 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3210 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3211 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3212 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3213 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
3214 case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break;
3215 default:
3216 return error(GL_INVALID_ENUM);
3217 }
3218 }
John Bauman66b8ab22014-05-06 15:57:45 -04003219}
3220
Nicolas Capenseb195b62015-04-28 17:18:42 -07003221void GetShaderiv(GLuint shader, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003222{
Nicolas Capens4be33702015-04-28 15:13:30 -07003223 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003224
Nicolas Capensf160b172014-11-26 11:58:23 -05003225 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003226
Nicolas Capensf160b172014-11-26 11:58:23 -05003227 if(context)
3228 {
3229 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003230
Nicolas Capensf160b172014-11-26 11:58:23 -05003231 if(!shaderObject)
3232 {
3233 return error(GL_INVALID_VALUE);
3234 }
John Bauman66b8ab22014-05-06 15:57:45 -04003235
Nicolas Capensf160b172014-11-26 11:58:23 -05003236 switch(pname)
3237 {
3238 case GL_SHADER_TYPE:
3239 *params = shaderObject->getType();
3240 return;
3241 case GL_DELETE_STATUS:
3242 *params = shaderObject->isFlaggedForDeletion();
3243 return;
3244 case GL_COMPILE_STATUS:
3245 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3246 return;
3247 case GL_INFO_LOG_LENGTH:
3248 *params = shaderObject->getInfoLogLength();
3249 return;
3250 case GL_SHADER_SOURCE_LENGTH:
3251 *params = shaderObject->getSourceLength();
3252 return;
3253 default:
3254 return error(GL_INVALID_ENUM);
3255 }
3256 }
John Bauman66b8ab22014-05-06 15:57:45 -04003257}
3258
Nicolas Capenseb195b62015-04-28 17:18:42 -07003259void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
John Bauman66b8ab22014-05-06 15:57:45 -04003260{
Nicolas Capens4be33702015-04-28 15:13:30 -07003261 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003262 shader, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04003263
Nicolas Capensf160b172014-11-26 11:58:23 -05003264 if(bufsize < 0)
3265 {
3266 return error(GL_INVALID_VALUE);
3267 }
John Bauman66b8ab22014-05-06 15:57:45 -04003268
Nicolas Capensf160b172014-11-26 11:58:23 -05003269 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003270
Nicolas Capensf160b172014-11-26 11:58:23 -05003271 if(context)
3272 {
3273 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003274
Nicolas Capensf160b172014-11-26 11:58:23 -05003275 if(!shaderObject)
3276 {
3277 return error(GL_INVALID_VALUE);
3278 }
John Bauman66b8ab22014-05-06 15:57:45 -04003279
Nicolas Capensf160b172014-11-26 11:58:23 -05003280 shaderObject->getInfoLog(bufsize, length, infolog);
3281 }
John Bauman66b8ab22014-05-06 15:57:45 -04003282}
3283
Nicolas Capenseb195b62015-04-28 17:18:42 -07003284void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
John Bauman66b8ab22014-05-06 15:57:45 -04003285{
Nicolas Capens4be33702015-04-28 15:13:30 -07003286 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003287 shadertype, precisiontype, range, precision);
John Bauman66b8ab22014-05-06 15:57:45 -04003288
Nicolas Capensf160b172014-11-26 11:58:23 -05003289 switch(shadertype)
3290 {
3291 case GL_VERTEX_SHADER:
3292 case GL_FRAGMENT_SHADER:
3293 break;
3294 default:
3295 return error(GL_INVALID_ENUM);
3296 }
John Bauman66b8ab22014-05-06 15:57:45 -04003297
Nicolas Capensf160b172014-11-26 11:58:23 -05003298 switch(precisiontype)
3299 {
3300 case GL_LOW_FLOAT:
3301 case GL_MEDIUM_FLOAT:
3302 case GL_HIGH_FLOAT:
3303 // IEEE 754 single-precision
3304 range[0] = 127;
3305 range[1] = 127;
3306 *precision = 23;
3307 break;
3308 case GL_LOW_INT:
3309 case GL_MEDIUM_INT:
3310 case GL_HIGH_INT:
3311 // Single-precision floating-point numbers can accurately represent integers up to +/-16777216
3312 range[0] = 24;
3313 range[1] = 24;
3314 *precision = 0;
3315 break;
3316 default:
3317 return error(GL_INVALID_ENUM);
3318 }
John Bauman66b8ab22014-05-06 15:57:45 -04003319}
3320
Nicolas Capenseb195b62015-04-28 17:18:42 -07003321void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
John Bauman66b8ab22014-05-06 15:57:45 -04003322{
Nicolas Capens4be33702015-04-28 15:13:30 -07003323 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003324 shader, bufsize, length, source);
John Bauman66b8ab22014-05-06 15:57:45 -04003325
Nicolas Capensf160b172014-11-26 11:58:23 -05003326 if(bufsize < 0)
3327 {
3328 return error(GL_INVALID_VALUE);
3329 }
John Bauman66b8ab22014-05-06 15:57:45 -04003330
Nicolas Capensf160b172014-11-26 11:58:23 -05003331 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003332
Nicolas Capensf160b172014-11-26 11:58:23 -05003333 if(context)
3334 {
3335 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003336
Nicolas Capensf160b172014-11-26 11:58:23 -05003337 if(!shaderObject)
3338 {
3339 return error(GL_INVALID_OPERATION);
3340 }
John Bauman66b8ab22014-05-06 15:57:45 -04003341
Nicolas Capensf160b172014-11-26 11:58:23 -05003342 shaderObject->getSource(bufsize, length, source);
3343 }
John Bauman66b8ab22014-05-06 15:57:45 -04003344}
3345
Nicolas Capenseb195b62015-04-28 17:18:42 -07003346const GLubyte* GetString(GLenum name)
John Bauman66b8ab22014-05-06 15:57:45 -04003347{
Nicolas Capensf160b172014-11-26 11:58:23 -05003348 TRACE("(GLenum name = 0x%X)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04003349
Nicolas Capensf160b172014-11-26 11:58:23 -05003350 switch(name)
3351 {
3352 case GL_VENDOR:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003353 return (GLubyte*)"Google Inc.";
Nicolas Capensf160b172014-11-26 11:58:23 -05003354 case GL_RENDERER:
3355 return (GLubyte*)"SwiftShader";
3356 case GL_VERSION:
3357 return (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3358 case GL_SHADING_LANGUAGE_VERSION:
3359 return (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3360 case GL_EXTENSIONS:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003361 {
3362 es2::Context *context = es2::getContext();
3363 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)NULL;
3364 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003365 default:
3366 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3367 }
John Bauman66b8ab22014-05-06 15:57:45 -04003368}
3369
Nicolas Capenseb195b62015-04-28 17:18:42 -07003370void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003371{
Nicolas Capens4be33702015-04-28 15:13:30 -07003372 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003373
Nicolas Capensf160b172014-11-26 11:58:23 -05003374 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003375
Nicolas Capensf160b172014-11-26 11:58:23 -05003376 if(context)
3377 {
3378 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003379
Alexis Hetued306182015-04-02 12:02:28 -04003380 egl::GLint clientVersion = context->getClientVersion();
3381
Nicolas Capensf160b172014-11-26 11:58:23 -05003382 switch(target)
3383 {
3384 case GL_TEXTURE_2D:
3385 texture = context->getTexture2D();
3386 break;
3387 case GL_TEXTURE_CUBE_MAP:
3388 texture = context->getTextureCubeMap();
3389 break;
3390 case GL_TEXTURE_EXTERNAL_OES:
3391 texture = context->getTextureExternal();
3392 break;
Alexis Hetued306182015-04-02 12:02:28 -04003393 case GL_TEXTURE_2D_ARRAY:
3394 if(clientVersion < 3)
3395 {
3396 return error(GL_INVALID_ENUM);
3397 }
3398 else
3399 {
3400 UNIMPLEMENTED();
3401 texture = context->getTexture3D();
3402 break;
3403 }
3404 case GL_TEXTURE_3D_OES:
3405 texture = context->getTexture3D();
3406 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003407 default:
3408 return error(GL_INVALID_ENUM);
3409 }
John Bauman66b8ab22014-05-06 15:57:45 -04003410
Nicolas Capensf160b172014-11-26 11:58:23 -05003411 switch(pname)
3412 {
3413 case GL_TEXTURE_MAG_FILTER:
3414 *params = (GLfloat)texture->getMagFilter();
3415 break;
3416 case GL_TEXTURE_MIN_FILTER:
3417 *params = (GLfloat)texture->getMinFilter();
3418 break;
3419 case GL_TEXTURE_WRAP_S:
3420 *params = (GLfloat)texture->getWrapS();
3421 break;
3422 case GL_TEXTURE_WRAP_T:
3423 *params = (GLfloat)texture->getWrapT();
3424 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003425 case GL_TEXTURE_WRAP_R_OES:
3426 *params = (GLfloat)texture->getWrapR();
3427 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003428 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3429 *params = texture->getMaxAnisotropy();
3430 break;
3431 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3432 *params = (GLfloat)1;
3433 break;
Alexis Hetued306182015-04-02 12:02:28 -04003434 case GL_TEXTURE_BASE_LEVEL:
3435 if(clientVersion >= 3)
3436 {
3437 *params = (GLfloat)texture->getBaseLevel();
3438 break;
3439 }
3440 else return error(GL_INVALID_ENUM);
3441 case GL_TEXTURE_COMPARE_FUNC:
3442 if(clientVersion >= 3)
3443 {
3444 *params = (GLfloat)texture->getCompareFunc();
3445 break;
3446 }
3447 else return error(GL_INVALID_ENUM);
3448 case GL_TEXTURE_COMPARE_MODE:
3449 if(clientVersion >= 3)
3450 {
3451 *params = (GLfloat)texture->getCompareMode();
3452 break;
3453 }
3454 else return error(GL_INVALID_ENUM);
3455 case GL_TEXTURE_IMMUTABLE_FORMAT:
3456 if(clientVersion >= 3)
3457 {
3458 *params = (GLfloat)texture->getImmutableFormat();
3459 break;
3460 }
3461 else return error(GL_INVALID_ENUM);
3462 case GL_TEXTURE_MAX_LEVEL:
3463 if(clientVersion >= 3)
3464 {
3465 *params = (GLfloat)texture->getMaxLevel();
3466 break;
3467 }
3468 else return error(GL_INVALID_ENUM);
3469 case GL_TEXTURE_MAX_LOD:
3470 if(clientVersion >= 3)
3471 {
3472 *params = texture->getMaxLOD();
3473 break;
3474 }
3475 else return error(GL_INVALID_ENUM);
3476 case GL_TEXTURE_MIN_LOD:
3477 if(clientVersion >= 3)
3478 {
3479 *params = texture->getMinLOD();
3480 break;
3481 }
3482 else return error(GL_INVALID_ENUM);
3483 case GL_TEXTURE_SWIZZLE_R:
3484 if(clientVersion >= 3)
3485 {
3486 *params = (GLfloat)texture->getSwizzleR();
3487 break;
3488 }
3489 else return error(GL_INVALID_ENUM);
3490 case GL_TEXTURE_SWIZZLE_G:
3491 if(clientVersion >= 3)
3492 {
3493 *params = (GLfloat)texture->getSwizzleG();
3494 break;
3495 }
3496 else return error(GL_INVALID_ENUM);
3497 case GL_TEXTURE_SWIZZLE_B:
3498 if(clientVersion >= 3)
3499 {
3500 *params = (GLfloat)texture->getSwizzleB();
3501 break;
3502 }
3503 else return error(GL_INVALID_ENUM);
3504 case GL_TEXTURE_SWIZZLE_A:
3505 if(clientVersion >= 3)
3506 {
3507 *params = (GLfloat)texture->getSwizzleA();
3508 break;
3509 }
3510 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003511 default:
3512 return error(GL_INVALID_ENUM);
3513 }
3514 }
John Bauman66b8ab22014-05-06 15:57:45 -04003515}
3516
Nicolas Capenseb195b62015-04-28 17:18:42 -07003517void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003518{
Nicolas Capens4be33702015-04-28 15:13:30 -07003519 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003520
Nicolas Capensf160b172014-11-26 11:58:23 -05003521 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003522
Nicolas Capensf160b172014-11-26 11:58:23 -05003523 if(context)
3524 {
3525 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003526
Alexis Hetued306182015-04-02 12:02:28 -04003527 egl::GLint clientVersion = context->getClientVersion();
3528
Nicolas Capensf160b172014-11-26 11:58:23 -05003529 switch(target)
3530 {
3531 case GL_TEXTURE_2D:
3532 texture = context->getTexture2D();
3533 break;
3534 case GL_TEXTURE_CUBE_MAP:
3535 texture = context->getTextureCubeMap();
3536 break;
3537 case GL_TEXTURE_EXTERNAL_OES:
3538 texture = context->getTextureExternal();
3539 break;
Alexis Hetued306182015-04-02 12:02:28 -04003540 case GL_TEXTURE_2D_ARRAY:
3541 if(clientVersion < 3)
3542 {
3543 return error(GL_INVALID_ENUM);
3544 }
3545 else
3546 {
3547 UNIMPLEMENTED();
3548 texture = context->getTexture3D();
3549 break;
3550 }
3551 case GL_TEXTURE_3D_OES:
3552 texture = context->getTexture3D();
3553 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003554 default:
3555 return error(GL_INVALID_ENUM);
3556 }
John Bauman66b8ab22014-05-06 15:57:45 -04003557
Nicolas Capensf160b172014-11-26 11:58:23 -05003558 switch(pname)
3559 {
3560 case GL_TEXTURE_MAG_FILTER:
3561 *params = texture->getMagFilter();
3562 break;
3563 case GL_TEXTURE_MIN_FILTER:
3564 *params = texture->getMinFilter();
3565 break;
3566 case GL_TEXTURE_WRAP_S:
3567 *params = texture->getWrapS();
3568 break;
3569 case GL_TEXTURE_WRAP_T:
3570 *params = texture->getWrapT();
3571 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003572 case GL_TEXTURE_WRAP_R_OES:
3573 *params = texture->getWrapR();
3574 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003575 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3576 *params = (GLint)texture->getMaxAnisotropy();
3577 break;
3578 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3579 *params = 1;
3580 break;
Alexis Hetued306182015-04-02 12:02:28 -04003581 case GL_TEXTURE_BASE_LEVEL:
3582 if(clientVersion >= 3)
3583 {
3584 *params = texture->getBaseLevel();
3585 break;
3586 }
3587 else return error(GL_INVALID_ENUM);
3588 case GL_TEXTURE_COMPARE_FUNC:
3589 if(clientVersion >= 3)
3590 {
3591 *params = (GLint)texture->getCompareFunc();
3592 break;
3593 }
3594 else return error(GL_INVALID_ENUM);
3595 case GL_TEXTURE_COMPARE_MODE:
3596 if(clientVersion >= 3)
3597 {
3598 *params = (GLint)texture->getCompareMode();
3599 break;
3600 }
3601 else return error(GL_INVALID_ENUM);
3602 case GL_TEXTURE_IMMUTABLE_FORMAT:
3603 if(clientVersion >= 3)
3604 {
3605 *params = (GLint)texture->getImmutableFormat();
3606 break;
3607 }
3608 else return error(GL_INVALID_ENUM);
3609 case GL_TEXTURE_MAX_LEVEL:
3610 if(clientVersion >= 3)
3611 {
3612 *params = texture->getMaxLevel();
3613 break;
3614 }
3615 else return error(GL_INVALID_ENUM);
3616 case GL_TEXTURE_MAX_LOD:
3617 if(clientVersion >= 3)
3618 {
3619 *params = (GLint)texture->getMaxLOD();
3620 break;
3621 }
3622 else return error(GL_INVALID_ENUM);
3623 case GL_TEXTURE_MIN_LOD:
3624 if(clientVersion >= 3)
3625 {
3626 *params = (GLint)texture->getMinLOD();
3627 break;
3628 }
3629 else return error(GL_INVALID_ENUM);
3630 case GL_TEXTURE_SWIZZLE_R:
3631 if(clientVersion >= 3)
3632 {
3633 *params = (GLint)texture->getSwizzleR();
3634 break;
3635 }
3636 else return error(GL_INVALID_ENUM);
3637 case GL_TEXTURE_SWIZZLE_G:
3638 if(clientVersion >= 3)
3639 {
3640 *params = (GLint)texture->getSwizzleG();
3641 break;
3642 }
3643 else return error(GL_INVALID_ENUM);
3644 case GL_TEXTURE_SWIZZLE_B:
3645 if(clientVersion >= 3)
3646 {
3647 *params = (GLint)texture->getSwizzleB();
3648 break;
3649 }
3650 else return error(GL_INVALID_ENUM);
3651 case GL_TEXTURE_SWIZZLE_A:
3652 if(clientVersion >= 3)
3653 {
3654 *params = (GLint)texture->getSwizzleA();
3655 break;
3656 }
3657 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003658 default:
3659 return error(GL_INVALID_ENUM);
3660 }
3661 }
John Bauman66b8ab22014-05-06 15:57:45 -04003662}
3663
Nicolas Capenseb195b62015-04-28 17:18:42 -07003664void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003665{
Nicolas Capens4be33702015-04-28 15:13:30 -07003666 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003667 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003668
Nicolas Capensf160b172014-11-26 11:58:23 -05003669 if(bufSize < 0)
3670 {
3671 return error(GL_INVALID_VALUE);
3672 }
John Bauman66b8ab22014-05-06 15:57:45 -04003673
Nicolas Capensf160b172014-11-26 11:58:23 -05003674 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003675
Nicolas Capensf160b172014-11-26 11:58:23 -05003676 if(context)
3677 {
3678 if(program == 0)
3679 {
3680 return error(GL_INVALID_VALUE);
3681 }
John Bauman66b8ab22014-05-06 15:57:45 -04003682
Nicolas Capensf160b172014-11-26 11:58:23 -05003683 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003684
Nicolas Capensf160b172014-11-26 11:58:23 -05003685 if(!programObject || !programObject->isLinked())
3686 {
3687 return error(GL_INVALID_OPERATION);
3688 }
John Bauman66b8ab22014-05-06 15:57:45 -04003689
Nicolas Capensf160b172014-11-26 11:58:23 -05003690 if(!programObject->getUniformfv(location, &bufSize, params))
3691 {
3692 return error(GL_INVALID_OPERATION);
3693 }
3694 }
John Bauman66b8ab22014-05-06 15:57:45 -04003695}
3696
Nicolas Capenseb195b62015-04-28 17:18:42 -07003697void GetUniformfv(GLuint program, GLint location, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003698{
Nicolas Capens4be33702015-04-28 15:13:30 -07003699 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003700
Nicolas Capensf160b172014-11-26 11:58:23 -05003701 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003702
Nicolas Capensf160b172014-11-26 11:58:23 -05003703 if(context)
3704 {
3705 if(program == 0)
3706 {
3707 return error(GL_INVALID_VALUE);
3708 }
John Bauman66b8ab22014-05-06 15:57:45 -04003709
Nicolas Capensf160b172014-11-26 11:58:23 -05003710 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003711
Nicolas Capensf160b172014-11-26 11:58:23 -05003712 if(!programObject || !programObject->isLinked())
3713 {
3714 return error(GL_INVALID_OPERATION);
3715 }
John Bauman66b8ab22014-05-06 15:57:45 -04003716
Nicolas Capensf160b172014-11-26 11:58:23 -05003717 if(!programObject->getUniformfv(location, NULL, params))
3718 {
3719 return error(GL_INVALID_OPERATION);
3720 }
3721 }
John Bauman66b8ab22014-05-06 15:57:45 -04003722}
3723
Nicolas Capenseb195b62015-04-28 17:18:42 -07003724void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003725{
Nicolas Capens4be33702015-04-28 15:13:30 -07003726 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003727 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003728
Nicolas Capensf160b172014-11-26 11:58:23 -05003729 if(bufSize < 0)
3730 {
3731 return error(GL_INVALID_VALUE);
3732 }
John Bauman66b8ab22014-05-06 15:57:45 -04003733
Nicolas Capensf160b172014-11-26 11:58:23 -05003734 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003735
Nicolas Capensf160b172014-11-26 11:58:23 -05003736 if(context)
3737 {
3738 if(program == 0)
3739 {
3740 return error(GL_INVALID_VALUE);
3741 }
John Bauman66b8ab22014-05-06 15:57:45 -04003742
Nicolas Capensf160b172014-11-26 11:58:23 -05003743 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003744
Nicolas Capensf160b172014-11-26 11:58:23 -05003745 if(!programObject || !programObject->isLinked())
3746 {
3747 return error(GL_INVALID_OPERATION);
3748 }
John Bauman66b8ab22014-05-06 15:57:45 -04003749
Nicolas Capensf160b172014-11-26 11:58:23 -05003750 if(!programObject)
3751 {
3752 return error(GL_INVALID_OPERATION);
3753 }
John Bauman66b8ab22014-05-06 15:57:45 -04003754
Nicolas Capensf160b172014-11-26 11:58:23 -05003755 if(!programObject->getUniformiv(location, &bufSize, params))
3756 {
3757 return error(GL_INVALID_OPERATION);
3758 }
3759 }
John Bauman66b8ab22014-05-06 15:57:45 -04003760}
3761
Nicolas Capenseb195b62015-04-28 17:18:42 -07003762void GetUniformiv(GLuint program, GLint location, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003763{
Nicolas Capens4be33702015-04-28 15:13:30 -07003764 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003765
Nicolas Capensf160b172014-11-26 11:58:23 -05003766 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003767
Nicolas Capensf160b172014-11-26 11:58:23 -05003768 if(context)
3769 {
3770 if(program == 0)
3771 {
3772 return error(GL_INVALID_VALUE);
3773 }
John Bauman66b8ab22014-05-06 15:57:45 -04003774
Nicolas Capensf160b172014-11-26 11:58:23 -05003775 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003776
Nicolas Capensf160b172014-11-26 11:58:23 -05003777 if(!programObject || !programObject->isLinked())
3778 {
3779 return error(GL_INVALID_OPERATION);
3780 }
John Bauman66b8ab22014-05-06 15:57:45 -04003781
Nicolas Capensf160b172014-11-26 11:58:23 -05003782 if(!programObject)
3783 {
3784 return error(GL_INVALID_OPERATION);
3785 }
John Bauman66b8ab22014-05-06 15:57:45 -04003786
Nicolas Capensf160b172014-11-26 11:58:23 -05003787 if(!programObject->getUniformiv(location, NULL, params))
3788 {
3789 return error(GL_INVALID_OPERATION);
3790 }
3791 }
John Bauman66b8ab22014-05-06 15:57:45 -04003792}
3793
Nicolas Capenseb195b62015-04-28 17:18:42 -07003794int GetUniformLocation(GLuint program, const GLchar* name)
John Bauman66b8ab22014-05-06 15:57:45 -04003795{
Nicolas Capensf160b172014-11-26 11:58:23 -05003796 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04003797
Nicolas Capensf160b172014-11-26 11:58:23 -05003798 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003799
Nicolas Capensf160b172014-11-26 11:58:23 -05003800 if(strstr(name, "gl_") == name)
3801 {
3802 return -1;
3803 }
John Bauman66b8ab22014-05-06 15:57:45 -04003804
Nicolas Capensf160b172014-11-26 11:58:23 -05003805 if(context)
3806 {
3807 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003808
Nicolas Capensf160b172014-11-26 11:58:23 -05003809 if(!programObject)
3810 {
3811 if(context->getShader(program))
3812 {
3813 return error(GL_INVALID_OPERATION, -1);
3814 }
3815 else
3816 {
3817 return error(GL_INVALID_VALUE, -1);
3818 }
3819 }
John Bauman66b8ab22014-05-06 15:57:45 -04003820
Nicolas Capensf160b172014-11-26 11:58:23 -05003821 if(!programObject->isLinked())
3822 {
3823 return error(GL_INVALID_OPERATION, -1);
3824 }
John Bauman66b8ab22014-05-06 15:57:45 -04003825
Nicolas Capensf160b172014-11-26 11:58:23 -05003826 return programObject->getUniformLocation(name);
3827 }
John Bauman66b8ab22014-05-06 15:57:45 -04003828
Nicolas Capensf160b172014-11-26 11:58:23 -05003829 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04003830}
3831
Nicolas Capenseb195b62015-04-28 17:18:42 -07003832void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003833{
Nicolas Capens4be33702015-04-28 15:13:30 -07003834 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003835
Nicolas Capensf160b172014-11-26 11:58:23 -05003836 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003837
Nicolas Capensf160b172014-11-26 11:58:23 -05003838 if(context)
3839 {
3840 if(index >= es2::MAX_VERTEX_ATTRIBS)
3841 {
3842 return error(GL_INVALID_VALUE);
3843 }
John Bauman66b8ab22014-05-06 15:57:45 -04003844
Nicolas Capensf160b172014-11-26 11:58:23 -05003845 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capensccee6a82015-04-28 16:49:59 -07003846
Alexis Hetued306182015-04-02 12:02:28 -04003847 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04003848
Nicolas Capensf160b172014-11-26 11:58:23 -05003849 switch(pname)
3850 {
3851 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3852 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3853 break;
3854 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3855 *params = (GLfloat)attribState.mSize;
3856 break;
3857 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3858 *params = (GLfloat)attribState.mStride;
3859 break;
3860 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3861 *params = (GLfloat)attribState.mType;
3862 break;
3863 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3864 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3865 break;
3866 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003867 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003868 break;
3869 case GL_CURRENT_VERTEX_ATTRIB:
Nicolas Capensf160b172014-11-26 11:58:23 -05003870 {
Alexis Hetub4d557d2015-04-24 17:25:10 -04003871 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
3872 for(int i = 0; i < 4; ++i)
3873 {
3874 params[i] = attrib.getCurrentValue(i);
3875 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003876 }
3877 break;
Alexis Hetued306182015-04-02 12:02:28 -04003878 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3879 if(clientVersion >= 3)
3880 {
3881 switch(attribState.mType)
3882 {
3883 case GL_BYTE:
3884 case GL_UNSIGNED_BYTE:
3885 case GL_SHORT:
3886 case GL_UNSIGNED_SHORT:
3887 case GL_INT:
3888 case GL_INT_2_10_10_10_REV:
3889 case GL_UNSIGNED_INT:
3890 case GL_FIXED:
3891 *params = (GLfloat)GL_TRUE;
3892 break;
3893 default:
3894 *params = (GLfloat)GL_FALSE;
3895 break;
3896 }
3897 break;
3898 }
3899 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003900 default: return error(GL_INVALID_ENUM);
3901 }
3902 }
John Bauman66b8ab22014-05-06 15:57:45 -04003903}
3904
Nicolas Capenseb195b62015-04-28 17:18:42 -07003905void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003906{
Nicolas Capens4be33702015-04-28 15:13:30 -07003907 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003908
Nicolas Capensf160b172014-11-26 11:58:23 -05003909 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003910
Nicolas Capensf160b172014-11-26 11:58:23 -05003911 if(context)
3912 {
3913 if(index >= es2::MAX_VERTEX_ATTRIBS)
3914 {
3915 return error(GL_INVALID_VALUE);
3916 }
John Bauman66b8ab22014-05-06 15:57:45 -04003917
Nicolas Capensf160b172014-11-26 11:58:23 -05003918 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
John Bauman66b8ab22014-05-06 15:57:45 -04003919
Alexis Hetued306182015-04-02 12:02:28 -04003920 egl::GLint clientVersion = context->getClientVersion();
3921
Nicolas Capensf160b172014-11-26 11:58:23 -05003922 switch(pname)
3923 {
3924 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3925 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3926 break;
3927 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3928 *params = attribState.mSize;
3929 break;
3930 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3931 *params = attribState.mStride;
3932 break;
3933 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3934 *params = attribState.mType;
3935 break;
3936 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3937 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3938 break;
3939 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003940 *params = attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003941 break;
3942 case GL_CURRENT_VERTEX_ATTRIB:
Nicolas Capensf160b172014-11-26 11:58:23 -05003943 {
Alexis Hetub4d557d2015-04-24 17:25:10 -04003944 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
3945 for(int i = 0; i < 4; ++i)
3946 {
3947 float currentValue = attrib.getCurrentValue(i);
3948 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3949 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003950 }
3951 break;
Alexis Hetued306182015-04-02 12:02:28 -04003952 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3953 if(clientVersion >= 3)
3954 {
3955 switch(attribState.mType)
3956 {
3957 case GL_BYTE:
3958 case GL_UNSIGNED_BYTE:
3959 case GL_SHORT:
3960 case GL_UNSIGNED_SHORT:
3961 case GL_INT:
3962 case GL_INT_2_10_10_10_REV:
3963 case GL_UNSIGNED_INT:
3964 case GL_FIXED:
3965 *params = GL_TRUE;
3966 break;
3967 default:
3968 *params = GL_FALSE;
3969 break;
3970 }
3971 break;
3972 }
3973 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003974 default: return error(GL_INVALID_ENUM);
3975 }
3976 }
John Bauman66b8ab22014-05-06 15:57:45 -04003977}
3978
Nicolas Capenseb195b62015-04-28 17:18:42 -07003979void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
John Bauman66b8ab22014-05-06 15:57:45 -04003980{
Nicolas Capens4be33702015-04-28 15:13:30 -07003981 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
John Bauman66b8ab22014-05-06 15:57:45 -04003982
Nicolas Capensf160b172014-11-26 11:58:23 -05003983 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003984
Nicolas Capensf160b172014-11-26 11:58:23 -05003985 if(context)
3986 {
3987 if(index >= es2::MAX_VERTEX_ATTRIBS)
3988 {
3989 return error(GL_INVALID_VALUE);
3990 }
John Bauman66b8ab22014-05-06 15:57:45 -04003991
Nicolas Capensf160b172014-11-26 11:58:23 -05003992 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3993 {
3994 return error(GL_INVALID_ENUM);
3995 }
John Bauman66b8ab22014-05-06 15:57:45 -04003996
Nicolas Capensf160b172014-11-26 11:58:23 -05003997 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3998 }
John Bauman66b8ab22014-05-06 15:57:45 -04003999}
4000
Nicolas Capenseb195b62015-04-28 17:18:42 -07004001void Hint(GLenum target, GLenum mode)
John Bauman66b8ab22014-05-06 15:57:45 -04004002{
Nicolas Capensf160b172014-11-26 11:58:23 -05004003 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
John Bauman66b8ab22014-05-06 15:57:45 -04004004
Nicolas Capensf160b172014-11-26 11:58:23 -05004005 switch(mode)
4006 {
4007 case GL_FASTEST:
4008 case GL_NICEST:
4009 case GL_DONT_CARE:
4010 break;
4011 default:
4012 return error(GL_INVALID_ENUM);
4013 }
John Bauman66b8ab22014-05-06 15:57:45 -04004014
Nicolas Capensf160b172014-11-26 11:58:23 -05004015 es2::Context *context = es2::getContext();
4016 switch(target)
4017 {
4018 case GL_GENERATE_MIPMAP_HINT:
4019 if(context) context->setGenerateMipmapHint(mode);
4020 break;
4021 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4022 if(context) context->setFragmentShaderDerivativeHint(mode);
4023 break;
4024 default:
4025 return error(GL_INVALID_ENUM);
4026 }
John Bauman66b8ab22014-05-06 15:57:45 -04004027}
4028
Nicolas Capenseb195b62015-04-28 17:18:42 -07004029GLboolean IsBuffer(GLuint buffer)
John Bauman66b8ab22014-05-06 15:57:45 -04004030{
Nicolas Capensf160b172014-11-26 11:58:23 -05004031 TRACE("(GLuint buffer = %d)", buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004032
Nicolas Capensf160b172014-11-26 11:58:23 -05004033 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004034
Nicolas Capensf160b172014-11-26 11:58:23 -05004035 if(context && buffer)
4036 {
4037 es2::Buffer *bufferObject = context->getBuffer(buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004038
Nicolas Capensf160b172014-11-26 11:58:23 -05004039 if(bufferObject)
4040 {
4041 return GL_TRUE;
4042 }
4043 }
John Bauman66b8ab22014-05-06 15:57:45 -04004044
Nicolas Capensf160b172014-11-26 11:58:23 -05004045 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004046}
4047
Nicolas Capenseb195b62015-04-28 17:18:42 -07004048GLboolean IsEnabled(GLenum cap)
John Bauman66b8ab22014-05-06 15:57:45 -04004049{
Nicolas Capensf160b172014-11-26 11:58:23 -05004050 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04004051
Nicolas Capensf160b172014-11-26 11:58:23 -05004052 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004053
Nicolas Capensf160b172014-11-26 11:58:23 -05004054 if(context)
4055 {
4056 switch(cap)
4057 {
4058 case GL_CULL_FACE: return context->isCullFaceEnabled();
4059 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4060 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4061 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4062 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4063 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4064 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4065 case GL_BLEND: return context->isBlendEnabled();
4066 case GL_DITHER: return context->isDitherEnabled();
4067 default:
4068 return error(GL_INVALID_ENUM, false);
4069 }
4070 }
John Bauman66b8ab22014-05-06 15:57:45 -04004071
Nicolas Capensf160b172014-11-26 11:58:23 -05004072 return false;
John Bauman66b8ab22014-05-06 15:57:45 -04004073}
4074
Nicolas Capenseb195b62015-04-28 17:18:42 -07004075GLboolean IsFenceNV(GLuint fence)
John Bauman66b8ab22014-05-06 15:57:45 -04004076{
Nicolas Capensf160b172014-11-26 11:58:23 -05004077 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004078
Nicolas Capensf160b172014-11-26 11:58:23 -05004079 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004080
Nicolas Capensf160b172014-11-26 11:58:23 -05004081 if(context)
4082 {
4083 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004084
Nicolas Capensf160b172014-11-26 11:58:23 -05004085 if(fenceObject == NULL)
4086 {
4087 return GL_FALSE;
4088 }
John Bauman66b8ab22014-05-06 15:57:45 -04004089
Nicolas Capensf160b172014-11-26 11:58:23 -05004090 return fenceObject->isFence();
4091 }
John Bauman66b8ab22014-05-06 15:57:45 -04004092
Nicolas Capensf160b172014-11-26 11:58:23 -05004093 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004094}
4095
Nicolas Capenseb195b62015-04-28 17:18:42 -07004096GLboolean IsFramebuffer(GLuint framebuffer)
John Bauman66b8ab22014-05-06 15:57:45 -04004097{
Nicolas Capensf160b172014-11-26 11:58:23 -05004098 TRACE("(GLuint framebuffer = %d)", framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004099
Nicolas Capensf160b172014-11-26 11:58:23 -05004100 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004101
Nicolas Capensf160b172014-11-26 11:58:23 -05004102 if(context && framebuffer)
4103 {
4104 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004105
Nicolas Capensf160b172014-11-26 11:58:23 -05004106 if(framebufferObject)
4107 {
4108 return GL_TRUE;
4109 }
4110 }
John Bauman66b8ab22014-05-06 15:57:45 -04004111
Nicolas Capensf160b172014-11-26 11:58:23 -05004112 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004113}
4114
Nicolas Capenseb195b62015-04-28 17:18:42 -07004115GLboolean IsProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04004116{
Nicolas Capensf160b172014-11-26 11:58:23 -05004117 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004118
Nicolas Capensf160b172014-11-26 11:58:23 -05004119 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004120
Nicolas Capensf160b172014-11-26 11:58:23 -05004121 if(context && program)
4122 {
4123 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004124
Nicolas Capensf160b172014-11-26 11:58:23 -05004125 if(programObject)
4126 {
4127 return GL_TRUE;
4128 }
4129 }
John Bauman66b8ab22014-05-06 15:57:45 -04004130
Nicolas Capensf160b172014-11-26 11:58:23 -05004131 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004132}
4133
Nicolas Capenseb195b62015-04-28 17:18:42 -07004134GLboolean IsQueryEXT(GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -04004135{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004136 TRACE("(GLuint name = %d)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04004137
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004138 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05004139 {
4140 return GL_FALSE;
4141 }
John Bauman66b8ab22014-05-06 15:57:45 -04004142
Nicolas Capensf160b172014-11-26 11:58:23 -05004143 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004144
Nicolas Capensf160b172014-11-26 11:58:23 -05004145 if(context)
4146 {
Alexis Hetu8e32f7b2015-04-28 09:59:09 -04004147 es2::Query *queryObject = context->getQuery(name);
John Bauman66b8ab22014-05-06 15:57:45 -04004148
Nicolas Capensf160b172014-11-26 11:58:23 -05004149 if(queryObject)
4150 {
4151 return GL_TRUE;
4152 }
4153 }
John Bauman66b8ab22014-05-06 15:57:45 -04004154
Nicolas Capensf160b172014-11-26 11:58:23 -05004155 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004156}
4157
Nicolas Capenseb195b62015-04-28 17:18:42 -07004158GLboolean IsRenderbuffer(GLuint renderbuffer)
John Bauman66b8ab22014-05-06 15:57:45 -04004159{
Nicolas Capensf160b172014-11-26 11:58:23 -05004160 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004161
Nicolas Capensf160b172014-11-26 11:58:23 -05004162 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004163
Nicolas Capensf160b172014-11-26 11:58:23 -05004164 if(context && renderbuffer)
4165 {
4166 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004167
Nicolas Capensf160b172014-11-26 11:58:23 -05004168 if(renderbufferObject)
4169 {
4170 return GL_TRUE;
4171 }
4172 }
John Bauman66b8ab22014-05-06 15:57:45 -04004173
Nicolas Capensf160b172014-11-26 11:58:23 -05004174 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004175}
4176
Nicolas Capenseb195b62015-04-28 17:18:42 -07004177GLboolean IsShader(GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -04004178{
Nicolas Capensf160b172014-11-26 11:58:23 -05004179 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004180
Nicolas Capensf160b172014-11-26 11:58:23 -05004181 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004182
Nicolas Capensf160b172014-11-26 11:58:23 -05004183 if(context && shader)
4184 {
4185 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004186
Nicolas Capensf160b172014-11-26 11:58:23 -05004187 if(shaderObject)
4188 {
4189 return GL_TRUE;
4190 }
4191 }
John Bauman66b8ab22014-05-06 15:57:45 -04004192
Nicolas Capensf160b172014-11-26 11:58:23 -05004193 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004194}
4195
Nicolas Capenseb195b62015-04-28 17:18:42 -07004196GLboolean IsTexture(GLuint texture)
John Bauman66b8ab22014-05-06 15:57:45 -04004197{
Nicolas Capensf160b172014-11-26 11:58:23 -05004198 TRACE("(GLuint texture = %d)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004199
Nicolas Capensf160b172014-11-26 11:58:23 -05004200 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004201
Nicolas Capensf160b172014-11-26 11:58:23 -05004202 if(context && texture)
4203 {
4204 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004205
Nicolas Capensf160b172014-11-26 11:58:23 -05004206 if(textureObject)
4207 {
4208 return GL_TRUE;
4209 }
4210 }
John Bauman66b8ab22014-05-06 15:57:45 -04004211
Nicolas Capensf160b172014-11-26 11:58:23 -05004212 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004213}
4214
Nicolas Capenseb195b62015-04-28 17:18:42 -07004215void LineWidth(GLfloat width)
John Bauman66b8ab22014-05-06 15:57:45 -04004216{
Nicolas Capensf160b172014-11-26 11:58:23 -05004217 TRACE("(GLfloat width = %f)", width);
John Bauman66b8ab22014-05-06 15:57:45 -04004218
Nicolas Capensf160b172014-11-26 11:58:23 -05004219 if(width <= 0.0f)
4220 {
4221 return error(GL_INVALID_VALUE);
4222 }
John Bauman66b8ab22014-05-06 15:57:45 -04004223
Nicolas Capensf160b172014-11-26 11:58:23 -05004224 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004225
Nicolas Capensf160b172014-11-26 11:58:23 -05004226 if(context)
4227 {
4228 context->setLineWidth(width);
4229 }
John Bauman66b8ab22014-05-06 15:57:45 -04004230}
4231
Nicolas Capenseb195b62015-04-28 17:18:42 -07004232void LinkProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04004233{
Nicolas Capensf160b172014-11-26 11:58:23 -05004234 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004235
Nicolas Capensf160b172014-11-26 11:58:23 -05004236 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004237
Nicolas Capensf160b172014-11-26 11:58:23 -05004238 if(context)
4239 {
4240 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004241
Nicolas Capensf160b172014-11-26 11:58:23 -05004242 if(!programObject)
4243 {
4244 if(context->getShader(program))
4245 {
4246 return error(GL_INVALID_OPERATION);
4247 }
4248 else
4249 {
4250 return error(GL_INVALID_VALUE);
4251 }
4252 }
John Bauman66b8ab22014-05-06 15:57:45 -04004253
Nicolas Capensf160b172014-11-26 11:58:23 -05004254 programObject->link();
4255 }
John Bauman66b8ab22014-05-06 15:57:45 -04004256}
4257
Nicolas Capenseb195b62015-04-28 17:18:42 -07004258void PixelStorei(GLenum pname, GLint param)
John Bauman66b8ab22014-05-06 15:57:45 -04004259{
Nicolas Capensf160b172014-11-26 11:58:23 -05004260 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04004261
Nicolas Capensf160b172014-11-26 11:58:23 -05004262 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004263
Nicolas Capensf160b172014-11-26 11:58:23 -05004264 if(context)
4265 {
Alexis Hetued306182015-04-02 12:02:28 -04004266 egl::GLint clientVersion = context->getClientVersion();
4267
Nicolas Capensf160b172014-11-26 11:58:23 -05004268 switch(pname)
4269 {
4270 case GL_UNPACK_ALIGNMENT:
4271 if(param != 1 && param != 2 && param != 4 && param != 8)
4272 {
4273 return error(GL_INVALID_VALUE);
4274 }
4275 context->setUnpackAlignment(param);
4276 break;
4277 case GL_PACK_ALIGNMENT:
4278 if(param != 1 && param != 2 && param != 4 && param != 8)
4279 {
4280 return error(GL_INVALID_VALUE);
4281 }
4282 context->setPackAlignment(param);
4283 break;
Alexis Hetued306182015-04-02 12:02:28 -04004284 case GL_PACK_ROW_LENGTH:
4285 case GL_PACK_SKIP_PIXELS:
4286 case GL_PACK_SKIP_ROWS:
4287 case GL_UNPACK_ROW_LENGTH:
4288 case GL_UNPACK_IMAGE_HEIGHT:
4289 case GL_UNPACK_SKIP_PIXELS:
4290 case GL_UNPACK_SKIP_ROWS:
4291 case GL_UNPACK_SKIP_IMAGES:
4292 if(clientVersion >= 3)
4293 {
4294 UNIMPLEMENTED();
4295 break;
4296 }
4297 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05004298 default:
4299 return error(GL_INVALID_ENUM);
4300 }
4301 }
John Bauman66b8ab22014-05-06 15:57:45 -04004302}
4303
Nicolas Capenseb195b62015-04-28 17:18:42 -07004304void PolygonOffset(GLfloat factor, GLfloat units)
John Bauman66b8ab22014-05-06 15:57:45 -04004305{
Nicolas Capensf160b172014-11-26 11:58:23 -05004306 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
John Bauman66b8ab22014-05-06 15:57:45 -04004307
Nicolas Capensf160b172014-11-26 11:58:23 -05004308 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004309
Nicolas Capensf160b172014-11-26 11:58:23 -05004310 if(context)
4311 {
4312 context->setPolygonOffsetParams(factor, units);
4313 }
John Bauman66b8ab22014-05-06 15:57:45 -04004314}
4315
Nicolas Capenseb195b62015-04-28 17:18:42 -07004316void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4317 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
John Bauman66b8ab22014-05-06 15:57:45 -04004318{
Nicolas Capensf160b172014-11-26 11:58:23 -05004319 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004320 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004321 x, y, width, height, format, type, bufSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04004322
Nicolas Capensf160b172014-11-26 11:58:23 -05004323 if(width < 0 || height < 0 || bufSize < 0)
4324 {
4325 return error(GL_INVALID_VALUE);
4326 }
John Bauman66b8ab22014-05-06 15:57:45 -04004327
Nicolas Capensf160b172014-11-26 11:58:23 -05004328 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004329
Nicolas Capensf160b172014-11-26 11:58:23 -05004330 if(context)
4331 {
4332 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4333 }
John Bauman66b8ab22014-05-06 15:57:45 -04004334}
4335
Nicolas Capenseb195b62015-04-28 17:18:42 -07004336void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04004337{
Nicolas Capensf160b172014-11-26 11:58:23 -05004338 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004339 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004340 x, y, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004341
Nicolas Capensf160b172014-11-26 11:58:23 -05004342 if(width < 0 || height < 0)
4343 {
4344 return error(GL_INVALID_VALUE);
4345 }
John Bauman66b8ab22014-05-06 15:57:45 -04004346
Nicolas Capensf160b172014-11-26 11:58:23 -05004347 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004348
Nicolas Capensf160b172014-11-26 11:58:23 -05004349 if(context)
4350 {
4351 context->readPixels(x, y, width, height, format, type, NULL, pixels);
4352 }
John Bauman66b8ab22014-05-06 15:57:45 -04004353}
4354
Nicolas Capenseb195b62015-04-28 17:18:42 -07004355void ReleaseShaderCompiler(void)
John Bauman66b8ab22014-05-06 15:57:45 -04004356{
Nicolas Capensf160b172014-11-26 11:58:23 -05004357 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04004358
Nicolas Capensf160b172014-11-26 11:58:23 -05004359 es2::Shader::releaseCompiler();
John Bauman66b8ab22014-05-06 15:57:45 -04004360}
4361
Nicolas Capenseb195b62015-04-28 17:18:42 -07004362void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04004363{
Nicolas Capensf160b172014-11-26 11:58:23 -05004364 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4365 target, samples, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004366
Nicolas Capensf160b172014-11-26 11:58:23 -05004367 switch(target)
4368 {
4369 case GL_RENDERBUFFER:
4370 break;
4371 default:
4372 return error(GL_INVALID_ENUM);
4373 }
John Bauman66b8ab22014-05-06 15:57:45 -04004374
Nicolas Capensf160b172014-11-26 11:58:23 -05004375 if(!es2::IsColorRenderable(internalformat) && !es2::IsDepthRenderable(internalformat) && !es2::IsStencilRenderable(internalformat))
4376 {
4377 return error(GL_INVALID_ENUM);
4378 }
John Bauman66b8ab22014-05-06 15:57:45 -04004379
Nicolas Capensf160b172014-11-26 11:58:23 -05004380 if(width < 0 || height < 0 || samples < 0)
4381 {
4382 return error(GL_INVALID_VALUE);
4383 }
John Bauman66b8ab22014-05-06 15:57:45 -04004384
Nicolas Capensf160b172014-11-26 11:58:23 -05004385 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004386
Nicolas Capensf160b172014-11-26 11:58:23 -05004387 if(context)
4388 {
4389 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4390 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4391 samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4392 {
4393 return error(GL_INVALID_VALUE);
4394 }
John Bauman66b8ab22014-05-06 15:57:45 -04004395
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004396 GLuint handle = context->getRenderbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05004397 if(handle == 0)
4398 {
4399 return error(GL_INVALID_OPERATION);
4400 }
John Bauman66b8ab22014-05-06 15:57:45 -04004401
Nicolas Capensf160b172014-11-26 11:58:23 -05004402 switch(internalformat)
4403 {
4404 case GL_DEPTH_COMPONENT16:
4405 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, samples));
4406 break;
4407 case GL_RGBA4:
4408 case GL_RGB5_A1:
4409 case GL_RGB565:
4410 case GL_RGB8_OES:
4411 case GL_RGBA8_OES:
4412 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4413 break;
4414 case GL_STENCIL_INDEX8:
4415 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4416 break;
4417 case GL_DEPTH24_STENCIL8_OES:
4418 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, samples));
4419 break;
4420 default:
4421 return error(GL_INVALID_ENUM);
4422 }
4423 }
John Bauman66b8ab22014-05-06 15:57:45 -04004424}
4425
Nicolas Capenseb195b62015-04-28 17:18:42 -07004426void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04004427{
Nicolas Capensf160b172014-11-26 11:58:23 -05004428 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004429}
4430
Nicolas Capenseb195b62015-04-28 17:18:42 -07004431void SampleCoverage(GLclampf value, GLboolean invert)
John Bauman66b8ab22014-05-06 15:57:45 -04004432{
Nicolas Capensf160b172014-11-26 11:58:23 -05004433 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
John Bauman66b8ab22014-05-06 15:57:45 -04004434
Nicolas Capensf160b172014-11-26 11:58:23 -05004435 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004436
Nicolas Capensf160b172014-11-26 11:58:23 -05004437 if(context)
4438 {
4439 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4440 }
John Bauman66b8ab22014-05-06 15:57:45 -04004441}
4442
Nicolas Capenseb195b62015-04-28 17:18:42 -07004443void SetFenceNV(GLuint fence, GLenum condition)
John Bauman66b8ab22014-05-06 15:57:45 -04004444{
Nicolas Capensf160b172014-11-26 11:58:23 -05004445 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
John Bauman66b8ab22014-05-06 15:57:45 -04004446
Nicolas Capensf160b172014-11-26 11:58:23 -05004447 if(condition != GL_ALL_COMPLETED_NV)
4448 {
4449 return error(GL_INVALID_ENUM);
4450 }
John Bauman66b8ab22014-05-06 15:57:45 -04004451
Nicolas Capensf160b172014-11-26 11:58:23 -05004452 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004453
Nicolas Capensf160b172014-11-26 11:58:23 -05004454 if(context)
4455 {
4456 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004457
Nicolas Capensf160b172014-11-26 11:58:23 -05004458 if(fenceObject == NULL)
4459 {
4460 return error(GL_INVALID_OPERATION);
4461 }
John Bauman66b8ab22014-05-06 15:57:45 -04004462
Nicolas Capensf160b172014-11-26 11:58:23 -05004463 fenceObject->setFence(condition);
4464 }
John Bauman66b8ab22014-05-06 15:57:45 -04004465}
4466
Nicolas Capenseb195b62015-04-28 17:18:42 -07004467void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04004468{
Nicolas Capensf160b172014-11-26 11:58:23 -05004469 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004470
Nicolas Capensf160b172014-11-26 11:58:23 -05004471 if(width < 0 || height < 0)
4472 {
4473 return error(GL_INVALID_VALUE);
4474 }
John Bauman66b8ab22014-05-06 15:57:45 -04004475
Nicolas Capensf160b172014-11-26 11:58:23 -05004476 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004477
Nicolas Capensf160b172014-11-26 11:58:23 -05004478 if(context)
4479 {
4480 context->setScissorParams(x, y, width, height);
4481 }
John Bauman66b8ab22014-05-06 15:57:45 -04004482}
4483
Nicolas Capenseb195b62015-04-28 17:18:42 -07004484void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
John Bauman66b8ab22014-05-06 15:57:45 -04004485{
Nicolas Capens4be33702015-04-28 15:13:30 -07004486 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4487 "const GLvoid* binary = %p, GLsizei length = %d)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004488 n, shaders, binaryformat, binary, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004489
Nicolas Capensf160b172014-11-26 11:58:23 -05004490 // No binary shader formats are supported.
4491 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04004492}
4493
Nicolas Capenseb195b62015-04-28 17:18:42 -07004494void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
John Bauman66b8ab22014-05-06 15:57:45 -04004495{
Nicolas Capens4be33702015-04-28 15:13:30 -07004496 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004497 shader, count, string, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004498
Nicolas Capensf160b172014-11-26 11:58:23 -05004499 if(count < 0)
4500 {
4501 return error(GL_INVALID_VALUE);
4502 }
John Bauman66b8ab22014-05-06 15:57:45 -04004503
Nicolas Capensf160b172014-11-26 11:58:23 -05004504 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004505
Nicolas Capensf160b172014-11-26 11:58:23 -05004506 if(context)
4507 {
4508 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004509
Nicolas Capensf160b172014-11-26 11:58:23 -05004510 if(!shaderObject)
4511 {
4512 if(context->getProgram(shader))
4513 {
4514 return error(GL_INVALID_OPERATION);
4515 }
4516 else
4517 {
4518 return error(GL_INVALID_VALUE);
4519 }
4520 }
John Bauman66b8ab22014-05-06 15:57:45 -04004521
Nicolas Capensf160b172014-11-26 11:58:23 -05004522 shaderObject->setSource(count, string, length);
4523 }
John Bauman66b8ab22014-05-06 15:57:45 -04004524}
4525
Nicolas Capenseb195b62015-04-28 17:18:42 -07004526void StencilFunc(GLenum func, GLint ref, GLuint mask)
John Bauman66b8ab22014-05-06 15:57:45 -04004527{
Nicolas Capensf160b172014-11-26 11:58:23 -05004528 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004529}
4530
Nicolas Capenseb195b62015-04-28 17:18:42 -07004531void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
John Bauman66b8ab22014-05-06 15:57:45 -04004532{
Nicolas Capensf160b172014-11-26 11:58:23 -05004533 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004534
Nicolas Capensf160b172014-11-26 11:58:23 -05004535 switch(face)
4536 {
4537 case GL_FRONT:
4538 case GL_BACK:
4539 case GL_FRONT_AND_BACK:
4540 break;
4541 default:
4542 return error(GL_INVALID_ENUM);
4543 }
John Bauman66b8ab22014-05-06 15:57:45 -04004544
Nicolas Capensf160b172014-11-26 11:58:23 -05004545 switch(func)
4546 {
4547 case GL_NEVER:
4548 case GL_ALWAYS:
4549 case GL_LESS:
4550 case GL_LEQUAL:
4551 case GL_EQUAL:
4552 case GL_GEQUAL:
4553 case GL_GREATER:
4554 case GL_NOTEQUAL:
4555 break;
4556 default:
4557 return error(GL_INVALID_ENUM);
4558 }
John Bauman66b8ab22014-05-06 15:57:45 -04004559
Nicolas Capensf160b172014-11-26 11:58:23 -05004560 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004561
Nicolas Capensf160b172014-11-26 11:58:23 -05004562 if(context)
4563 {
4564 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4565 {
4566 context->setStencilParams(func, ref, mask);
4567 }
John Bauman66b8ab22014-05-06 15:57:45 -04004568
Nicolas Capensf160b172014-11-26 11:58:23 -05004569 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4570 {
4571 context->setStencilBackParams(func, ref, mask);
4572 }
4573 }
John Bauman66b8ab22014-05-06 15:57:45 -04004574}
4575
Nicolas Capenseb195b62015-04-28 17:18:42 -07004576void StencilMask(GLuint mask)
John Bauman66b8ab22014-05-06 15:57:45 -04004577{
Nicolas Capensf160b172014-11-26 11:58:23 -05004578 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004579}
4580
Nicolas Capenseb195b62015-04-28 17:18:42 -07004581void StencilMaskSeparate(GLenum face, GLuint mask)
John Bauman66b8ab22014-05-06 15:57:45 -04004582{
Nicolas Capensf160b172014-11-26 11:58:23 -05004583 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004584
Nicolas Capensf160b172014-11-26 11:58:23 -05004585 switch(face)
4586 {
4587 case GL_FRONT:
4588 case GL_BACK:
4589 case GL_FRONT_AND_BACK:
4590 break;
4591 default:
4592 return error(GL_INVALID_ENUM);
4593 }
John Bauman66b8ab22014-05-06 15:57:45 -04004594
Nicolas Capensf160b172014-11-26 11:58:23 -05004595 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004596
Nicolas Capensf160b172014-11-26 11:58:23 -05004597 if(context)
4598 {
4599 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4600 {
4601 context->setStencilWritemask(mask);
4602 }
John Bauman66b8ab22014-05-06 15:57:45 -04004603
Nicolas Capensf160b172014-11-26 11:58:23 -05004604 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4605 {
4606 context->setStencilBackWritemask(mask);
4607 }
4608 }
John Bauman66b8ab22014-05-06 15:57:45 -04004609}
4610
Nicolas Capenseb195b62015-04-28 17:18:42 -07004611void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
John Bauman66b8ab22014-05-06 15:57:45 -04004612{
Nicolas Capensf160b172014-11-26 11:58:23 -05004613 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004614}
4615
Nicolas Capenseb195b62015-04-28 17:18:42 -07004616void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
John Bauman66b8ab22014-05-06 15:57:45 -04004617{
Nicolas Capensf160b172014-11-26 11:58:23 -05004618 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4619 face, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004620
Nicolas Capensf160b172014-11-26 11:58:23 -05004621 switch(face)
4622 {
4623 case GL_FRONT:
4624 case GL_BACK:
4625 case GL_FRONT_AND_BACK:
4626 break;
4627 default:
4628 return error(GL_INVALID_ENUM);
4629 }
John Bauman66b8ab22014-05-06 15:57:45 -04004630
Nicolas Capensf160b172014-11-26 11:58:23 -05004631 switch(fail)
4632 {
4633 case GL_ZERO:
4634 case GL_KEEP:
4635 case GL_REPLACE:
4636 case GL_INCR:
4637 case GL_DECR:
4638 case GL_INVERT:
4639 case GL_INCR_WRAP:
4640 case GL_DECR_WRAP:
4641 break;
4642 default:
4643 return error(GL_INVALID_ENUM);
4644 }
John Bauman66b8ab22014-05-06 15:57:45 -04004645
Nicolas Capensf160b172014-11-26 11:58:23 -05004646 switch(zfail)
4647 {
4648 case GL_ZERO:
4649 case GL_KEEP:
4650 case GL_REPLACE:
4651 case GL_INCR:
4652 case GL_DECR:
4653 case GL_INVERT:
4654 case GL_INCR_WRAP:
4655 case GL_DECR_WRAP:
4656 break;
4657 default:
4658 return error(GL_INVALID_ENUM);
4659 }
John Bauman66b8ab22014-05-06 15:57:45 -04004660
Nicolas Capensf160b172014-11-26 11:58:23 -05004661 switch(zpass)
4662 {
4663 case GL_ZERO:
4664 case GL_KEEP:
4665 case GL_REPLACE:
4666 case GL_INCR:
4667 case GL_DECR:
4668 case GL_INVERT:
4669 case GL_INCR_WRAP:
4670 case GL_DECR_WRAP:
4671 break;
4672 default:
4673 return error(GL_INVALID_ENUM);
4674 }
John Bauman66b8ab22014-05-06 15:57:45 -04004675
Nicolas Capensf160b172014-11-26 11:58:23 -05004676 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004677
Nicolas Capensf160b172014-11-26 11:58:23 -05004678 if(context)
4679 {
4680 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4681 {
4682 context->setStencilOperations(fail, zfail, zpass);
4683 }
John Bauman66b8ab22014-05-06 15:57:45 -04004684
Nicolas Capensf160b172014-11-26 11:58:23 -05004685 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4686 {
4687 context->setStencilBackOperations(fail, zfail, zpass);
4688 }
4689 }
John Bauman66b8ab22014-05-06 15:57:45 -04004690}
4691
Nicolas Capenseb195b62015-04-28 17:18:42 -07004692GLboolean TestFenceNV(GLuint fence)
John Bauman66b8ab22014-05-06 15:57:45 -04004693{
Nicolas Capensf160b172014-11-26 11:58:23 -05004694 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004695
Nicolas Capensf160b172014-11-26 11:58:23 -05004696 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004697
Nicolas Capensf160b172014-11-26 11:58:23 -05004698 if(context)
4699 {
4700 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004701
Nicolas Capensf160b172014-11-26 11:58:23 -05004702 if(fenceObject == NULL)
4703 {
4704 return error(GL_INVALID_OPERATION, GL_TRUE);
4705 }
John Bauman66b8ab22014-05-06 15:57:45 -04004706
Nicolas Capensf160b172014-11-26 11:58:23 -05004707 return fenceObject->testFence();
4708 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05004709
Nicolas Capensf160b172014-11-26 11:58:23 -05004710 return GL_TRUE;
John Bauman66b8ab22014-05-06 15:57:45 -04004711}
4712
Nicolas Capenseb195b62015-04-28 17:18:42 -07004713void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4714 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04004715{
Nicolas Capensf160b172014-11-26 11:58:23 -05004716 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004717 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004718 target, level, internalformat, width, height, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004719
Nicolas Capensf160b172014-11-26 11:58:23 -05004720 if(!validImageSize(level, width, height))
4721 {
4722 return error(GL_INVALID_VALUE);
4723 }
John Bauman66b8ab22014-05-06 15:57:45 -04004724
Nicolas Capensf160b172014-11-26 11:58:23 -05004725 es2::Context *context = es2::getContext();
4726
4727 if(context)
4728 {
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004729 if(context->getClientVersion() < 3)
4730 {
4731 if(internalformat != format)
4732 {
4733 return error(GL_INVALID_OPERATION);
4734 }
4735 }
4736
4737 switch(format)
4738 {
4739 case GL_ALPHA:
4740 case GL_LUMINANCE:
4741 case GL_LUMINANCE_ALPHA:
4742 switch(type)
4743 {
4744 case GL_UNSIGNED_BYTE:
4745 case GL_FLOAT:
4746 case GL_HALF_FLOAT_OES:
4747 break;
4748 default:
4749 return error(GL_INVALID_ENUM);
4750 }
4751 break;
Alexis Hetued306182015-04-02 12:02:28 -04004752 case GL_RED:
4753 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004754 {
Alexis Hetued306182015-04-02 12:02:28 -04004755 case GL_R8:
4756 switch(type)
4757 {
4758 case GL_UNSIGNED_BYTE:
4759 break;
4760 default:
4761 return error(GL_INVALID_ENUM);
4762 }
4763 break;
4764 case GL_R8_SNORM:
4765 switch(type)
4766 {
4767 case GL_BYTE:
4768 break;
4769 default:
4770 return error(GL_INVALID_ENUM);
4771 }
4772 break;
4773 case GL_R16F:
4774 switch(type)
4775 {
4776 case GL_FLOAT:
4777 case GL_HALF_FLOAT:
4778 break;
4779 default:
4780 return error(GL_INVALID_ENUM);
4781 }
4782 break;
4783 case GL_R32F:
4784 switch(type)
4785 {
4786 case GL_FLOAT:
4787 break;
4788 default:
4789 return error(GL_INVALID_ENUM);
4790 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004791 break;
4792 default:
Alexis Hetued306182015-04-02 12:02:28 -04004793 return error(GL_INVALID_VALUE);
4794 }
4795 break;
4796 case GL_RED_INTEGER:
4797 switch(internalformat)
4798 {
4799 case GL_R8UI:
4800 switch(type)
4801 {
4802 case GL_UNSIGNED_BYTE:
4803 break;
4804 default:
4805 return error(GL_INVALID_ENUM);
4806 }
4807 break;
4808 case GL_R8I:
4809 switch(type)
4810 {
4811 case GL_BYTE:
4812 break;
4813 default:
4814 return error(GL_INVALID_ENUM);
4815 }
4816 break;
4817 case GL_R16UI:
4818 switch(type)
4819 {
4820 case GL_UNSIGNED_SHORT:
4821 break;
4822 default:
4823 return error(GL_INVALID_ENUM);
4824 }
4825 break;
4826 case GL_R16I:
4827 switch(type)
4828 {
4829 case GL_SHORT:
4830 break;
4831 default:
4832 return error(GL_INVALID_ENUM);
4833 }
4834 break;
4835 case GL_R32UI:
4836 switch(type)
4837 {
4838 case GL_UNSIGNED_INT:
4839 break;
4840 default:
4841 return error(GL_INVALID_ENUM);
4842 }
4843 break;
4844 case GL_R32I:
4845 switch(type)
4846 {
4847 case GL_INT:
4848 break;
4849 default:
4850 return error(GL_INVALID_ENUM);
4851 }
4852 break;
4853 default:
4854 return error(GL_INVALID_VALUE);
4855 }
4856 break;
4857 case GL_RG_INTEGER:
4858 switch(internalformat)
4859 {
4860 case GL_RG8UI:
4861 switch(type)
4862 {
4863 case GL_UNSIGNED_BYTE:
4864 break;
4865 default:
4866 return error(GL_INVALID_ENUM);
4867 }
4868 break;
4869 case GL_RG8I:
4870 switch(type)
4871 {
4872 case GL_BYTE:
4873 break;
4874 default:
4875 return error(GL_INVALID_ENUM);
4876 }
4877 break;
4878 case GL_RG16UI:
4879 switch(type)
4880 {
4881 case GL_UNSIGNED_SHORT:
4882 break;
4883 default:
4884 return error(GL_INVALID_ENUM);
4885 }
4886 break;
4887 case GL_RG16I:
4888 switch(type)
4889 {
4890 case GL_SHORT:
4891 break;
4892 default:
4893 return error(GL_INVALID_ENUM);
4894 }
4895 break;
4896 case GL_RG32UI:
4897 switch(type)
4898 {
4899 case GL_UNSIGNED_INT:
4900 break;
4901 default:
4902 return error(GL_INVALID_ENUM);
4903 }
4904 break;
4905 case GL_RG32I:
4906 switch(type)
4907 {
4908 case GL_INT:
4909 break;
4910 default:
4911 return error(GL_INVALID_ENUM);
4912 }
4913 break;
4914 default:
4915 return error(GL_INVALID_VALUE);
4916 }
4917 break;
4918 case GL_RGB_INTEGER:
4919 switch(internalformat)
4920 {
4921 case GL_RGB8UI:
4922 switch(type)
4923 {
4924 case GL_UNSIGNED_BYTE:
4925 break;
4926 default:
4927 return error(GL_INVALID_ENUM);
4928 }
4929 break;
4930 case GL_RGB8I:
4931 switch(type)
4932 {
4933 case GL_BYTE:
4934 break;
4935 default:
4936 return error(GL_INVALID_ENUM);
4937 }
4938 break;
4939 case GL_RGB16UI:
4940 switch(type)
4941 {
4942 case GL_UNSIGNED_SHORT:
4943 break;
4944 default:
4945 return error(GL_INVALID_ENUM);
4946 }
4947 break;
4948 case GL_RGB16I:
4949 switch(type)
4950 {
4951 case GL_SHORT:
4952 break;
4953 default:
4954 return error(GL_INVALID_ENUM);
4955 }
4956 break;
4957 case GL_RGB32UI:
4958 switch(type)
4959 {
4960 case GL_UNSIGNED_INT:
4961 break;
4962 default:
4963 return error(GL_INVALID_ENUM);
4964 }
4965 break;
4966 case GL_RGB32I:
4967 switch(type)
4968 {
4969 case GL_INT:
4970 break;
4971 default:
4972 return error(GL_INVALID_ENUM);
4973 }
4974 break;
4975 default:
4976 return error(GL_INVALID_VALUE);
4977 }
4978 break;
4979 case GL_RGBA_INTEGER:
4980 switch(internalformat)
4981 {
4982 case GL_RGBA8UI:
4983 switch(type)
4984 {
4985 case GL_UNSIGNED_BYTE:
4986 break;
4987 default:
4988 return error(GL_INVALID_ENUM);
4989 }
4990 break;
4991 case GL_RGBA8I:
4992 switch(type)
4993 {
4994 case GL_BYTE:
4995 break;
4996 default:
4997 return error(GL_INVALID_ENUM);
4998 }
4999 break;
5000 case GL_RGB10_A2UI:
5001 switch(type)
5002 {
5003 case GL_UNSIGNED_INT_2_10_10_10_REV:
5004 break;
5005 default:
5006 return error(GL_INVALID_ENUM);
5007 }
5008 break;
5009 case GL_RGBA16UI:
5010 switch(type)
5011 {
5012 case GL_UNSIGNED_SHORT:
5013 break;
5014 default:
5015 return error(GL_INVALID_ENUM);
5016 }
5017 break;
5018 case GL_RGBA16I:
5019 switch(type)
5020 {
5021 case GL_SHORT:
5022 break;
5023 default:
5024 return error(GL_INVALID_ENUM);
5025 }
5026 break;
5027 case GL_RGBA32UI:
5028 switch(type)
5029 {
5030 case GL_INT:
5031 break;
5032 default:
5033 return error(GL_INVALID_ENUM);
5034 }
5035 break;
5036 case GL_RGBA32I:
5037 switch(type)
5038 {
5039 case GL_UNSIGNED_INT:
5040 break;
5041 default:
5042 return error(GL_INVALID_ENUM);
5043 }
5044 break;
5045 default:
5046 return error(GL_INVALID_VALUE);
5047 }
5048 break;
5049 case GL_RG:
5050 switch(internalformat)
5051 {
5052 case GL_RG8:
5053 switch(type)
5054 {
5055 case GL_UNSIGNED_BYTE:
5056 break;
5057 default:
5058 return error(GL_INVALID_ENUM);
5059 }
5060 break;
5061 case GL_RG8_SNORM:
5062 switch(type)
5063 {
5064 case GL_BYTE:
5065 break;
5066 default:
5067 return error(GL_INVALID_ENUM);
5068 }
5069 break;
5070 case GL_RG16F:
5071 switch(type)
5072 {
5073 case GL_FLOAT:
5074 case GL_HALF_FLOAT:
5075 break;
5076 default:
5077 return error(GL_INVALID_ENUM);
5078 }
5079 break;
5080 case GL_RG32F:
5081 switch(type)
5082 {
5083 case GL_FLOAT:
5084 break;
5085 default:
5086 return error(GL_INVALID_ENUM);
5087 }
5088 break;
5089 default:
5090 return error(GL_INVALID_VALUE);
5091 }
5092 break;
5093 case GL_RGB:
5094 switch(internalformat)
5095 {
5096 case GL_RGB:
5097 switch(type)
5098 {
5099 case GL_UNSIGNED_BYTE:
5100 case GL_UNSIGNED_SHORT_5_6_5:
5101 case GL_FLOAT:
5102 case GL_HALF_FLOAT_OES:
5103 break;
5104 default:
5105 return error(GL_INVALID_ENUM);
5106 }
5107 break;
5108 case GL_RGB8:
5109 switch(type)
5110 {
5111 case GL_UNSIGNED_BYTE:
5112 break;
5113 default:
5114 return error(GL_INVALID_ENUM);
5115 }
5116 break;
5117 case GL_SRGB8:
5118 switch(type)
5119 {
5120 case GL_UNSIGNED_BYTE:
5121 break;
5122 default:
5123 return error(GL_INVALID_ENUM);
5124 }
5125 break;
5126 case GL_RGB565:
5127 switch(type)
5128 {
5129 case GL_UNSIGNED_BYTE:
5130 case GL_UNSIGNED_SHORT_5_6_5:
5131 break;
5132 default:
5133 return error(GL_INVALID_ENUM);
5134 }
5135 break;
5136 case GL_RGB8_SNORM:
5137 switch(type)
5138 {
5139 case GL_BYTE:
5140 break;
5141 default:
5142 return error(GL_INVALID_ENUM);
5143 }
5144 break;
5145 case GL_R11F_G11F_B10F:
5146 switch(type)
5147 {
5148 case GL_UNSIGNED_INT_10F_11F_11F_REV:
5149 case GL_FLOAT:
5150 case GL_HALF_FLOAT:
5151 break;
5152 default:
5153 return error(GL_INVALID_ENUM);
5154 }
5155 break;
5156 case GL_RGB9_E5:
5157 switch(type)
5158 {
5159 case GL_UNSIGNED_INT_5_9_9_9_REV:
5160 case GL_FLOAT:
5161 case GL_HALF_FLOAT:
5162 break;
5163 default:
5164 return error(GL_INVALID_ENUM);
5165 }
5166 break;
5167 case GL_RGB16F:
5168 switch(type)
5169 {
5170 case GL_FLOAT:
5171 case GL_HALF_FLOAT:
5172 break;
5173 default:
5174 return error(GL_INVALID_ENUM);
5175 }
5176 break;
5177 case GL_RGB32F:
5178 switch(type)
5179 {
5180 case GL_FLOAT:
5181 break;
5182 default:
5183 return error(GL_INVALID_ENUM);
5184 }
5185 break;
5186 default:
5187 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005188 }
5189 break;
5190 case GL_RGBA:
Alexis Hetued306182015-04-02 12:02:28 -04005191 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005192 {
Alexis Hetued306182015-04-02 12:02:28 -04005193 case GL_RGBA:
5194 switch(type)
5195 {
5196 case GL_UNSIGNED_BYTE:
5197 case GL_UNSIGNED_SHORT_4_4_4_4:
5198 case GL_UNSIGNED_SHORT_5_5_5_1:
5199 case GL_FLOAT:
5200 case GL_HALF_FLOAT_OES:
5201 break;
5202 default:
5203 return error(GL_INVALID_ENUM);
5204 }
5205 break;
5206 case GL_RGBA8:
5207 switch(type)
5208 {
5209 case GL_UNSIGNED_BYTE:
5210 break;
5211 default:
5212 return error(GL_INVALID_ENUM);
5213 }
5214 break;
5215 case GL_SRGB8_ALPHA8:
5216 switch(type)
5217 {
5218 case GL_UNSIGNED_BYTE:
5219 break;
5220 default:
5221 return error(GL_INVALID_ENUM);
5222 }
5223 break;
5224 case GL_RGB5_A1:
5225 switch(type)
5226 {
5227 case GL_UNSIGNED_BYTE:
5228 case GL_UNSIGNED_SHORT_5_5_5_1:
5229 case GL_UNSIGNED_INT_2_10_10_10_REV:
5230 break;
5231 default:
5232 return error(GL_INVALID_ENUM);
5233 }
5234 break;
5235 case GL_RGBA8_SNORM:
5236 switch(type)
5237 {
5238 case GL_BYTE:
5239 break;
5240 default:
5241 return error(GL_INVALID_ENUM);
5242 }
5243 break;
5244 case GL_RGBA4:
5245 switch(type)
5246 {
5247 case GL_UNSIGNED_BYTE:
5248 case GL_UNSIGNED_SHORT_4_4_4_4:
5249 break;
5250 default:
5251 return error(GL_INVALID_ENUM);
5252 }
5253 break;
5254 case GL_RGB10_A2:
5255 switch(type)
5256 {
5257 case GL_UNSIGNED_INT_2_10_10_10_REV:
5258 break;
5259 default:
5260 return error(GL_INVALID_ENUM);
5261 }
5262 break;
5263 case GL_RGBA16F:
5264 switch(type)
5265 {
5266 case GL_FLOAT:
5267 case GL_HALF_FLOAT:
5268 break;
5269 default:
5270 return error(GL_INVALID_ENUM);
5271 }
5272 break;
5273 case GL_RGBA32F:
5274 switch(type)
5275 {
5276 case GL_FLOAT:
5277 break;
5278 default:
5279 return error(GL_INVALID_ENUM);
5280 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005281 break;
5282 default:
Alexis Hetued306182015-04-02 12:02:28 -04005283 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005284 }
5285 break;
5286 case GL_BGRA_EXT:
5287 switch(type)
5288 {
5289 case GL_UNSIGNED_BYTE:
5290 break;
5291 default:
5292 return error(GL_INVALID_ENUM);
5293 }
5294 break;
5295 case GL_ETC1_RGB8_OES:
5296 return error(GL_INVALID_OPERATION);
5297 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5298 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5299 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5300 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5301 if(S3TC_SUPPORT)
5302 {
5303 return error(GL_INVALID_OPERATION);
5304 }
5305 else
5306 {
5307 return error(GL_INVALID_ENUM);
5308 }
5309 case GL_DEPTH_COMPONENT:
Alexis Hetued306182015-04-02 12:02:28 -04005310 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005311 {
Alexis Hetued306182015-04-02 12:02:28 -04005312 case GL_DEPTH_COMPONENT:
5313 case GL_DEPTH_COMPONENT16:
5314 switch(type)
5315 {
5316 case GL_UNSIGNED_SHORT:
5317 case GL_UNSIGNED_INT:
5318 break;
5319 default:
5320 return error(GL_INVALID_ENUM);
5321 }
5322 break;
5323 case GL_DEPTH_COMPONENT24:
5324 switch(type)
5325 {
5326 case GL_UNSIGNED_INT:
5327 break;
5328 default:
5329 return error(GL_INVALID_ENUM);
5330 }
5331 break;
5332 case GL_DEPTH_COMPONENT32F:
5333 switch(type)
5334 {
5335 case GL_UNSIGNED_INT:
5336 break;
5337 default:
5338 return error(GL_INVALID_ENUM);
5339 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005340 break;
5341 default:
Alexis Hetued306182015-04-02 12:02:28 -04005342 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005343 }
5344 break;
5345 case GL_DEPTH_STENCIL_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005346 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005347 {
Alexis Hetued306182015-04-02 12:02:28 -04005348 case GL_DEPTH_STENCIL_OES:
5349 case GL_DEPTH24_STENCIL8:
5350 switch(type)
5351 {
5352 case GL_UNSIGNED_INT_24_8_OES:
5353 break;
5354 default:
5355 return error(GL_INVALID_ENUM);
5356 }
5357 break;
5358 case GL_DEPTH32F_STENCIL8:
5359 switch(type)
5360 {
5361 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
5362 break;
5363 default:
5364 return error(GL_INVALID_ENUM);
5365 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005366 break;
5367 default:
Alexis Hetued306182015-04-02 12:02:28 -04005368 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005369 }
5370 break;
5371 default:
5372 return error(GL_INVALID_VALUE);
5373 }
5374
5375 if(border != 0)
5376 {
5377 return error(GL_INVALID_VALUE);
5378 }
5379
Nicolas Capensf160b172014-11-26 11:58:23 -05005380 switch(target)
5381 {
Nicolas Capens22658242014-11-29 00:31:41 -05005382 case GL_TEXTURE_2D:
Nicolas Capensf160b172014-11-26 11:58:23 -05005383 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5384 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
John Bauman66b8ab22014-05-06 15:57:45 -04005385 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005386 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005387 }
5388 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005389 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5390 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5391 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5392 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5393 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5394 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
Nicolas Capensf160b172014-11-26 11:58:23 -05005395 if(width != height)
John Bauman66b8ab22014-05-06 15:57:45 -04005396 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005397 return error(GL_INVALID_VALUE);
5398 }
5399
5400 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5401 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5402 {
5403 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005404 }
5405 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005406 default:
Nicolas Capensf160b172014-11-26 11:58:23 -05005407 return error(GL_INVALID_ENUM);
5408 }
John Bauman66b8ab22014-05-06 15:57:45 -04005409
Nicolas Capensf160b172014-11-26 11:58:23 -05005410 if(target == GL_TEXTURE_2D)
5411 {
5412 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005413
Nicolas Capensf160b172014-11-26 11:58:23 -05005414 if(!texture)
5415 {
5416 return error(GL_INVALID_OPERATION);
5417 }
John Bauman66b8ab22014-05-06 15:57:45 -04005418
Nicolas Capensf160b172014-11-26 11:58:23 -05005419 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
5420 }
5421 else
5422 {
5423 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04005424
Nicolas Capensf160b172014-11-26 11:58:23 -05005425 if(!texture)
5426 {
5427 return error(GL_INVALID_OPERATION);
5428 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005429
Nicolas Capensf160b172014-11-26 11:58:23 -05005430 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
5431 }
5432 }
John Bauman66b8ab22014-05-06 15:57:45 -04005433}
5434
Nicolas Capenseb195b62015-04-28 17:18:42 -07005435void TexParameterf(GLenum target, GLenum pname, GLfloat param)
John Bauman66b8ab22014-05-06 15:57:45 -04005436{
Nicolas Capensf160b172014-11-26 11:58:23 -05005437 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005438
Nicolas Capensf160b172014-11-26 11:58:23 -05005439 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005440
Nicolas Capensf160b172014-11-26 11:58:23 -05005441 if(context)
5442 {
5443 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005444
Alexis Hetued306182015-04-02 12:02:28 -04005445 egl::GLint clientVersion = context->getClientVersion();
5446
Nicolas Capensf160b172014-11-26 11:58:23 -05005447 switch(target)
5448 {
5449 case GL_TEXTURE_2D:
5450 texture = context->getTexture2D();
5451 break;
Alexis Hetued306182015-04-02 12:02:28 -04005452 case GL_TEXTURE_2D_ARRAY:
5453 if(clientVersion < 3)
5454 {
5455 return error(GL_INVALID_ENUM);
5456 }
5457 else
5458 {
5459 UNIMPLEMENTED();
5460 texture = context->getTexture3D();
5461 break;
5462 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005463 case GL_TEXTURE_3D_OES:
5464 texture = context->getTexture3D();
5465 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005466 case GL_TEXTURE_CUBE_MAP:
5467 texture = context->getTextureCubeMap();
5468 break;
5469 case GL_TEXTURE_EXTERNAL_OES:
5470 texture = context->getTextureExternal();
5471 break;
5472 default:
5473 return error(GL_INVALID_ENUM);
5474 }
John Bauman66b8ab22014-05-06 15:57:45 -04005475
Nicolas Capensf160b172014-11-26 11:58:23 -05005476 switch(pname)
5477 {
5478 case GL_TEXTURE_WRAP_S:
5479 if(!texture->setWrapS((GLenum)param))
5480 {
5481 return error(GL_INVALID_ENUM);
5482 }
5483 break;
5484 case GL_TEXTURE_WRAP_T:
5485 if(!texture->setWrapT((GLenum)param))
5486 {
5487 return error(GL_INVALID_ENUM);
5488 }
5489 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005490 case GL_TEXTURE_WRAP_R_OES:
5491 if(!texture->setWrapR((GLenum)param))
5492 {
5493 return error(GL_INVALID_ENUM);
5494 }
5495 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005496 case GL_TEXTURE_MIN_FILTER:
5497 if(!texture->setMinFilter((GLenum)param))
5498 {
5499 return error(GL_INVALID_ENUM);
5500 }
5501 break;
5502 case GL_TEXTURE_MAG_FILTER:
5503 if(!texture->setMagFilter((GLenum)param))
5504 {
5505 return error(GL_INVALID_ENUM);
5506 }
5507 break;
5508 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5509 if(!texture->setMaxAnisotropy(param))
5510 {
5511 return error(GL_INVALID_VALUE);
5512 }
5513 break;
Alexis Hetued306182015-04-02 12:02:28 -04005514 case GL_TEXTURE_BASE_LEVEL:
5515 if(clientVersion < 3 || !texture->setBaseLevel((GLint)param))
5516 {
5517 return error(GL_INVALID_VALUE);
5518 }
5519 break;
5520 case GL_TEXTURE_COMPARE_FUNC:
5521 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5522 {
5523 return error(GL_INVALID_VALUE);
5524 }
5525 break;
5526 case GL_TEXTURE_COMPARE_MODE:
5527 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5528 {
5529 return error(GL_INVALID_VALUE);
5530 }
5531 break;
5532 case GL_TEXTURE_IMMUTABLE_FORMAT:
5533 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5534 {
5535 return error(GL_INVALID_VALUE);
5536 }
5537 break;
5538 case GL_TEXTURE_MAX_LEVEL:
5539 if(clientVersion < 3 || !texture->setMaxLevel((GLint)param))
5540 {
5541 return error(GL_INVALID_VALUE);
5542 }
5543 break;
5544 case GL_TEXTURE_MAX_LOD:
5545 if(clientVersion < 3 || !texture->setMaxLOD(param))
5546 {
5547 return error(GL_INVALID_VALUE);
5548 }
5549 break;
5550 case GL_TEXTURE_MIN_LOD:
5551 if(clientVersion < 3 || !texture->setMinLOD(param))
5552 {
5553 return error(GL_INVALID_VALUE);
5554 }
5555 break;
5556 case GL_TEXTURE_SWIZZLE_R:
5557 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5558 {
5559 return error(GL_INVALID_VALUE);
5560 }
5561 break;
5562 case GL_TEXTURE_SWIZZLE_G:
5563 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5564 {
5565 return error(GL_INVALID_VALUE);
5566 }
5567 break;
5568 case GL_TEXTURE_SWIZZLE_B:
5569 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5570 {
5571 return error(GL_INVALID_VALUE);
5572 }
5573 break;
5574 case GL_TEXTURE_SWIZZLE_A:
5575 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5576 {
5577 return error(GL_INVALID_VALUE);
5578 }
5579 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005580 default:
5581 return error(GL_INVALID_ENUM);
5582 }
5583 }
John Bauman66b8ab22014-05-06 15:57:45 -04005584}
5585
Nicolas Capenseb195b62015-04-28 17:18:42 -07005586void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04005587{
Nicolas Capensf160b172014-11-26 11:58:23 -05005588 glTexParameterf(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005589}
5590
Nicolas Capenseb195b62015-04-28 17:18:42 -07005591void TexParameteri(GLenum target, GLenum pname, GLint param)
John Bauman66b8ab22014-05-06 15:57:45 -04005592{
Nicolas Capensf160b172014-11-26 11:58:23 -05005593 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005594
Nicolas Capensf160b172014-11-26 11:58:23 -05005595 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005596
Nicolas Capensf160b172014-11-26 11:58:23 -05005597 if(context)
5598 {
5599 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005600
Alexis Hetued306182015-04-02 12:02:28 -04005601 egl::GLint clientVersion = context->getClientVersion();
5602
Nicolas Capensf160b172014-11-26 11:58:23 -05005603 switch(target)
5604 {
5605 case GL_TEXTURE_2D:
5606 texture = context->getTexture2D();
5607 break;
Alexis Hetued306182015-04-02 12:02:28 -04005608 case GL_TEXTURE_2D_ARRAY:
5609 if(clientVersion < 3)
5610 {
5611 return error(GL_INVALID_ENUM);
5612 }
5613 else
5614 {
5615 UNIMPLEMENTED();
5616 texture = context->getTexture3D();
5617 break;
5618 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005619 case GL_TEXTURE_3D_OES:
5620 texture = context->getTexture3D();
5621 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005622 case GL_TEXTURE_CUBE_MAP:
5623 texture = context->getTextureCubeMap();
5624 break;
5625 case GL_TEXTURE_EXTERNAL_OES:
Alexis Hetuf7be67f2015-02-11 16:11:07 -05005626 texture = context->getTextureExternal();
5627 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005628 default:
5629 return error(GL_INVALID_ENUM);
5630 }
John Bauman66b8ab22014-05-06 15:57:45 -04005631
Nicolas Capensf160b172014-11-26 11:58:23 -05005632 switch(pname)
5633 {
5634 case GL_TEXTURE_WRAP_S:
5635 if(!texture->setWrapS((GLenum)param))
5636 {
5637 return error(GL_INVALID_ENUM);
5638 }
5639 break;
5640 case GL_TEXTURE_WRAP_T:
5641 if(!texture->setWrapT((GLenum)param))
5642 {
5643 return error(GL_INVALID_ENUM);
5644 }
5645 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005646 case GL_TEXTURE_WRAP_R_OES:
5647 if(!texture->setWrapR((GLenum)param))
5648 {
5649 return error(GL_INVALID_ENUM);
5650 }
5651 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005652 case GL_TEXTURE_MIN_FILTER:
5653 if(!texture->setMinFilter((GLenum)param))
5654 {
5655 return error(GL_INVALID_ENUM);
5656 }
5657 break;
5658 case GL_TEXTURE_MAG_FILTER:
5659 if(!texture->setMagFilter((GLenum)param))
5660 {
5661 return error(GL_INVALID_ENUM);
5662 }
5663 break;
5664 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5665 if(!texture->setMaxAnisotropy((GLfloat)param))
5666 {
5667 return error(GL_INVALID_VALUE);
5668 }
5669 break;
Alexis Hetued306182015-04-02 12:02:28 -04005670 case GL_TEXTURE_BASE_LEVEL:
5671 if(clientVersion < 3 || !texture->setBaseLevel(param))
5672 {
5673 return error(GL_INVALID_VALUE);
5674 }
5675 break;
5676 case GL_TEXTURE_COMPARE_FUNC:
5677 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5678 {
5679 return error(GL_INVALID_VALUE);
5680 }
5681 break;
5682 case GL_TEXTURE_COMPARE_MODE:
5683 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5684 {
5685 return error(GL_INVALID_VALUE);
5686 }
5687 case GL_TEXTURE_IMMUTABLE_FORMAT:
5688 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5689 {
5690 return error(GL_INVALID_VALUE);
5691 }
5692 break;
5693 case GL_TEXTURE_MAX_LEVEL:
5694 if(clientVersion < 3 || !texture->setMaxLevel(param))
5695 {
5696 return error(GL_INVALID_VALUE);
5697 }
5698 break;
5699 case GL_TEXTURE_MAX_LOD:
5700 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5701 {
5702 return error(GL_INVALID_VALUE);
5703 }
5704 break;
5705 case GL_TEXTURE_MIN_LOD:
5706 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5707 {
5708 return error(GL_INVALID_VALUE);
5709 }
5710 break;
5711 case GL_TEXTURE_SWIZZLE_R:
5712 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5713 {
5714 return error(GL_INVALID_VALUE);
5715 }
5716 break;
5717 case GL_TEXTURE_SWIZZLE_G:
5718 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5719 {
5720 return error(GL_INVALID_VALUE);
5721 }
5722 break;
5723 case GL_TEXTURE_SWIZZLE_B:
5724 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5725 {
5726 return error(GL_INVALID_VALUE);
5727 }
5728 break;
5729 case GL_TEXTURE_SWIZZLE_A:
5730 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5731 {
5732 return error(GL_INVALID_VALUE);
5733 }
5734 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005735 default:
5736 return error(GL_INVALID_ENUM);
5737 }
5738 }
John Bauman66b8ab22014-05-06 15:57:45 -04005739}
5740
Nicolas Capenseb195b62015-04-28 17:18:42 -07005741void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04005742{
Nicolas Capensf160b172014-11-26 11:58:23 -05005743 glTexParameteri(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005744}
5745
Nicolas Capenseb195b62015-04-28 17:18:42 -07005746void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5747 GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04005748{
Nicolas Capensf160b172014-11-26 11:58:23 -05005749 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5750 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07005751 "const GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05005752 target, level, xoffset, yoffset, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04005753
Nicolas Capensf160b172014-11-26 11:58:23 -05005754 if(!es2::IsTextureTarget(target))
5755 {
5756 return error(GL_INVALID_ENUM);
5757 }
John Bauman66b8ab22014-05-06 15:57:45 -04005758
Nicolas Capensf160b172014-11-26 11:58:23 -05005759 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5760 {
5761 return error(GL_INVALID_VALUE);
5762 }
John Bauman66b8ab22014-05-06 15:57:45 -04005763
Nicolas Capensf160b172014-11-26 11:58:23 -05005764 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5765 {
5766 return error(GL_INVALID_VALUE);
5767 }
John Bauman66b8ab22014-05-06 15:57:45 -04005768
Nicolas Capensf160b172014-11-26 11:58:23 -05005769 if(!es2::CheckTextureFormatType(format, type))
5770 {
5771 return error(GL_INVALID_ENUM);
5772 }
John Bauman66b8ab22014-05-06 15:57:45 -04005773
Nicolas Capensf160b172014-11-26 11:58:23 -05005774 if(width == 0 || height == 0 || pixels == NULL)
5775 {
5776 return;
5777 }
John Bauman66b8ab22014-05-06 15:57:45 -04005778
Nicolas Capensf160b172014-11-26 11:58:23 -05005779 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005780
Nicolas Capensf160b172014-11-26 11:58:23 -05005781 if(context)
5782 {
Alexis Hetub027aa92015-01-19 15:56:12 -05005783 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05005784 {
5785 return error(GL_INVALID_VALUE);
5786 }
John Bauman66b8ab22014-05-06 15:57:45 -04005787
Nicolas Capensf160b172014-11-26 11:58:23 -05005788 if(target == GL_TEXTURE_2D)
5789 {
5790 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005791
Nicolas Capensf160b172014-11-26 11:58:23 -05005792 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5793 {
5794 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5795 }
5796 }
5797 else if(es2::IsCubemapTextureTarget(target))
5798 {
5799 es2::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens08e90f02014-11-21 12:49:12 -05005800
Nicolas Capensf160b172014-11-26 11:58:23 -05005801 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5802 {
5803 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5804 }
5805 }
5806 else
5807 {
5808 UNREACHABLE();
5809 }
5810 }
John Bauman66b8ab22014-05-06 15:57:45 -04005811}
5812
Nicolas Capenseb195b62015-04-28 17:18:42 -07005813void Uniform1f(GLint location, GLfloat x)
John Bauman66b8ab22014-05-06 15:57:45 -04005814{
Nicolas Capensf160b172014-11-26 11:58:23 -05005815 glUniform1fv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005816}
5817
Nicolas Capenseb195b62015-04-28 17:18:42 -07005818void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
John Bauman66b8ab22014-05-06 15:57:45 -04005819{
Nicolas Capens4be33702015-04-28 15:13:30 -07005820 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005821
Nicolas Capensf160b172014-11-26 11:58:23 -05005822 if(count < 0)
5823 {
5824 return error(GL_INVALID_VALUE);
5825 }
John Bauman66b8ab22014-05-06 15:57:45 -04005826
Nicolas Capensf160b172014-11-26 11:58:23 -05005827 if(location == -1)
5828 {
5829 return;
5830 }
John Bauman66b8ab22014-05-06 15:57:45 -04005831
Nicolas Capensf160b172014-11-26 11:58:23 -05005832 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005833
Nicolas Capensf160b172014-11-26 11:58:23 -05005834 if(context)
5835 {
5836 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005837
Nicolas Capensf160b172014-11-26 11:58:23 -05005838 if(!program)
5839 {
5840 return error(GL_INVALID_OPERATION);
5841 }
John Bauman66b8ab22014-05-06 15:57:45 -04005842
Nicolas Capensf160b172014-11-26 11:58:23 -05005843 if(!program->setUniform1fv(location, count, v))
5844 {
5845 return error(GL_INVALID_OPERATION);
5846 }
5847 }
John Bauman66b8ab22014-05-06 15:57:45 -04005848}
5849
Nicolas Capenseb195b62015-04-28 17:18:42 -07005850void Uniform1i(GLint location, GLint x)
John Bauman66b8ab22014-05-06 15:57:45 -04005851{
Nicolas Capensf160b172014-11-26 11:58:23 -05005852 glUniform1iv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005853}
5854
Nicolas Capenseb195b62015-04-28 17:18:42 -07005855void Uniform1iv(GLint location, GLsizei count, const GLint* v)
John Bauman66b8ab22014-05-06 15:57:45 -04005856{
Nicolas Capens4be33702015-04-28 15:13:30 -07005857 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005858
Nicolas Capensf160b172014-11-26 11:58:23 -05005859 if(count < 0)
5860 {
5861 return error(GL_INVALID_VALUE);
5862 }
John Bauman66b8ab22014-05-06 15:57:45 -04005863
Nicolas Capensf160b172014-11-26 11:58:23 -05005864 if(location == -1)
5865 {
5866 return;
5867 }
John Bauman66b8ab22014-05-06 15:57:45 -04005868
Nicolas Capensf160b172014-11-26 11:58:23 -05005869 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005870
Nicolas Capensf160b172014-11-26 11:58:23 -05005871 if(context)
5872 {
5873 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005874
Nicolas Capensf160b172014-11-26 11:58:23 -05005875 if(!program)
5876 {
5877 return error(GL_INVALID_OPERATION);
5878 }
John Bauman66b8ab22014-05-06 15:57:45 -04005879
Nicolas Capensf160b172014-11-26 11:58:23 -05005880 if(!program->setUniform1iv(location, count, v))
5881 {
5882 return error(GL_INVALID_OPERATION);
5883 }
5884 }
John Bauman66b8ab22014-05-06 15:57:45 -04005885}
5886
Nicolas Capenseb195b62015-04-28 17:18:42 -07005887void Uniform2f(GLint location, GLfloat x, GLfloat y)
John Bauman66b8ab22014-05-06 15:57:45 -04005888{
Nicolas Capensf160b172014-11-26 11:58:23 -05005889 GLfloat xy[2] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005890
Nicolas Capensf160b172014-11-26 11:58:23 -05005891 glUniform2fv(location, 1, (GLfloat*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005892}
5893
Nicolas Capenseb195b62015-04-28 17:18:42 -07005894void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
John Bauman66b8ab22014-05-06 15:57:45 -04005895{
Nicolas Capens4be33702015-04-28 15:13:30 -07005896 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005897
Nicolas Capensf160b172014-11-26 11:58:23 -05005898 if(count < 0)
5899 {
5900 return error(GL_INVALID_VALUE);
5901 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005902
Nicolas Capensf160b172014-11-26 11:58:23 -05005903 if(location == -1)
5904 {
5905 return;
5906 }
John Bauman66b8ab22014-05-06 15:57:45 -04005907
Nicolas Capensf160b172014-11-26 11:58:23 -05005908 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005909
Nicolas Capensf160b172014-11-26 11:58:23 -05005910 if(context)
5911 {
5912 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005913
Nicolas Capensf160b172014-11-26 11:58:23 -05005914 if(!program)
5915 {
5916 return error(GL_INVALID_OPERATION);
5917 }
John Bauman66b8ab22014-05-06 15:57:45 -04005918
Nicolas Capensf160b172014-11-26 11:58:23 -05005919 if(!program->setUniform2fv(location, count, v))
5920 {
5921 return error(GL_INVALID_OPERATION);
5922 }
5923 }
John Bauman66b8ab22014-05-06 15:57:45 -04005924}
5925
Nicolas Capenseb195b62015-04-28 17:18:42 -07005926void Uniform2i(GLint location, GLint x, GLint y)
John Bauman66b8ab22014-05-06 15:57:45 -04005927{
Nicolas Capensf160b172014-11-26 11:58:23 -05005928 GLint xy[4] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005929
Nicolas Capensf160b172014-11-26 11:58:23 -05005930 glUniform2iv(location, 1, (GLint*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005931}
5932
Nicolas Capenseb195b62015-04-28 17:18:42 -07005933void Uniform2iv(GLint location, GLsizei count, const GLint* v)
John Bauman66b8ab22014-05-06 15:57:45 -04005934{
Nicolas Capens4be33702015-04-28 15:13:30 -07005935 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005936
Nicolas Capensf160b172014-11-26 11:58:23 -05005937 if(count < 0)
5938 {
5939 return error(GL_INVALID_VALUE);
5940 }
John Bauman66b8ab22014-05-06 15:57:45 -04005941
Nicolas Capensf160b172014-11-26 11:58:23 -05005942 if(location == -1)
5943 {
5944 return;
5945 }
John Bauman66b8ab22014-05-06 15:57:45 -04005946
Nicolas Capensf160b172014-11-26 11:58:23 -05005947 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005948
Nicolas Capensf160b172014-11-26 11:58:23 -05005949 if(context)
5950 {
5951 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005952
Nicolas Capensf160b172014-11-26 11:58:23 -05005953 if(!program)
5954 {
5955 return error(GL_INVALID_OPERATION);
5956 }
John Bauman66b8ab22014-05-06 15:57:45 -04005957
Nicolas Capensf160b172014-11-26 11:58:23 -05005958 if(!program->setUniform2iv(location, count, v))
5959 {
5960 return error(GL_INVALID_OPERATION);
5961 }
5962 }
John Bauman66b8ab22014-05-06 15:57:45 -04005963}
5964
Nicolas Capenseb195b62015-04-28 17:18:42 -07005965void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
John Bauman66b8ab22014-05-06 15:57:45 -04005966{
Nicolas Capensf160b172014-11-26 11:58:23 -05005967 GLfloat xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04005968
Nicolas Capensf160b172014-11-26 11:58:23 -05005969 glUniform3fv(location, 1, (GLfloat*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04005970}
5971
Nicolas Capenseb195b62015-04-28 17:18:42 -07005972void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
John Bauman66b8ab22014-05-06 15:57:45 -04005973{
Nicolas Capens4be33702015-04-28 15:13:30 -07005974 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005975
Nicolas Capensf160b172014-11-26 11:58:23 -05005976 if(count < 0)
5977 {
5978 return error(GL_INVALID_VALUE);
5979 }
John Bauman66b8ab22014-05-06 15:57:45 -04005980
Nicolas Capensf160b172014-11-26 11:58:23 -05005981 if(location == -1)
5982 {
5983 return;
5984 }
John Bauman66b8ab22014-05-06 15:57:45 -04005985
Nicolas Capensf160b172014-11-26 11:58:23 -05005986 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005987
Nicolas Capensf160b172014-11-26 11:58:23 -05005988 if(context)
5989 {
5990 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005991
Nicolas Capensf160b172014-11-26 11:58:23 -05005992 if(!program)
5993 {
5994 return error(GL_INVALID_OPERATION);
5995 }
John Bauman66b8ab22014-05-06 15:57:45 -04005996
Nicolas Capensf160b172014-11-26 11:58:23 -05005997 if(!program->setUniform3fv(location, count, v))
5998 {
5999 return error(GL_INVALID_OPERATION);
6000 }
6001 }
John Bauman66b8ab22014-05-06 15:57:45 -04006002}
6003
Nicolas Capenseb195b62015-04-28 17:18:42 -07006004void Uniform3i(GLint location, GLint x, GLint y, GLint z)
John Bauman66b8ab22014-05-06 15:57:45 -04006005{
Nicolas Capensf160b172014-11-26 11:58:23 -05006006 GLint xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04006007
Nicolas Capensf160b172014-11-26 11:58:23 -05006008 glUniform3iv(location, 1, (GLint*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04006009}
6010
Nicolas Capenseb195b62015-04-28 17:18:42 -07006011void Uniform3iv(GLint location, GLsizei count, const GLint* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006012{
Nicolas Capens4be33702015-04-28 15:13:30 -07006013 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006014
Nicolas Capensf160b172014-11-26 11:58:23 -05006015 if(count < 0)
6016 {
6017 return error(GL_INVALID_VALUE);
6018 }
John Bauman66b8ab22014-05-06 15:57:45 -04006019
Nicolas Capensf160b172014-11-26 11:58:23 -05006020 if(location == -1)
6021 {
6022 return;
6023 }
John Bauman66b8ab22014-05-06 15:57:45 -04006024
Nicolas Capensf160b172014-11-26 11:58:23 -05006025 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006026
Nicolas Capensf160b172014-11-26 11:58:23 -05006027 if(context)
6028 {
6029 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006030
Nicolas Capensf160b172014-11-26 11:58:23 -05006031 if(!program)
6032 {
6033 return error(GL_INVALID_OPERATION);
6034 }
John Bauman66b8ab22014-05-06 15:57:45 -04006035
Nicolas Capensf160b172014-11-26 11:58:23 -05006036 if(!program->setUniform3iv(location, count, v))
6037 {
6038 return error(GL_INVALID_OPERATION);
6039 }
6040 }
John Bauman66b8ab22014-05-06 15:57:45 -04006041}
6042
Nicolas Capenseb195b62015-04-28 17:18:42 -07006043void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
John Bauman66b8ab22014-05-06 15:57:45 -04006044{
Nicolas Capensf160b172014-11-26 11:58:23 -05006045 GLfloat xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04006046
Nicolas Capensf160b172014-11-26 11:58:23 -05006047 glUniform4fv(location, 1, (GLfloat*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04006048}
6049
Nicolas Capenseb195b62015-04-28 17:18:42 -07006050void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006051{
Nicolas Capens4be33702015-04-28 15:13:30 -07006052 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006053
Nicolas Capensf160b172014-11-26 11:58:23 -05006054 if(count < 0)
6055 {
6056 return error(GL_INVALID_VALUE);
6057 }
John Bauman66b8ab22014-05-06 15:57:45 -04006058
Nicolas Capensf160b172014-11-26 11:58:23 -05006059 if(location == -1)
6060 {
6061 return;
6062 }
John Bauman66b8ab22014-05-06 15:57:45 -04006063
Nicolas Capensf160b172014-11-26 11:58:23 -05006064 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006065
Nicolas Capensf160b172014-11-26 11:58:23 -05006066 if(context)
6067 {
6068 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006069
Nicolas Capensf160b172014-11-26 11:58:23 -05006070 if(!program)
6071 {
6072 return error(GL_INVALID_OPERATION);
6073 }
John Bauman66b8ab22014-05-06 15:57:45 -04006074
Nicolas Capensf160b172014-11-26 11:58:23 -05006075 if(!program->setUniform4fv(location, count, v))
6076 {
6077 return error(GL_INVALID_OPERATION);
6078 }
6079 }
John Bauman66b8ab22014-05-06 15:57:45 -04006080}
6081
Nicolas Capenseb195b62015-04-28 17:18:42 -07006082void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
John Bauman66b8ab22014-05-06 15:57:45 -04006083{
Nicolas Capensf160b172014-11-26 11:58:23 -05006084 GLint xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04006085
Nicolas Capensf160b172014-11-26 11:58:23 -05006086 glUniform4iv(location, 1, (GLint*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04006087}
6088
Nicolas Capenseb195b62015-04-28 17:18:42 -07006089void Uniform4iv(GLint location, GLsizei count, const GLint* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006090{
Nicolas Capens4be33702015-04-28 15:13:30 -07006091 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006092
Nicolas Capensf160b172014-11-26 11:58:23 -05006093 if(count < 0)
6094 {
6095 return error(GL_INVALID_VALUE);
6096 }
John Bauman66b8ab22014-05-06 15:57:45 -04006097
Nicolas Capensf160b172014-11-26 11:58:23 -05006098 if(location == -1)
6099 {
6100 return;
6101 }
John Bauman66b8ab22014-05-06 15:57:45 -04006102
Nicolas Capensf160b172014-11-26 11:58:23 -05006103 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006104
Nicolas Capensf160b172014-11-26 11:58:23 -05006105 if(context)
6106 {
6107 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006108
Nicolas Capensf160b172014-11-26 11:58:23 -05006109 if(!program)
6110 {
6111 return error(GL_INVALID_OPERATION);
6112 }
John Bauman66b8ab22014-05-06 15:57:45 -04006113
Nicolas Capensf160b172014-11-26 11:58:23 -05006114 if(!program->setUniform4iv(location, count, v))
6115 {
6116 return error(GL_INVALID_OPERATION);
6117 }
6118 }
John Bauman66b8ab22014-05-06 15:57:45 -04006119}
6120
Nicolas Capenseb195b62015-04-28 17:18:42 -07006121void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
John Bauman66b8ab22014-05-06 15:57:45 -04006122{
Nicolas Capens4be33702015-04-28 15:13:30 -07006123 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006124 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006125
Nicolas Capensf160b172014-11-26 11:58:23 -05006126 if(count < 0 || transpose != GL_FALSE)
6127 {
6128 return error(GL_INVALID_VALUE);
6129 }
John Bauman66b8ab22014-05-06 15:57:45 -04006130
Nicolas Capensf160b172014-11-26 11:58:23 -05006131 if(location == -1)
6132 {
6133 return;
6134 }
John Bauman66b8ab22014-05-06 15:57:45 -04006135
Nicolas Capensf160b172014-11-26 11:58:23 -05006136 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006137
Nicolas Capensf160b172014-11-26 11:58:23 -05006138 if(context)
6139 {
6140 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006141
Nicolas Capensf160b172014-11-26 11:58:23 -05006142 if(!program)
6143 {
6144 return error(GL_INVALID_OPERATION);
6145 }
John Bauman66b8ab22014-05-06 15:57:45 -04006146
Nicolas Capensf160b172014-11-26 11:58:23 -05006147 if(!program->setUniformMatrix2fv(location, count, value))
6148 {
6149 return error(GL_INVALID_OPERATION);
6150 }
6151 }
John Bauman66b8ab22014-05-06 15:57:45 -04006152}
6153
Nicolas Capenseb195b62015-04-28 17:18:42 -07006154void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
John Bauman66b8ab22014-05-06 15:57:45 -04006155{
Nicolas Capens4be33702015-04-28 15:13:30 -07006156 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006157 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006158
Nicolas Capensf160b172014-11-26 11:58:23 -05006159 if(count < 0 || transpose != GL_FALSE)
6160 {
6161 return error(GL_INVALID_VALUE);
6162 }
John Bauman66b8ab22014-05-06 15:57:45 -04006163
Nicolas Capensf160b172014-11-26 11:58:23 -05006164 if(location == -1)
6165 {
6166 return;
6167 }
John Bauman66b8ab22014-05-06 15:57:45 -04006168
Nicolas Capensf160b172014-11-26 11:58:23 -05006169 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006170
Nicolas Capensf160b172014-11-26 11:58:23 -05006171 if(context)
6172 {
6173 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006174
Nicolas Capensf160b172014-11-26 11:58:23 -05006175 if(!program)
6176 {
6177 return error(GL_INVALID_OPERATION);
6178 }
John Bauman66b8ab22014-05-06 15:57:45 -04006179
Nicolas Capensf160b172014-11-26 11:58:23 -05006180 if(!program->setUniformMatrix3fv(location, count, value))
6181 {
6182 return error(GL_INVALID_OPERATION);
6183 }
6184 }
John Bauman66b8ab22014-05-06 15:57:45 -04006185}
6186
Nicolas Capenseb195b62015-04-28 17:18:42 -07006187void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
John Bauman66b8ab22014-05-06 15:57:45 -04006188{
Nicolas Capens4be33702015-04-28 15:13:30 -07006189 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006190 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006191
Nicolas Capensf160b172014-11-26 11:58:23 -05006192 if(count < 0 || transpose != GL_FALSE)
6193 {
6194 return error(GL_INVALID_VALUE);
6195 }
John Bauman66b8ab22014-05-06 15:57:45 -04006196
Nicolas Capensf160b172014-11-26 11:58:23 -05006197 if(location == -1)
6198 {
6199 return;
6200 }
John Bauman66b8ab22014-05-06 15:57:45 -04006201
Nicolas Capensf160b172014-11-26 11:58:23 -05006202 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006203
Nicolas Capensf160b172014-11-26 11:58:23 -05006204 if(context)
6205 {
6206 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006207
Nicolas Capensf160b172014-11-26 11:58:23 -05006208 if(!program)
6209 {
6210 return error(GL_INVALID_OPERATION);
6211 }
John Bauman66b8ab22014-05-06 15:57:45 -04006212
Nicolas Capensf160b172014-11-26 11:58:23 -05006213 if(!program->setUniformMatrix4fv(location, count, value))
6214 {
6215 return error(GL_INVALID_OPERATION);
6216 }
6217 }
John Bauman66b8ab22014-05-06 15:57:45 -04006218}
6219
Nicolas Capenseb195b62015-04-28 17:18:42 -07006220void UseProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04006221{
Nicolas Capensf160b172014-11-26 11:58:23 -05006222 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006223
Nicolas Capensf160b172014-11-26 11:58:23 -05006224 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006225
Nicolas Capensf160b172014-11-26 11:58:23 -05006226 if(context)
6227 {
6228 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006229
Nicolas Capensf160b172014-11-26 11:58:23 -05006230 if(!programObject && program != 0)
6231 {
6232 if(context->getShader(program))
6233 {
6234 return error(GL_INVALID_OPERATION);
6235 }
6236 else
6237 {
6238 return error(GL_INVALID_VALUE);
6239 }
6240 }
John Bauman66b8ab22014-05-06 15:57:45 -04006241
Nicolas Capensf160b172014-11-26 11:58:23 -05006242 if(program != 0 && !programObject->isLinked())
6243 {
6244 return error(GL_INVALID_OPERATION);
6245 }
John Bauman66b8ab22014-05-06 15:57:45 -04006246
Nicolas Capensf160b172014-11-26 11:58:23 -05006247 context->useProgram(program);
6248 }
John Bauman66b8ab22014-05-06 15:57:45 -04006249}
6250
Nicolas Capenseb195b62015-04-28 17:18:42 -07006251void ValidateProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04006252{
Nicolas Capensf160b172014-11-26 11:58:23 -05006253 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006254
Nicolas Capensf160b172014-11-26 11:58:23 -05006255 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006256
Nicolas Capensf160b172014-11-26 11:58:23 -05006257 if(context)
6258 {
6259 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006260
Nicolas Capensf160b172014-11-26 11:58:23 -05006261 if(!programObject)
6262 {
6263 if(context->getShader(program))
6264 {
6265 return error(GL_INVALID_OPERATION);
6266 }
6267 else
6268 {
6269 return error(GL_INVALID_VALUE);
6270 }
6271 }
John Bauman66b8ab22014-05-06 15:57:45 -04006272
Nicolas Capensf160b172014-11-26 11:58:23 -05006273 programObject->validate();
6274 }
John Bauman66b8ab22014-05-06 15:57:45 -04006275}
6276
Nicolas Capenseb195b62015-04-28 17:18:42 -07006277void VertexAttrib1f(GLuint index, GLfloat x)
John Bauman66b8ab22014-05-06 15:57:45 -04006278{
Nicolas Capensf160b172014-11-26 11:58:23 -05006279 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
John Bauman66b8ab22014-05-06 15:57:45 -04006280
Nicolas Capensf160b172014-11-26 11:58:23 -05006281 if(index >= es2::MAX_VERTEX_ATTRIBS)
6282 {
6283 return error(GL_INVALID_VALUE);
6284 }
John Bauman66b8ab22014-05-06 15:57:45 -04006285
Nicolas Capensf160b172014-11-26 11:58:23 -05006286 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006287
Nicolas Capensf160b172014-11-26 11:58:23 -05006288 if(context)
6289 {
6290 GLfloat vals[4] = { x, 0, 0, 1 };
6291 context->setVertexAttrib(index, vals);
6292 }
John Bauman66b8ab22014-05-06 15:57:45 -04006293}
6294
Nicolas Capenseb195b62015-04-28 17:18:42 -07006295void VertexAttrib1fv(GLuint index, const GLfloat* values)
John Bauman66b8ab22014-05-06 15:57:45 -04006296{
Nicolas Capens4be33702015-04-28 15:13:30 -07006297 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006298
Nicolas Capensf160b172014-11-26 11:58:23 -05006299 if(index >= es2::MAX_VERTEX_ATTRIBS)
6300 {
6301 return error(GL_INVALID_VALUE);
6302 }
John Bauman66b8ab22014-05-06 15:57:45 -04006303
Nicolas Capensf160b172014-11-26 11:58:23 -05006304 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006305
Nicolas Capensf160b172014-11-26 11:58:23 -05006306 if(context)
6307 {
6308 GLfloat vals[4] = { values[0], 0, 0, 1 };
6309 context->setVertexAttrib(index, vals);
6310 }
John Bauman66b8ab22014-05-06 15:57:45 -04006311}
6312
Nicolas Capenseb195b62015-04-28 17:18:42 -07006313void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
John Bauman66b8ab22014-05-06 15:57:45 -04006314{
Nicolas Capensf160b172014-11-26 11:58:23 -05006315 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
John Bauman66b8ab22014-05-06 15:57:45 -04006316
Nicolas Capensf160b172014-11-26 11:58:23 -05006317 if(index >= es2::MAX_VERTEX_ATTRIBS)
6318 {
6319 return error(GL_INVALID_VALUE);
6320 }
John Bauman66b8ab22014-05-06 15:57:45 -04006321
Nicolas Capensf160b172014-11-26 11:58:23 -05006322 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006323
Nicolas Capensf160b172014-11-26 11:58:23 -05006324 if(context)
6325 {
6326 GLfloat vals[4] = { x, y, 0, 1 };
6327 context->setVertexAttrib(index, vals);
6328 }
John Bauman66b8ab22014-05-06 15:57:45 -04006329}
6330
Nicolas Capenseb195b62015-04-28 17:18:42 -07006331void VertexAttrib2fv(GLuint index, const GLfloat* values)
John Bauman66b8ab22014-05-06 15:57:45 -04006332{
Nicolas Capens4be33702015-04-28 15:13:30 -07006333 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006334
Nicolas Capensf160b172014-11-26 11:58:23 -05006335 if(index >= es2::MAX_VERTEX_ATTRIBS)
6336 {
6337 return error(GL_INVALID_VALUE);
6338 }
John Bauman66b8ab22014-05-06 15:57:45 -04006339
Nicolas Capensf160b172014-11-26 11:58:23 -05006340 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006341
Nicolas Capensf160b172014-11-26 11:58:23 -05006342 if(context)
6343 {
6344 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6345 context->setVertexAttrib(index, vals);
6346 }
John Bauman66b8ab22014-05-06 15:57:45 -04006347}
6348
Nicolas Capenseb195b62015-04-28 17:18:42 -07006349void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
John Bauman66b8ab22014-05-06 15:57:45 -04006350{
Nicolas Capensf160b172014-11-26 11:58:23 -05006351 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
John Bauman66b8ab22014-05-06 15:57:45 -04006352
Nicolas Capensf160b172014-11-26 11:58:23 -05006353 if(index >= es2::MAX_VERTEX_ATTRIBS)
6354 {
6355 return error(GL_INVALID_VALUE);
6356 }
John Bauman66b8ab22014-05-06 15:57:45 -04006357
Nicolas Capensf160b172014-11-26 11:58:23 -05006358 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006359
Nicolas Capensf160b172014-11-26 11:58:23 -05006360 if(context)
6361 {
6362 GLfloat vals[4] = { x, y, z, 1 };
6363 context->setVertexAttrib(index, vals);
6364 }
John Bauman66b8ab22014-05-06 15:57:45 -04006365}
6366
Nicolas Capenseb195b62015-04-28 17:18:42 -07006367void VertexAttrib3fv(GLuint index, const GLfloat* values)
John Bauman66b8ab22014-05-06 15:57:45 -04006368{
Nicolas Capens4be33702015-04-28 15:13:30 -07006369 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006370
Nicolas Capensf160b172014-11-26 11:58:23 -05006371 if(index >= es2::MAX_VERTEX_ATTRIBS)
6372 {
6373 return error(GL_INVALID_VALUE);
6374 }
John Bauman66b8ab22014-05-06 15:57:45 -04006375
Nicolas Capensf160b172014-11-26 11:58:23 -05006376 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006377
Nicolas Capensf160b172014-11-26 11:58:23 -05006378 if(context)
6379 {
6380 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6381 context->setVertexAttrib(index, vals);
6382 }
John Bauman66b8ab22014-05-06 15:57:45 -04006383}
6384
Nicolas Capenseb195b62015-04-28 17:18:42 -07006385void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
John Bauman66b8ab22014-05-06 15:57:45 -04006386{
Nicolas Capensf160b172014-11-26 11:58:23 -05006387 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
John Bauman66b8ab22014-05-06 15:57:45 -04006388
Nicolas Capensf160b172014-11-26 11:58:23 -05006389 if(index >= es2::MAX_VERTEX_ATTRIBS)
6390 {
6391 return error(GL_INVALID_VALUE);
6392 }
John Bauman66b8ab22014-05-06 15:57:45 -04006393
Nicolas Capensf160b172014-11-26 11:58:23 -05006394 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006395
Nicolas Capensf160b172014-11-26 11:58:23 -05006396 if(context)
6397 {
6398 GLfloat vals[4] = { x, y, z, w };
6399 context->setVertexAttrib(index, vals);
6400 }
John Bauman66b8ab22014-05-06 15:57:45 -04006401}
6402
Nicolas Capenseb195b62015-04-28 17:18:42 -07006403void VertexAttrib4fv(GLuint index, const GLfloat* values)
John Bauman66b8ab22014-05-06 15:57:45 -04006404{
Nicolas Capens4be33702015-04-28 15:13:30 -07006405 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006406
Nicolas Capensf160b172014-11-26 11:58:23 -05006407 if(index >= es2::MAX_VERTEX_ATTRIBS)
6408 {
6409 return error(GL_INVALID_VALUE);
6410 }
John Bauman66b8ab22014-05-06 15:57:45 -04006411
Nicolas Capensf160b172014-11-26 11:58:23 -05006412 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006413
Nicolas Capensf160b172014-11-26 11:58:23 -05006414 if(context)
6415 {
6416 context->setVertexAttrib(index, values);
6417 }
John Bauman66b8ab22014-05-06 15:57:45 -04006418}
6419
Nicolas Capenseb195b62015-04-28 17:18:42 -07006420void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
John Bauman66b8ab22014-05-06 15:57:45 -04006421{
Nicolas Capensf160b172014-11-26 11:58:23 -05006422 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006423 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006424 index, size, type, normalized, stride, ptr);
John Bauman66b8ab22014-05-06 15:57:45 -04006425
Nicolas Capensf160b172014-11-26 11:58:23 -05006426 if(index >= es2::MAX_VERTEX_ATTRIBS)
6427 {
6428 return error(GL_INVALID_VALUE);
6429 }
John Bauman66b8ab22014-05-06 15:57:45 -04006430
Nicolas Capensf160b172014-11-26 11:58:23 -05006431 if(size < 1 || size > 4)
6432 {
6433 return error(GL_INVALID_VALUE);
6434 }
John Bauman66b8ab22014-05-06 15:57:45 -04006435
Alexis Hetued306182015-04-02 12:02:28 -04006436 egl::GLint clientVersion = egl::getClientVersion();
6437
Nicolas Capensf160b172014-11-26 11:58:23 -05006438 switch(type)
6439 {
6440 case GL_BYTE:
6441 case GL_UNSIGNED_BYTE:
6442 case GL_SHORT:
6443 case GL_UNSIGNED_SHORT:
6444 case GL_FIXED:
6445 case GL_FLOAT:
6446 break;
Alexis Hetued306182015-04-02 12:02:28 -04006447 case GL_INT_2_10_10_10_REV:
6448 case GL_UNSIGNED_INT_2_10_10_10_REV:
6449 if(clientVersion >= 3)
6450 {
6451 if(size != 4)
6452 {
6453 return error(GL_INVALID_OPERATION);
6454 }
6455 break;
6456 }
6457 else return error(GL_INVALID_ENUM);
6458 case GL_INT:
6459 case GL_UNSIGNED_INT:
6460 case GL_HALF_FLOAT:
6461 if(clientVersion >= 3)
6462 {
6463 break;
6464 }
6465 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05006466 default:
6467 return error(GL_INVALID_ENUM);
6468 }
John Bauman66b8ab22014-05-06 15:57:45 -04006469
Nicolas Capensf160b172014-11-26 11:58:23 -05006470 if(stride < 0)
6471 {
6472 return error(GL_INVALID_VALUE);
6473 }
John Bauman66b8ab22014-05-06 15:57:45 -04006474
Nicolas Capensf160b172014-11-26 11:58:23 -05006475 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006476
Nicolas Capensf160b172014-11-26 11:58:23 -05006477 if(context)
6478 {
6479 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6480 }
John Bauman66b8ab22014-05-06 15:57:45 -04006481}
6482
Nicolas Capenseb195b62015-04-28 17:18:42 -07006483void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04006484{
Nicolas Capensf160b172014-11-26 11:58:23 -05006485 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04006486
Nicolas Capensf160b172014-11-26 11:58:23 -05006487 if(width < 0 || height < 0)
6488 {
6489 return error(GL_INVALID_VALUE);
6490 }
John Bauman66b8ab22014-05-06 15:57:45 -04006491
Nicolas Capensf160b172014-11-26 11:58:23 -05006492 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006493
Nicolas Capensf160b172014-11-26 11:58:23 -05006494 if(context)
6495 {
6496 context->setViewportParams(x, y, width, height);
6497 }
John Bauman66b8ab22014-05-06 15:57:45 -04006498}
6499
Nicolas Capenseb195b62015-04-28 17:18:42 -07006500void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
John Bauman66b8ab22014-05-06 15:57:45 -04006501{
Nicolas Capensf160b172014-11-26 11:58:23 -05006502 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6503 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6504 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6505 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
John Bauman66b8ab22014-05-06 15:57:45 -04006506
Nicolas Capensf160b172014-11-26 11:58:23 -05006507 switch(filter)
6508 {
6509 case GL_NEAREST:
6510 break;
6511 default:
6512 return error(GL_INVALID_ENUM);
6513 }
John Bauman66b8ab22014-05-06 15:57:45 -04006514
Nicolas Capensf160b172014-11-26 11:58:23 -05006515 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6516 {
6517 return error(GL_INVALID_VALUE);
6518 }
John Bauman66b8ab22014-05-06 15:57:45 -04006519
Nicolas Capensf160b172014-11-26 11:58:23 -05006520 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006521
Nicolas Capensf160b172014-11-26 11:58:23 -05006522 if(context)
6523 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006524 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capensf160b172014-11-26 11:58:23 -05006525 {
6526 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6527 return error(GL_INVALID_OPERATION);
6528 }
John Bauman66b8ab22014-05-06 15:57:45 -04006529
Nicolas Capensf160b172014-11-26 11:58:23 -05006530 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6531 }
John Bauman66b8ab22014-05-06 15:57:45 -04006532}
6533
Nicolas Capenseb195b62015-04-28 17:18:42 -07006534void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6535 GLbitfield mask, GLenum filter)
Alexis Hetue9233fb2015-02-11 10:31:58 -05006536{
6537 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6538 {
6539 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6540 return error(GL_INVALID_OPERATION);
6541 }
6542
6543 glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6544}
6545
Nicolas Capenseb195b62015-04-28 17:18:42 -07006546void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6547 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04006548{
Nicolas Capensf160b172014-11-26 11:58:23 -05006549 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6550 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006551 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006552 target, level, internalformat, width, height, depth, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04006553
Alexis Hetub027aa92015-01-19 15:56:12 -05006554 switch(target)
6555 {
6556 case GL_TEXTURE_3D_OES:
6557 switch(format)
6558 {
6559 case GL_DEPTH_COMPONENT:
6560 case GL_DEPTH_STENCIL_OES:
6561 return error(GL_INVALID_OPERATION);
6562 default:
6563 break;
6564 }
6565 break;
6566 default:
6567 return error(GL_INVALID_ENUM);
6568 }
6569
6570 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6571 {
6572 return error(GL_INVALID_ENUM);
6573 }
6574
6575 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6576 {
6577 return error(GL_INVALID_VALUE);
6578 }
6579
6580 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6581 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6582 {
6583 return error(GL_INVALID_VALUE);
6584 }
6585
6586 if(border != 0)
6587 {
6588 return error(GL_INVALID_VALUE);
6589 }
6590
6591 if(!ValidateInternalFormat3D(internalformat, format, type))
6592 {
6593 return error(GL_INVALID_OPERATION);
6594 }
6595
6596 es2::Context *context = es2::getContext();
6597
6598 if(context)
6599 {
6600 es2::Texture3D *texture = context->getTexture3D();
6601
6602 if(!texture)
6603 {
6604 return error(GL_INVALID_OPERATION);
6605 }
6606
6607 texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackAlignment(), pixels);
6608 }
John Bauman66b8ab22014-05-06 15:57:45 -04006609}
6610
Nicolas Capenseb195b62015-04-28 17:18:42 -07006611void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006612{
Alexis Hetub027aa92015-01-19 15:56:12 -05006613 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6614 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006615 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006616 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
6617
Alexis Hetub027aa92015-01-19 15:56:12 -05006618 switch(target)
6619 {
6620 case GL_TEXTURE_3D_OES:
6621 break;
6622 default:
6623 return error(GL_INVALID_ENUM);
6624 }
6625
6626 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6627 {
6628 return error(GL_INVALID_ENUM);
6629 }
6630
6631 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6632 {
6633 return error(GL_INVALID_VALUE);
6634 }
6635
6636 if((width < 0) || (height < 0) || (depth < 0))
6637 {
6638 return error(GL_INVALID_VALUE);
6639 }
6640
6641 es2::Context *context = es2::getContext();
6642
6643 if(context)
6644 {
6645 es2::Texture3D *texture = context->getTexture3D();
6646
6647 if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))
6648 {
6649 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackAlignment(), pixels);
6650 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006651 }
6652}
6653
Nicolas Capenseb195b62015-04-28 17:18:42 -07006654void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006655{
Alexis Hetub027aa92015-01-19 15:56:12 -05006656 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6657 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006658 target, level, xoffset, yoffset, zoffset, x, y, width, height);
6659
Alexis Hetub027aa92015-01-19 15:56:12 -05006660 switch(target)
6661 {
6662 case GL_TEXTURE_3D_OES:
6663 break;
6664 default:
6665 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006666 }
6667
Alexis Hetub027aa92015-01-19 15:56:12 -05006668 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6669 {
6670 return error(GL_INVALID_VALUE);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006671 }
6672
Alexis Hetub027aa92015-01-19 15:56:12 -05006673 es2::Context *context = es2::getContext();
6674
6675 if(context)
6676 {
6677 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6678
6679 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
6680 {
6681 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6682 }
6683
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006684 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Alexis Hetub027aa92015-01-19 15:56:12 -05006685 {
6686 return error(GL_INVALID_OPERATION);
6687 }
6688
6689 es2::Renderbuffer *source = framebuffer->getColorbuffer();
6690 GLenum colorbufferFormat = source->getFormat();
6691 es2::Texture3D *texture = context->getTexture3D();
6692
6693 if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))
6694 {
6695 return;
6696 }
6697
6698 GLenum textureFormat = texture->getFormat(target, level);
6699
6700 if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
6701 {
6702 return;
6703 }
Nicolas Capensccee6a82015-04-28 16:49:59 -07006704
Alexis Hetub027aa92015-01-19 15:56:12 -05006705 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006706 }
6707}
6708
Nicolas Capenseb195b62015-04-28 17:18:42 -07006709void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006710{
Alexis Hetub027aa92015-01-19 15:56:12 -05006711 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006712 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
Alexis Hetub027aa92015-01-19 15:56:12 -05006713 target, level, internalformat, width, height, depth, border, imageSize, data);
6714
6715 switch(target)
6716 {
6717 case GL_TEXTURE_3D_OES:
6718 break;
6719 default:
6720 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006721 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006722
6723 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6724 {
6725 return error(GL_INVALID_VALUE);
6726 }
6727
6728 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6729 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6730 {
6731 return error(GL_INVALID_VALUE);
6732 }
6733
6734 switch(internalformat)
6735 {
6736 case GL_ETC1_RGB8_OES:
6737 break;
6738 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6739 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6740 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6741 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6742 if(!S3TC_SUPPORT)
6743 {
6744 return error(GL_INVALID_ENUM);
6745 }
6746 break;
6747 case GL_DEPTH_COMPONENT:
6748 case GL_DEPTH_COMPONENT16:
6749 case GL_DEPTH_COMPONENT32_OES:
6750 case GL_DEPTH_STENCIL_OES:
6751 case GL_DEPTH24_STENCIL8_OES:
6752 return error(GL_INVALID_OPERATION);
6753 default:
6754 return error(GL_INVALID_ENUM);
6755 }
6756
Nicolas Capensdeda34b2015-04-28 15:21:53 -07006757 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
Alexis Hetub027aa92015-01-19 15:56:12 -05006758 {
6759 return error(GL_INVALID_VALUE);
6760 }
6761
6762 es2::Context *context = es2::getContext();
6763
6764 if(context)
6765 {
6766 es2::Texture3D *texture = context->getTexture3D();
6767
6768 if(!texture)
6769 {
6770 return error(GL_INVALID_OPERATION);
6771 }
6772
6773 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006774 }
6775}
6776
Nicolas Capenseb195b62015-04-28 17:18:42 -07006777void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006778{
Alexis Hetub027aa92015-01-19 15:56:12 -05006779 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6780 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006781 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006782 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6783
Alexis Hetub027aa92015-01-19 15:56:12 -05006784 switch(target)
6785 {
6786 case GL_TEXTURE_3D_OES:
6787 break;
6788 default:
6789 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006790 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006791
6792 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6793 {
6794 return error(GL_INVALID_VALUE);
6795 }
6796
6797 switch(format)
6798 {
6799 case GL_ETC1_RGB8_OES:
6800 break;
6801 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6802 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6803 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6804 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6805 if(!S3TC_SUPPORT)
6806 {
6807 return error(GL_INVALID_ENUM);
6808 }
6809 break;
6810 default:
6811 return error(GL_INVALID_ENUM);
6812 }
6813
6814 if(width == 0 || height == 0 || depth == 0 || data == NULL)
6815 {
6816 return;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006817 }
6818
Alexis Hetub027aa92015-01-19 15:56:12 -05006819 es2::Context *context = es2::getContext();
6820
6821 if(context)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006822 {
Alexis Hetub027aa92015-01-19 15:56:12 -05006823 es2::Texture3D *texture = context->getTexture3D();
6824
6825 if(!texture)
6826 {
6827 return error(GL_INVALID_OPERATION);
6828 }
6829
6830 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6831 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006832}
6833
Nicolas Capenseb195b62015-04-28 17:18:42 -07006834void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006835{
Alexis Hetub027aa92015-01-19 15:56:12 -05006836 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6837 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6838
6839 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
6840 {
6841 return error(GL_INVALID_ENUM);
6842 }
6843
6844 switch(attachment)
6845 {
6846 case GL_COLOR_ATTACHMENT0:
6847 case GL_DEPTH_ATTACHMENT:
6848 case GL_STENCIL_ATTACHMENT:
6849 break;
6850 default:
6851 return error(GL_INVALID_ENUM);
6852 }
6853
6854 es2::Context *context = es2::getContext();
6855
6856 if(context)
6857 {
6858 if(texture == 0)
6859 {
6860 textarget = GL_NONE;
6861 }
6862 else
6863 {
6864 es2::Texture *tex = context->getTexture(texture);
6865
6866 if(tex == NULL)
6867 {
6868 return error(GL_INVALID_OPERATION);
6869 }
6870
6871 if(tex->isCompressed(textarget, level))
6872 {
6873 return error(GL_INVALID_OPERATION);
6874 }
6875
6876 switch(textarget)
6877 {
6878 case GL_TEXTURE_3D_OES:
6879 if(tex->getTarget() != GL_TEXTURE_3D_OES)
6880 {
6881 return error(GL_INVALID_OPERATION);
6882 }
6883 break;
6884 default:
6885 return error(GL_INVALID_ENUM);
6886 }
6887
6888 if(level != 0)
6889 {
6890 return error(GL_INVALID_VALUE);
6891 }
6892 }
6893
6894 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006895 GLuint framebufferName = 0;
Alexis Hetub027aa92015-01-19 15:56:12 -05006896 if(target == GL_READ_FRAMEBUFFER_ANGLE)
6897 {
6898 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006899 framebufferName = context->getReadFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006900 }
6901 else
6902 {
6903 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006904 framebufferName = context->getDrawFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006905 }
6906
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006907 if(framebufferName == 0 || !framebuffer)
Alexis Hetub027aa92015-01-19 15:56:12 -05006908 {
6909 return error(GL_INVALID_OPERATION);
6910 }
6911
6912 switch(attachment)
6913 {
6914 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
6915 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
6916 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6917 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006918 }
6919}
Alexis Hetub027aa92015-01-19 15:56:12 -05006920
Nicolas Capenseb195b62015-04-28 17:18:42 -07006921void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006922{
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006923 if(egl::getClientVersion() == 1)
6924 {
Nicolas Capensa2308052015-04-15 16:50:21 -04006925 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006926 }
6927
Nicolas Capens4be33702015-04-28 15:13:30 -07006928 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006929
Nicolas Capensf160b172014-11-26 11:58:23 -05006930 switch(target)
6931 {
6932 case GL_TEXTURE_2D:
6933 case GL_TEXTURE_EXTERNAL_OES:
6934 break;
6935 default:
6936 return error(GL_INVALID_ENUM);
6937 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006938
Nicolas Capensf160b172014-11-26 11:58:23 -05006939 if(!image)
6940 {
6941 return error(GL_INVALID_OPERATION);
6942 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006943
Nicolas Capensf160b172014-11-26 11:58:23 -05006944 es2::Context *context = es2::getContext();
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006945
Nicolas Capensf160b172014-11-26 11:58:23 -05006946 if(context)
6947 {
6948 es2::Texture2D *texture = 0;
Nicolas Capens08e90f02014-11-21 12:49:12 -05006949
Nicolas Capensf160b172014-11-26 11:58:23 -05006950 switch(target)
6951 {
6952 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
6953 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
6954 default: UNREACHABLE();
6955 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006956
Nicolas Capensf160b172014-11-26 11:58:23 -05006957 if(!texture)
6958 {
6959 return error(GL_INVALID_OPERATION);
6960 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006961
Nicolas Capensf160b172014-11-26 11:58:23 -05006962 egl::Image *glImage = static_cast<egl::Image*>(image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006963
Nicolas Capensf160b172014-11-26 11:58:23 -05006964 texture->setImage(glImage);
6965 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006966}
6967
Nicolas Capenseb195b62015-04-28 17:18:42 -07006968void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006969{
Nicolas Capens4be33702015-04-28 15:13:30 -07006970 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006971
6972 UNIMPLEMENTED();
6973}
6974
Nicolas Capenseb195b62015-04-28 17:18:42 -07006975}
6976
6977extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
John Bauman66b8ab22014-05-06 15:57:45 -04006978{
Nicolas Capensf160b172014-11-26 11:58:23 -05006979 struct Extension
6980 {
6981 const char *name;
6982 __eglMustCastToProperFunctionPointerType address;
6983 };
John Bauman66b8ab22014-05-06 15:57:45 -04006984
Nicolas Capensf160b172014-11-26 11:58:23 -05006985 static const Extension glExtensions[] =
6986 {
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006987 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6988
Nicolas Capensf160b172014-11-26 11:58:23 -05006989 EXTENSION(glTexImage3DOES),
6990 EXTENSION(glBlitFramebufferANGLE),
Alexis Hetue9233fb2015-02-11 10:31:58 -05006991 EXTENSION(glBlitFramebufferNV),
Nicolas Capensf160b172014-11-26 11:58:23 -05006992 EXTENSION(glRenderbufferStorageMultisampleANGLE),
6993 EXTENSION(glDeleteFencesNV),
6994 EXTENSION(glGenFencesNV),
6995 EXTENSION(glIsFenceNV),
6996 EXTENSION(glTestFenceNV),
6997 EXTENSION(glGetFenceivNV),
6998 EXTENSION(glFinishFenceNV),
6999 EXTENSION(glSetFenceNV),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007000 EXTENSION(glGetGraphicsResetStatusEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05007001 EXTENSION(glReadnPixelsEXT),
7002 EXTENSION(glGetnUniformfvEXT),
7003 EXTENSION(glGetnUniformivEXT),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007004 EXTENSION(glGenQueriesEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05007005 EXTENSION(glDeleteQueriesEXT),
7006 EXTENSION(glIsQueryEXT),
7007 EXTENSION(glBeginQueryEXT),
7008 EXTENSION(glEndQueryEXT),
7009 EXTENSION(glGetQueryivEXT),
7010 EXTENSION(glGetQueryObjectuivEXT),
7011 EXTENSION(glEGLImageTargetTexture2DOES),
Nicolas Capens7e12ac62014-11-05 17:07:53 -05007012 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
Alexis Hetue8af6d12015-04-17 16:58:45 -04007013 EXTENSION(glDrawElementsInstancedEXT),
7014 EXTENSION(glDrawArraysInstancedEXT),
7015 EXTENSION(glVertexAttribDivisorEXT),
Nicolas Capens0416e5c2015-04-28 15:30:28 -07007016 EXTENSION(glDrawArraysInstancedANGLE),
7017 EXTENSION(glDrawElementsInstancedANGLE),
Alexis Hetub4d557d2015-04-24 17:25:10 -04007018 EXTENSION(glVertexAttribDivisorANGLE),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007019
7020 #undef EXTENSION
Nicolas Capensf160b172014-11-26 11:58:23 -05007021 };
John Bauman66b8ab22014-05-06 15:57:45 -04007022
Nicolas Capensf160b172014-11-26 11:58:23 -05007023 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
7024 {
7025 if(strcmp(procname, glExtensions[ext].name) == 0)
7026 {
7027 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
7028 }
7029 }
John Bauman66b8ab22014-05-06 15:57:45 -04007030
Nicolas Capensf160b172014-11-26 11:58:23 -05007031 return NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04007032}