blob: 70f5c464385e39b55f05d5b7317a6a1dd95bfa1a [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"
John Baumand4ae8632014-05-06 16:18:33 -040027#include "Main/Register.hpp"
John Bauman66b8ab22014-05-06 15:57:45 -040028
29#define GL_APICALL
30#include <GLES2/gl2.h>
31#include <GLES2/gl2ext.h>
Alexis Hetufceb1832015-03-10 16:42:04 -040032#include <GLES3/gl3.h>
John Bauman66b8ab22014-05-06 15:57:45 -040033
John Bauman66b8ab22014-05-06 15:57:45 -040034#include <limits>
35
Greg Hartman6074f122015-04-08 09:57:16 -070036#ifdef ANDROID
37#include <cutils/log.h>
38#endif
39
Nicolas Capensa2308052015-04-15 16:50:21 -040040using namespace es2;
41
Alexis Hetub027aa92015-01-19 15:56:12 -050042typedef std::pair<GLenum, GLenum> InternalFormatTypePair;
43typedef std::map<InternalFormatTypePair, GLenum> FormatMap;
44
45// A helper function to insert data into the format map with fewer characters.
46static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)
47{
48 map[InternalFormatTypePair(internalformat, type)] = format;
49}
50
John Bauman66b8ab22014-05-06 15:57:45 -040051static bool validImageSize(GLint level, GLsizei width, GLsizei height)
52{
Nicolas Capensf160b172014-11-26 11:58:23 -050053 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
54 {
55 return false;
56 }
John Bauman66b8ab22014-05-06 15:57:45 -040057
Nicolas Capensf160b172014-11-26 11:58:23 -050058 return true;
John Bauman66b8ab22014-05-06 15:57:45 -040059}
60
Nicolas Capens14ee7622014-10-28 23:48:41 -040061static 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 -040062{
Nicolas Capensf160b172014-11-26 11:58:23 -050063 if(!texture)
64 {
65 return error(GL_INVALID_OPERATION, false);
66 }
John Bauman66b8ab22014-05-06 15:57:45 -040067
Nicolas Capensf160b172014-11-26 11:58:23 -050068 if(compressed != texture->isCompressed(target, level))
69 {
70 return error(GL_INVALID_OPERATION, false);
71 }
John Bauman66b8ab22014-05-06 15:57:45 -040072
Nicolas Capensf160b172014-11-26 11:58:23 -050073 if(format != GL_NONE && format != texture->getFormat(target, level))
74 {
75 return error(GL_INVALID_OPERATION, false);
76 }
John Bauman66b8ab22014-05-06 15:57:45 -040077
Nicolas Capensf160b172014-11-26 11:58:23 -050078 if(compressed)
79 {
80 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
Alexis Hetub027aa92015-01-19 15:56:12 -050081 (height % 4 != 0 && height != texture->getHeight(target, 0)))
Nicolas Capensf160b172014-11-26 11:58:23 -050082 {
83 return error(GL_INVALID_OPERATION, false);
84 }
85 }
John Bauman66b8ab22014-05-06 15:57:45 -040086
Nicolas Capensf160b172014-11-26 11:58:23 -050087 if(xoffset + width > texture->getWidth(target, level) ||
Alexis Hetub027aa92015-01-19 15:56:12 -050088 yoffset + height > texture->getHeight(target, level))
Nicolas Capensf160b172014-11-26 11:58:23 -050089 {
90 return error(GL_INVALID_VALUE, false);
91 }
John Bauman66b8ab22014-05-06 15:57:45 -040092
Nicolas Capensf160b172014-11-26 11:58:23 -050093 return true;
John Bauman66b8ab22014-05-06 15:57:45 -040094}
95
Alexis Hetub027aa92015-01-19 15:56:12 -050096static 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)
97{
98 if(!texture)
99 {
100 return error(GL_INVALID_OPERATION, false);
101 }
102
103 if(compressed != texture->isCompressed(target, level))
104 {
105 return error(GL_INVALID_OPERATION, false);
106 }
107
108 if(format != GL_NONE && format != texture->getFormat(target, level))
109 {
110 return error(GL_INVALID_OPERATION, false);
111 }
112
113 if(compressed)
114 {
115 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
116 (height % 4 != 0 && height != texture->getHeight(target, 0)) ||
117 (depth % 4 != 0 && depth != texture->getDepth(target, 0)))
118 {
119 return error(GL_INVALID_OPERATION, false);
120 }
121 }
122
123 if(xoffset + width > texture->getWidth(target, level) ||
124 yoffset + height > texture->getHeight(target, level) ||
125 zoffset + depth > texture->getDepth(target, level))
126 {
127 return error(GL_INVALID_VALUE, false);
128 }
129
130 return true;
131}
132
133static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
134{
135 // [OpenGL ES 2.0.24] table 3.9
136 switch(textureFormat)
137 {
138 case GL_ALPHA:
139 if(colorbufferFormat != GL_ALPHA &&
140 colorbufferFormat != GL_RGBA &&
141 colorbufferFormat != GL_RGBA4 &&
142 colorbufferFormat != GL_RGB5_A1 &&
143 colorbufferFormat != GL_RGBA8_OES)
144 {
145 return error(GL_INVALID_OPERATION, false);
146 }
147 break;
148 case GL_LUMINANCE:
149 case GL_RGB:
150 if(colorbufferFormat != GL_RGB &&
151 colorbufferFormat != GL_RGB565 &&
152 colorbufferFormat != GL_RGB8_OES &&
153 colorbufferFormat != GL_RGBA &&
154 colorbufferFormat != GL_RGBA4 &&
155 colorbufferFormat != GL_RGB5_A1 &&
156 colorbufferFormat != GL_RGBA8_OES)
157 {
158 return error(GL_INVALID_OPERATION, false);
159 }
160 break;
161 case GL_LUMINANCE_ALPHA:
162 case GL_RGBA:
163 if(colorbufferFormat != GL_RGBA &&
164 colorbufferFormat != GL_RGBA4 &&
165 colorbufferFormat != GL_RGB5_A1 &&
166 colorbufferFormat != GL_RGBA8_OES)
167 {
168 return error(GL_INVALID_OPERATION, false);
169 }
170 break;
171 case GL_ETC1_RGB8_OES:
172 return error(GL_INVALID_OPERATION, false);
173 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
174 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
175 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
176 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
177 if(S3TC_SUPPORT)
178 {
179 return error(GL_INVALID_OPERATION, false);
180 }
181 else
182 {
183 return error(GL_INVALID_ENUM, false);
184 }
185 case GL_DEPTH_COMPONENT:
186 case GL_DEPTH_STENCIL_OES:
187 return error(GL_INVALID_OPERATION, false);
188 default:
189 return error(GL_INVALID_ENUM, false);
190 }
191 return true;
192}
193
194static FormatMap BuildFormatMap3D()
195{
196 FormatMap map;
197
198 // Internal format | Format | Type
199 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
200 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
201 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
202 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
203 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
204 InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
205 InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
206 InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
207 InsertFormatMapping(map, GL_R8_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE);
208 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
209 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
210 InsertFormatMapping(map, GL_R32F_EXT, GL_RED_EXT, GL_FLOAT);
211 InsertFormatMapping(map, GL_RG8_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE);
212 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
213 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
214 InsertFormatMapping(map, GL_RG32F_EXT, GL_RG_EXT, GL_FLOAT);
215 InsertFormatMapping(map, GL_RGB8_OES, GL_RGB, GL_UNSIGNED_BYTE);
216 InsertFormatMapping(map, GL_SRGB8_NV, GL_RGB, GL_UNSIGNED_BYTE);
217 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);
218 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
Alexis Hetu0300e3c2015-03-12 17:33:07 -0400219 InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
220 InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_FLOAT);
Alexis Hetub027aa92015-01-19 15:56:12 -0500221 InsertFormatMapping(map, GL_RGB32F_EXT, GL_RGB, GL_FLOAT);
222 InsertFormatMapping(map, GL_RGBA8_OES, GL_RGBA, GL_UNSIGNED_BYTE);
223 InsertFormatMapping(map, GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_BYTE);
224 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);
225 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
226 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
227 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);
228 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
229 InsertFormatMapping(map, GL_RGB10_A2_EXT, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
230 InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
231 InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_FLOAT);
232 InsertFormatMapping(map, GL_RGBA32F_EXT, GL_RGBA, GL_FLOAT);
233
234 return map;
235}
236
237static bool ValidateType3D(GLenum type)
238{
239 switch(type)
240 {
241 case GL_UNSIGNED_BYTE:
242 case GL_BYTE:
243 case GL_UNSIGNED_SHORT:
244 case GL_SHORT:
245 case GL_UNSIGNED_INT:
246 case GL_INT:
247 case GL_HALF_FLOAT_OES:
248 case GL_FLOAT:
249 case GL_UNSIGNED_SHORT_5_6_5:
250 case GL_UNSIGNED_SHORT_4_4_4_4:
251 case GL_UNSIGNED_SHORT_5_5_5_1:
252 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
253 return true;
254 default:
255 break;
256 }
257 return false;
258}
259
260static bool ValidateFormat3D(GLenum format)
261{
262 switch(format)
263 {
264 case GL_RED_EXT:
265 case GL_RG_EXT:
266 case GL_RGB:
267 case GL_RGBA:
268 case GL_DEPTH_COMPONENT:
269 case GL_DEPTH_STENCIL_OES:
270 case GL_LUMINANCE_ALPHA:
271 case GL_LUMINANCE:
272 case GL_ALPHA:
273 return true;
274 default:
275 break;
276 }
277 return false;
278}
279
280static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)
281{
282 static const FormatMap formatMap = BuildFormatMap3D();
283 FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));
284 if(iter != formatMap.end())
285 {
286 return iter->second == format;
287 }
288 return false;
289}
290
John Bauman66b8ab22014-05-06 15:57:45 -0400291extern "C"
292{
293
294void GL_APIENTRY glActiveTexture(GLenum texture)
295{
Nicolas Capensf160b172014-11-26 11:58:23 -0500296 TRACE("(GLenum texture = 0x%X)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400297
Nicolas Capensf160b172014-11-26 11:58:23 -0500298 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400299
Nicolas Capensf160b172014-11-26 11:58:23 -0500300 if(context)
301 {
302 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
303 {
304 return error(GL_INVALID_ENUM);
305 }
John Bauman66b8ab22014-05-06 15:57:45 -0400306
Nicolas Capensf160b172014-11-26 11:58:23 -0500307 context->setActiveSampler(texture - GL_TEXTURE0);
308 }
John Bauman66b8ab22014-05-06 15:57:45 -0400309}
310
311void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
312{
Nicolas Capensf160b172014-11-26 11:58:23 -0500313 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400314
Nicolas Capensf160b172014-11-26 11:58:23 -0500315 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400316
Nicolas Capensf160b172014-11-26 11:58:23 -0500317 if(context)
318 {
319 es2::Program *programObject = context->getProgram(program);
320 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400321
Nicolas Capensf160b172014-11-26 11:58:23 -0500322 if(!programObject)
323 {
324 if(context->getShader(program))
325 {
326 return error(GL_INVALID_OPERATION);
327 }
328 else
329 {
330 return error(GL_INVALID_VALUE);
331 }
332 }
John Bauman66b8ab22014-05-06 15:57:45 -0400333
Nicolas Capensf160b172014-11-26 11:58:23 -0500334 if(!shaderObject)
335 {
336 if(context->getProgram(shader))
337 {
338 return error(GL_INVALID_OPERATION);
339 }
340 else
341 {
342 return error(GL_INVALID_VALUE);
343 }
344 }
John Bauman66b8ab22014-05-06 15:57:45 -0400345
Nicolas Capensf160b172014-11-26 11:58:23 -0500346 if(!programObject->attachShader(shaderObject))
347 {
348 return error(GL_INVALID_OPERATION);
349 }
350 }
John Bauman66b8ab22014-05-06 15:57:45 -0400351}
352
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500353void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -0400354{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500355 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
John Bauman66b8ab22014-05-06 15:57:45 -0400356
Nicolas Capensf160b172014-11-26 11:58:23 -0500357 switch(target)
358 {
359 case GL_ANY_SAMPLES_PASSED_EXT:
360 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
361 break;
362 default:
363 return error(GL_INVALID_ENUM);
364 }
John Bauman66b8ab22014-05-06 15:57:45 -0400365
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500366 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -0500367 {
368 return error(GL_INVALID_OPERATION);
369 }
John Bauman66b8ab22014-05-06 15:57:45 -0400370
Nicolas Capensf160b172014-11-26 11:58:23 -0500371 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400372
Nicolas Capensf160b172014-11-26 11:58:23 -0500373 if(context)
374 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500375 context->beginQuery(target, name);
Nicolas Capensf160b172014-11-26 11:58:23 -0500376 }
John Bauman66b8ab22014-05-06 15:57:45 -0400377}
378
379void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
380{
Nicolas Capensf160b172014-11-26 11:58:23 -0500381 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
John Bauman66b8ab22014-05-06 15:57:45 -0400382
Nicolas Capensf160b172014-11-26 11:58:23 -0500383 if(index >= es2::MAX_VERTEX_ATTRIBS)
384 {
385 return error(GL_INVALID_VALUE);
386 }
John Bauman66b8ab22014-05-06 15:57:45 -0400387
Nicolas Capensf160b172014-11-26 11:58:23 -0500388 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400389
Nicolas Capensf160b172014-11-26 11:58:23 -0500390 if(context)
391 {
392 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -0400393
Nicolas Capensf160b172014-11-26 11:58:23 -0500394 if(!programObject)
395 {
396 if(context->getShader(program))
397 {
398 return error(GL_INVALID_OPERATION);
399 }
400 else
401 {
402 return error(GL_INVALID_VALUE);
403 }
404 }
John Bauman66b8ab22014-05-06 15:57:45 -0400405
Nicolas Capensf160b172014-11-26 11:58:23 -0500406 if(strncmp(name, "gl_", 3) == 0)
407 {
408 return error(GL_INVALID_OPERATION);
409 }
John Bauman66b8ab22014-05-06 15:57:45 -0400410
Nicolas Capensf160b172014-11-26 11:58:23 -0500411 programObject->bindAttributeLocation(index, name);
412 }
John Bauman66b8ab22014-05-06 15:57:45 -0400413}
414
415void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
416{
Nicolas Capensf160b172014-11-26 11:58:23 -0500417 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400418
Nicolas Capensf160b172014-11-26 11:58:23 -0500419 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400420
Nicolas Capensf160b172014-11-26 11:58:23 -0500421 if(context)
422 {
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400423 egl::GLint clientVersion = egl::getClientVersion();
424
Nicolas Capensf160b172014-11-26 11:58:23 -0500425 switch(target)
426 {
427 case GL_ARRAY_BUFFER:
428 context->bindArrayBuffer(buffer);
429 return;
430 case GL_ELEMENT_ARRAY_BUFFER:
431 context->bindElementArrayBuffer(buffer);
432 return;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400433 case GL_COPY_READ_BUFFER:
434 if(clientVersion >= 3)
435 {
436 context->bindCopyReadBuffer(buffer);
437 return;
438 }
439 else return error(GL_INVALID_ENUM);
440 case GL_COPY_WRITE_BUFFER:
441 if(clientVersion >= 3)
442 {
443 context->bindCopyWriteBuffer(buffer);
444 return;
445 }
446 else return error(GL_INVALID_ENUM);
447 case GL_PIXEL_PACK_BUFFER:
448 if(clientVersion >= 3)
449 {
450 context->bindPixelPackBuffer(buffer);
451 return;
452 }
453 else return error(GL_INVALID_ENUM);
454 case GL_PIXEL_UNPACK_BUFFER:
455 if(clientVersion >= 3)
456 {
457 context->bindPixelUnpackBuffer(buffer);
458 return;
459 }
460 else return error(GL_INVALID_ENUM);
461 case GL_TRANSFORM_FEEDBACK_BUFFER:
462 if(clientVersion >= 3)
463 {
464 UNIMPLEMENTED();
465 return;
466 }
467 else return error(GL_INVALID_ENUM);
468 case GL_UNIFORM_BUFFER:
469 if(clientVersion >= 3)
470 {
471 context->bindUniformBuffer(buffer);
472 return;
473 }
474 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -0500475 default:
476 return error(GL_INVALID_ENUM);
477 }
478 }
John Bauman66b8ab22014-05-06 15:57:45 -0400479}
480
481void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
482{
Nicolas Capensf160b172014-11-26 11:58:23 -0500483 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400484
Nicolas Capensf160b172014-11-26 11:58:23 -0500485 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
486 {
487 return error(GL_INVALID_ENUM);
488 }
John Bauman66b8ab22014-05-06 15:57:45 -0400489
Nicolas Capensf160b172014-11-26 11:58:23 -0500490 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400491
Nicolas Capensf160b172014-11-26 11:58:23 -0500492 if(context)
493 {
494 if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
495 {
496 context->bindReadFramebuffer(framebuffer);
497 }
Nicolas Capens08e90f02014-11-21 12:49:12 -0500498
Nicolas Capensf160b172014-11-26 11:58:23 -0500499 if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
500 {
501 context->bindDrawFramebuffer(framebuffer);
502 }
503 }
John Bauman66b8ab22014-05-06 15:57:45 -0400504}
505
506void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
507{
Nicolas Capensf160b172014-11-26 11:58:23 -0500508 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400509
Nicolas Capensf160b172014-11-26 11:58:23 -0500510 if(target != GL_RENDERBUFFER)
511 {
512 return error(GL_INVALID_ENUM);
513 }
John Bauman66b8ab22014-05-06 15:57:45 -0400514
Nicolas Capensf160b172014-11-26 11:58:23 -0500515 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400516
Nicolas Capensf160b172014-11-26 11:58:23 -0500517 if(context)
518 {
519 if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))
520 {
521 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
522 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
523 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
524 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
525 return error(GL_INVALID_OPERATION);
526 }
Alexis Hetu42a584d2014-11-07 14:23:33 -0500527
Nicolas Capensf160b172014-11-26 11:58:23 -0500528 context->bindRenderbuffer(renderbuffer);
529 }
John Bauman66b8ab22014-05-06 15:57:45 -0400530}
531
532void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
533{
Nicolas Capensf160b172014-11-26 11:58:23 -0500534 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400535
Nicolas Capensf160b172014-11-26 11:58:23 -0500536 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400537
Nicolas Capensf160b172014-11-26 11:58:23 -0500538 if(context)
539 {
540 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400541
Nicolas Capensf160b172014-11-26 11:58:23 -0500542 if(textureObject && textureObject->getTarget() != target && texture != 0)
543 {
544 return error(GL_INVALID_OPERATION);
545 }
John Bauman66b8ab22014-05-06 15:57:45 -0400546
Alexis Hetued306182015-04-02 12:02:28 -0400547 egl::GLint clientVersion = context->getClientVersion();
548
Nicolas Capensf160b172014-11-26 11:58:23 -0500549 switch(target)
550 {
551 case GL_TEXTURE_2D:
552 context->bindTexture2D(texture);
553 return;
554 case GL_TEXTURE_CUBE_MAP:
555 context->bindTextureCubeMap(texture);
556 return;
557 case GL_TEXTURE_EXTERNAL_OES:
558 context->bindTextureExternal(texture);
559 return;
Alexis Hetued306182015-04-02 12:02:28 -0400560 case GL_TEXTURE_2D_ARRAY:
561 if(clientVersion < 3)
562 {
563 return error(GL_INVALID_ENUM);
564 }
565 else
566 {
567 UNIMPLEMENTED();
568 context->bindTexture3D(texture);
569 break;
570 }
Alexis Hetub027aa92015-01-19 15:56:12 -0500571 case GL_TEXTURE_3D_OES:
572 context->bindTexture3D(texture);
573 return;
Nicolas Capensf160b172014-11-26 11:58:23 -0500574 default:
575 return error(GL_INVALID_ENUM);
576 }
577 }
John Bauman66b8ab22014-05-06 15:57:45 -0400578}
579
580void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
581{
Nicolas Capensf160b172014-11-26 11:58:23 -0500582 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
583 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400584
Nicolas Capensf160b172014-11-26 11:58:23 -0500585 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400586
Nicolas Capensf160b172014-11-26 11:58:23 -0500587 if(context)
588 {
589 context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));
590 }
John Bauman66b8ab22014-05-06 15:57:45 -0400591}
592
593void GL_APIENTRY glBlendEquation(GLenum mode)
594{
Nicolas Capensf160b172014-11-26 11:58:23 -0500595 glBlendEquationSeparate(mode, mode);
John Bauman66b8ab22014-05-06 15:57:45 -0400596}
597
598void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
599{
Nicolas Capensf160b172014-11-26 11:58:23 -0500600 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400601
Nicolas Capensf160b172014-11-26 11:58:23 -0500602 switch(modeRGB)
603 {
604 case GL_FUNC_ADD:
605 case GL_FUNC_SUBTRACT:
606 case GL_FUNC_REVERSE_SUBTRACT:
607 case GL_MIN_EXT:
608 case GL_MAX_EXT:
609 break;
610 default:
611 return error(GL_INVALID_ENUM);
612 }
John Bauman66b8ab22014-05-06 15:57:45 -0400613
Nicolas Capensf160b172014-11-26 11:58:23 -0500614 switch(modeAlpha)
615 {
616 case GL_FUNC_ADD:
617 case GL_FUNC_SUBTRACT:
618 case GL_FUNC_REVERSE_SUBTRACT:
619 case GL_MIN_EXT:
620 case GL_MAX_EXT:
621 break;
622 default:
623 return error(GL_INVALID_ENUM);
624 }
John Bauman66b8ab22014-05-06 15:57:45 -0400625
Nicolas Capensf160b172014-11-26 11:58:23 -0500626 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400627
Nicolas Capensf160b172014-11-26 11:58:23 -0500628 if(context)
629 {
630 context->setBlendEquation(modeRGB, modeAlpha);
631 }
John Bauman66b8ab22014-05-06 15:57:45 -0400632}
633
634void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
635{
Nicolas Capensf160b172014-11-26 11:58:23 -0500636 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
John Bauman66b8ab22014-05-06 15:57:45 -0400637}
638
639void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
640{
Nicolas Capensf160b172014-11-26 11:58:23 -0500641 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
642 srcRGB, dstRGB, srcAlpha, dstAlpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400643
Nicolas Capensf160b172014-11-26 11:58:23 -0500644 switch(srcRGB)
645 {
646 case GL_ZERO:
647 case GL_ONE:
648 case GL_SRC_COLOR:
649 case GL_ONE_MINUS_SRC_COLOR:
650 case GL_DST_COLOR:
651 case GL_ONE_MINUS_DST_COLOR:
652 case GL_SRC_ALPHA:
653 case GL_ONE_MINUS_SRC_ALPHA:
654 case GL_DST_ALPHA:
655 case GL_ONE_MINUS_DST_ALPHA:
656 case GL_CONSTANT_COLOR:
657 case GL_ONE_MINUS_CONSTANT_COLOR:
658 case GL_CONSTANT_ALPHA:
659 case GL_ONE_MINUS_CONSTANT_ALPHA:
660 case GL_SRC_ALPHA_SATURATE:
661 break;
662 default:
663 return error(GL_INVALID_ENUM);
664 }
John Bauman66b8ab22014-05-06 15:57:45 -0400665
Nicolas Capensf160b172014-11-26 11:58:23 -0500666 switch(dstRGB)
667 {
668 case GL_ZERO:
669 case GL_ONE:
670 case GL_SRC_COLOR:
671 case GL_ONE_MINUS_SRC_COLOR:
672 case GL_DST_COLOR:
673 case GL_ONE_MINUS_DST_COLOR:
674 case GL_SRC_ALPHA:
675 case GL_ONE_MINUS_SRC_ALPHA:
676 case GL_DST_ALPHA:
677 case GL_ONE_MINUS_DST_ALPHA:
678 case GL_CONSTANT_COLOR:
679 case GL_ONE_MINUS_CONSTANT_COLOR:
680 case GL_CONSTANT_ALPHA:
681 case GL_ONE_MINUS_CONSTANT_ALPHA:
682 break;
683 default:
684 return error(GL_INVALID_ENUM);
685 }
John Bauman66b8ab22014-05-06 15:57:45 -0400686
Nicolas Capensf160b172014-11-26 11:58:23 -0500687 switch(srcAlpha)
688 {
689 case GL_ZERO:
690 case GL_ONE:
691 case GL_SRC_COLOR:
692 case GL_ONE_MINUS_SRC_COLOR:
693 case GL_DST_COLOR:
694 case GL_ONE_MINUS_DST_COLOR:
695 case GL_SRC_ALPHA:
696 case GL_ONE_MINUS_SRC_ALPHA:
697 case GL_DST_ALPHA:
698 case GL_ONE_MINUS_DST_ALPHA:
699 case GL_CONSTANT_COLOR:
700 case GL_ONE_MINUS_CONSTANT_COLOR:
701 case GL_CONSTANT_ALPHA:
702 case GL_ONE_MINUS_CONSTANT_ALPHA:
703 case GL_SRC_ALPHA_SATURATE:
704 break;
705 default:
706 return error(GL_INVALID_ENUM);
707 }
John Bauman66b8ab22014-05-06 15:57:45 -0400708
Nicolas Capensf160b172014-11-26 11:58:23 -0500709 switch(dstAlpha)
710 {
711 case GL_ZERO:
712 case GL_ONE:
713 case GL_SRC_COLOR:
714 case GL_ONE_MINUS_SRC_COLOR:
715 case GL_DST_COLOR:
716 case GL_ONE_MINUS_DST_COLOR:
717 case GL_SRC_ALPHA:
718 case GL_ONE_MINUS_SRC_ALPHA:
719 case GL_DST_ALPHA:
720 case GL_ONE_MINUS_DST_ALPHA:
721 case GL_CONSTANT_COLOR:
722 case GL_ONE_MINUS_CONSTANT_COLOR:
723 case GL_CONSTANT_ALPHA:
724 case GL_ONE_MINUS_CONSTANT_ALPHA:
725 break;
726 default:
727 return error(GL_INVALID_ENUM);
728 }
John Bauman66b8ab22014-05-06 15:57:45 -0400729
Nicolas Capensf160b172014-11-26 11:58:23 -0500730 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400731
Nicolas Capensf160b172014-11-26 11:58:23 -0500732 if(context)
733 {
734 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
735 }
John Bauman66b8ab22014-05-06 15:57:45 -0400736}
737
738void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
Nicolas Capens54b721d2014-12-12 12:50:04 -0500739{
740 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
Nicolas Capens4cadfe32014-12-10 22:26:26 -0500741
Nicolas Capensf160b172014-11-26 11:58:23 -0500742 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
743 target, size, data, usage);
John Bauman66b8ab22014-05-06 15:57:45 -0400744
Nicolas Capensf160b172014-11-26 11:58:23 -0500745 if(size < 0)
746 {
747 return error(GL_INVALID_VALUE);
748 }
John Bauman66b8ab22014-05-06 15:57:45 -0400749
Alexis Hetued306182015-04-02 12:02:28 -0400750 egl::GLint clientVersion = egl::getClientVersion();
751
Nicolas Capensf160b172014-11-26 11:58:23 -0500752 switch(usage)
753 {
754 case GL_STREAM_DRAW:
755 case GL_STATIC_DRAW:
756 case GL_DYNAMIC_DRAW:
757 break;
Alexis Hetued306182015-04-02 12:02:28 -0400758 case GL_STREAM_READ:
759 case GL_STREAM_COPY:
760 case GL_STATIC_READ:
761 case GL_STATIC_COPY:
762 case GL_DYNAMIC_READ:
763 case GL_DYNAMIC_COPY:
764 if(clientVersion < 3)
765 {
766 return error(GL_INVALID_ENUM);
767 }
768 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500769 default:
770 return error(GL_INVALID_ENUM);
771 }
John Bauman66b8ab22014-05-06 15:57:45 -0400772
Nicolas Capensf160b172014-11-26 11:58:23 -0500773 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400774
Nicolas Capensf160b172014-11-26 11:58:23 -0500775 if(context)
776 {
777 es2::Buffer *buffer;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400778 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -0500779 {
Nicolas Capensf160b172014-11-26 11:58:23 -0500780 return error(GL_INVALID_ENUM);
781 }
John Bauman66b8ab22014-05-06 15:57:45 -0400782
Nicolas Capensf160b172014-11-26 11:58:23 -0500783 if(!buffer)
784 {
Alexis Hetued306182015-04-02 12:02:28 -0400785 // A null buffer means that "0" is bound to the requested buffer target
Nicolas Capensf160b172014-11-26 11:58:23 -0500786 return error(GL_INVALID_OPERATION);
787 }
John Bauman66b8ab22014-05-06 15:57:45 -0400788
Nicolas Capensf160b172014-11-26 11:58:23 -0500789 buffer->bufferData(data, size, usage);
790 }
John Bauman66b8ab22014-05-06 15:57:45 -0400791}
792
793void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
Nicolas Capens54b721d2014-12-12 12:50:04 -0500794{
795 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
796 offset = static_cast<GLint>(offset);
Nicolas Capens4cadfe32014-12-10 22:26:26 -0500797
Nicolas Capensf160b172014-11-26 11:58:23 -0500798 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
799 target, offset, size, data);
John Bauman66b8ab22014-05-06 15:57:45 -0400800
Nicolas Capensf160b172014-11-26 11:58:23 -0500801 if(size < 0 || offset < 0)
802 {
803 return error(GL_INVALID_VALUE);
804 }
John Bauman66b8ab22014-05-06 15:57:45 -0400805
Nicolas Capensf160b172014-11-26 11:58:23 -0500806 if(data == NULL)
807 {
808 return;
809 }
John Bauman66b8ab22014-05-06 15:57:45 -0400810
Nicolas Capensf160b172014-11-26 11:58:23 -0500811 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400812
Nicolas Capensf160b172014-11-26 11:58:23 -0500813 if(context)
814 {
815 es2::Buffer *buffer;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400816 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -0500817 {
Nicolas Capensf160b172014-11-26 11:58:23 -0500818 return error(GL_INVALID_ENUM);
819 }
John Bauman66b8ab22014-05-06 15:57:45 -0400820
Nicolas Capensf160b172014-11-26 11:58:23 -0500821 if(!buffer)
822 {
Alexis Hetued306182015-04-02 12:02:28 -0400823 // A null buffer means that "0" is bound to the requested buffer target
Nicolas Capensf160b172014-11-26 11:58:23 -0500824 return error(GL_INVALID_OPERATION);
825 }
John Bauman66b8ab22014-05-06 15:57:45 -0400826
Nicolas Capensf160b172014-11-26 11:58:23 -0500827 if((size_t)size + offset > buffer->size())
John Bauman66b8ab22014-05-06 15:57:45 -0400828 {
829 return error(GL_INVALID_VALUE);
830 }
831
Nicolas Capensf160b172014-11-26 11:58:23 -0500832 buffer->bufferSubData(data, size, offset);
833 }
834}
John Bauman66b8ab22014-05-06 15:57:45 -0400835
Nicolas Capensf160b172014-11-26 11:58:23 -0500836GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
837{
838 TRACE("(GLenum target = 0x%X)", target);
839
840 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
841 {
842 return error(GL_INVALID_ENUM, 0);
843 }
844
845 es2::Context *context = es2::getContext();
846
847 if(context)
848 {
849 es2::Framebuffer *framebuffer = NULL;
850 if(target == GL_READ_FRAMEBUFFER_ANGLE)
851 {
852 framebuffer = context->getReadFramebuffer();
853 }
854 else
855 {
856 framebuffer = context->getDrawFramebuffer();
857 }
858
859 return framebuffer->completeness();
860 }
861
862 return 0;
863}
864
865void GL_APIENTRY glClear(GLbitfield mask)
866{
867 TRACE("(GLbitfield mask = %X)", mask);
868
869 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
870 {
871 return error(GL_INVALID_VALUE);
872 }
873
874 es2::Context *context = es2::getContext();
875
876 if(context)
877 {
878 context->clear(mask);
879 }
John Bauman66b8ab22014-05-06 15:57:45 -0400880}
881
882void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
883{
Nicolas Capensf160b172014-11-26 11:58:23 -0500884 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
885 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400886
Nicolas Capensf160b172014-11-26 11:58:23 -0500887 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400888
Nicolas Capensf160b172014-11-26 11:58:23 -0500889 if(context)
890 {
891 context->setClearColor(red, green, blue, alpha);
892 }
John Bauman66b8ab22014-05-06 15:57:45 -0400893}
894
895void GL_APIENTRY glClearDepthf(GLclampf depth)
896{
Nicolas Capensf160b172014-11-26 11:58:23 -0500897 TRACE("(GLclampf depth = %f)", depth);
John Bauman66b8ab22014-05-06 15:57:45 -0400898
Nicolas Capensf160b172014-11-26 11:58:23 -0500899 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400900
Nicolas Capensf160b172014-11-26 11:58:23 -0500901 if(context)
902 {
903 context->setClearDepth(depth);
904 }
John Bauman66b8ab22014-05-06 15:57:45 -0400905}
906
907void GL_APIENTRY glClearStencil(GLint s)
908{
Nicolas Capensf160b172014-11-26 11:58:23 -0500909 TRACE("(GLint s = %d)", s);
John Bauman66b8ab22014-05-06 15:57:45 -0400910
Nicolas Capensf160b172014-11-26 11:58:23 -0500911 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400912
Nicolas Capensf160b172014-11-26 11:58:23 -0500913 if(context)
914 {
915 context->setClearStencil(s);
916 }
John Bauman66b8ab22014-05-06 15:57:45 -0400917}
918
919void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
920{
Nicolas Capensf160b172014-11-26 11:58:23 -0500921 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
922 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400923
Nicolas Capensf160b172014-11-26 11:58:23 -0500924 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400925
Nicolas Capensf160b172014-11-26 11:58:23 -0500926 if(context)
927 {
928 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
929 }
John Bauman66b8ab22014-05-06 15:57:45 -0400930}
931
932void GL_APIENTRY glCompileShader(GLuint shader)
933{
Nicolas Capensf160b172014-11-26 11:58:23 -0500934 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400935
Nicolas Capensf160b172014-11-26 11:58:23 -0500936 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400937
Nicolas Capensf160b172014-11-26 11:58:23 -0500938 if(context)
939 {
940 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400941
Nicolas Capensf160b172014-11-26 11:58:23 -0500942 if(!shaderObject)
943 {
944 if(context->getProgram(shader))
945 {
946 return error(GL_INVALID_OPERATION);
947 }
948 else
949 {
950 return error(GL_INVALID_VALUE);
951 }
952 }
John Bauman66b8ab22014-05-06 15:57:45 -0400953
Nicolas Capensf160b172014-11-26 11:58:23 -0500954 shaderObject->compile();
955 }
John Bauman66b8ab22014-05-06 15:57:45 -0400956}
957
Nicolas Capens08e90f02014-11-21 12:49:12 -0500958void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
John Bauman66b8ab22014-05-06 15:57:45 -0400959 GLint border, GLsizei imageSize, const GLvoid* data)
960{
Nicolas Capensf160b172014-11-26 11:58:23 -0500961 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
962 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
963 target, level, internalformat, width, height, border, imageSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -0400964
Nicolas Capensf160b172014-11-26 11:58:23 -0500965 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
966 {
967 return error(GL_INVALID_VALUE);
968 }
John Bauman66b8ab22014-05-06 15:57:45 -0400969
Alexis Hetued306182015-04-02 12:02:28 -0400970 egl::GLint clientVersion = egl::getClientVersion();
971
Nicolas Capensf160b172014-11-26 11:58:23 -0500972 switch(internalformat)
973 {
Nicolas Capens22658242014-11-29 00:31:41 -0500974 case GL_ETC1_RGB8_OES:
975 break;
Alexis Hetued306182015-04-02 12:02:28 -0400976 case GL_COMPRESSED_R11_EAC:
977 case GL_COMPRESSED_SIGNED_R11_EAC:
978 case GL_COMPRESSED_RG11_EAC:
979 case GL_COMPRESSED_SIGNED_RG11_EAC:
980 case GL_COMPRESSED_RGB8_ETC2:
981 case GL_COMPRESSED_SRGB8_ETC2:
982 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
983 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
984 case GL_COMPRESSED_RGBA8_ETC2_EAC:
985 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
986 if(clientVersion >= 3)
987 {
988 break;
989 }
990 return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -0500991 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
992 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
993 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
994 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
995 if(!S3TC_SUPPORT)
996 {
997 return error(GL_INVALID_ENUM);
998 }
999 break;
1000 case GL_DEPTH_COMPONENT:
1001 case GL_DEPTH_COMPONENT16:
1002 case GL_DEPTH_COMPONENT32_OES:
1003 case GL_DEPTH_STENCIL_OES:
1004 case GL_DEPTH24_STENCIL8_OES:
1005 return error(GL_INVALID_OPERATION);
1006 default:
1007 return error(GL_INVALID_ENUM);
1008 }
John Bauman66b8ab22014-05-06 15:57:45 -04001009
Nicolas Capensf160b172014-11-26 11:58:23 -05001010 if(border != 0)
1011 {
1012 return error(GL_INVALID_VALUE);
1013 }
John Bauman66b8ab22014-05-06 15:57:45 -04001014
Nicolas Capensf160b172014-11-26 11:58:23 -05001015 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001016
Nicolas Capensf160b172014-11-26 11:58:23 -05001017 if(context)
1018 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001019 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001020 {
1021 return error(GL_INVALID_VALUE);
1022 }
John Bauman66b8ab22014-05-06 15:57:45 -04001023
Nicolas Capensf160b172014-11-26 11:58:23 -05001024 switch(target)
1025 {
1026 case GL_TEXTURE_2D:
1027 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1028 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
1029 {
1030 return error(GL_INVALID_VALUE);
1031 }
1032 break;
1033 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1034 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1035 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1036 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1037 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1038 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1039 if(width != height)
1040 {
1041 return error(GL_INVALID_VALUE);
1042 }
John Bauman66b8ab22014-05-06 15:57:45 -04001043
Nicolas Capensf160b172014-11-26 11:58:23 -05001044 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1045 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1046 {
1047 return error(GL_INVALID_VALUE);
1048 }
1049 break;
1050 default:
1051 return error(GL_INVALID_ENUM);
1052 }
John Bauman66b8ab22014-05-06 15:57:45 -04001053
Nicolas Capensf160b172014-11-26 11:58:23 -05001054 if(imageSize != es2::ComputeCompressedSize(width, height, internalformat))
1055 {
1056 return error(GL_INVALID_VALUE);
1057 }
John Bauman66b8ab22014-05-06 15:57:45 -04001058
Nicolas Capensf160b172014-11-26 11:58:23 -05001059 if(target == GL_TEXTURE_2D)
1060 {
1061 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001062
Nicolas Capensf160b172014-11-26 11:58:23 -05001063 if(!texture)
1064 {
1065 return error(GL_INVALID_OPERATION);
1066 }
John Bauman66b8ab22014-05-06 15:57:45 -04001067
Nicolas Capensf160b172014-11-26 11:58:23 -05001068 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
1069 }
1070 else
1071 {
1072 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001073
Nicolas Capensf160b172014-11-26 11:58:23 -05001074 if(!texture)
1075 {
1076 return error(GL_INVALID_OPERATION);
1077 }
John Bauman66b8ab22014-05-06 15:57:45 -04001078
Nicolas Capensf160b172014-11-26 11:58:23 -05001079 switch(target)
1080 {
1081 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1082 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1083 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1084 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1085 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1086 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1087 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
1088 break;
1089 default: UNREACHABLE();
1090 }
1091 }
1092 }
John Bauman66b8ab22014-05-06 15:57:45 -04001093}
1094
1095void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05001096 GLenum format, GLsizei imageSize, const GLvoid* data)
John Bauman66b8ab22014-05-06 15:57:45 -04001097{
Nicolas Capensf160b172014-11-26 11:58:23 -05001098 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1099 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
1100 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
1101 target, level, xoffset, yoffset, width, height, format, imageSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04001102
Nicolas Capensf160b172014-11-26 11:58:23 -05001103 if(!es2::IsTextureTarget(target))
1104 {
1105 return error(GL_INVALID_ENUM);
1106 }
John Bauman66b8ab22014-05-06 15:57:45 -04001107
Nicolas Capensf160b172014-11-26 11:58:23 -05001108 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
1109 {
1110 return error(GL_INVALID_VALUE);
1111 }
John Bauman66b8ab22014-05-06 15:57:45 -04001112
Alexis Hetued306182015-04-02 12:02:28 -04001113 egl::GLint clientVersion = egl::getClientVersion();
1114
Nicolas Capensf160b172014-11-26 11:58:23 -05001115 switch(format)
1116 {
Nicolas Capens22658242014-11-29 00:31:41 -05001117 case GL_ETC1_RGB8_OES:
1118 break;
Alexis Hetued306182015-04-02 12:02:28 -04001119 case GL_COMPRESSED_R11_EAC:
1120 case GL_COMPRESSED_SIGNED_R11_EAC:
1121 case GL_COMPRESSED_RG11_EAC:
1122 case GL_COMPRESSED_SIGNED_RG11_EAC:
1123 case GL_COMPRESSED_RGB8_ETC2:
1124 case GL_COMPRESSED_SRGB8_ETC2:
1125 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1126 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1127 case GL_COMPRESSED_RGBA8_ETC2_EAC:
1128 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1129 if(clientVersion >= 3)
1130 {
1131 break;
1132 }
1133 return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05001134 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1135 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1136 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1137 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1138 if(!S3TC_SUPPORT)
1139 {
1140 return error(GL_INVALID_ENUM);
1141 }
1142 break;
1143 default:
1144 return error(GL_INVALID_ENUM);
1145 }
John Bauman66b8ab22014-05-06 15:57:45 -04001146
Nicolas Capensf160b172014-11-26 11:58:23 -05001147 if(width == 0 || height == 0 || data == NULL)
1148 {
1149 return;
1150 }
John Bauman66b8ab22014-05-06 15:57:45 -04001151
Nicolas Capensf160b172014-11-26 11:58:23 -05001152 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001153
Nicolas Capensf160b172014-11-26 11:58:23 -05001154 if(context)
1155 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001156 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001157 {
1158 return error(GL_INVALID_VALUE);
1159 }
John Bauman66b8ab22014-05-06 15:57:45 -04001160
Nicolas Capensf160b172014-11-26 11:58:23 -05001161 if(imageSize != es2::ComputeCompressedSize(width, height, format))
1162 {
1163 return error(GL_INVALID_VALUE);
1164 }
John Bauman66b8ab22014-05-06 15:57:45 -04001165
Nicolas Capensf160b172014-11-26 11:58:23 -05001166 if(xoffset % 4 != 0 || yoffset % 4 != 0)
1167 {
1168 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
1169 return error(GL_INVALID_OPERATION);
1170 }
John Bauman66b8ab22014-05-06 15:57:45 -04001171
Nicolas Capensf160b172014-11-26 11:58:23 -05001172 if(target == GL_TEXTURE_2D)
1173 {
1174 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001175
Nicolas Capensf160b172014-11-26 11:58:23 -05001176 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
1177 {
1178 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
1179 }
1180 }
1181 else if(es2::IsCubemapTextureTarget(target))
1182 {
1183 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001184
Nicolas Capensf160b172014-11-26 11:58:23 -05001185 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
1186 {
1187 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
1188 }
1189 }
1190 else
1191 {
1192 UNREACHABLE();
1193 }
1194 }
John Bauman66b8ab22014-05-06 15:57:45 -04001195}
1196
1197void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1198{
Nicolas Capensf160b172014-11-26 11:58:23 -05001199 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
1200 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
1201 target, level, internalformat, x, y, width, height, border);
John Bauman66b8ab22014-05-06 15:57:45 -04001202
Nicolas Capensf160b172014-11-26 11:58:23 -05001203 if(!validImageSize(level, width, height))
1204 {
1205 return error(GL_INVALID_VALUE);
1206 }
John Bauman66b8ab22014-05-06 15:57:45 -04001207
Nicolas Capensf160b172014-11-26 11:58:23 -05001208 if(border != 0)
1209 {
1210 return error(GL_INVALID_VALUE);
1211 }
John Bauman66b8ab22014-05-06 15:57:45 -04001212
Nicolas Capensf160b172014-11-26 11:58:23 -05001213 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001214
Nicolas Capensf160b172014-11-26 11:58:23 -05001215 if(context)
1216 {
1217 switch(target)
1218 {
1219 case GL_TEXTURE_2D:
1220 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1221 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
1222 {
1223 return error(GL_INVALID_VALUE);
1224 }
1225 break;
1226 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1227 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1228 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1229 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1230 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1231 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1232 if(width != height)
1233 {
1234 return error(GL_INVALID_VALUE);
1235 }
John Bauman66b8ab22014-05-06 15:57:45 -04001236
Nicolas Capensf160b172014-11-26 11:58:23 -05001237 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1238 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1239 {
1240 return error(GL_INVALID_VALUE);
1241 }
1242 break;
1243 default:
1244 return error(GL_INVALID_ENUM);
1245 }
John Bauman66b8ab22014-05-06 15:57:45 -04001246
Nicolas Capensf160b172014-11-26 11:58:23 -05001247 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
John Bauman66b8ab22014-05-06 15:57:45 -04001248
Nicolas Capensf160b172014-11-26 11:58:23 -05001249 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1250 {
1251 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1252 }
John Bauman66b8ab22014-05-06 15:57:45 -04001253
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001254 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capensf160b172014-11-26 11:58:23 -05001255 {
1256 return error(GL_INVALID_OPERATION);
1257 }
John Bauman66b8ab22014-05-06 15:57:45 -04001258
Nicolas Capensf160b172014-11-26 11:58:23 -05001259 es2::Renderbuffer *source = framebuffer->getColorbuffer();
1260 GLenum colorbufferFormat = source->getFormat();
John Bauman66b8ab22014-05-06 15:57:45 -04001261
Alexis Hetub027aa92015-01-19 15:56:12 -05001262 if(!validateColorBufferFormat(internalformat, colorbufferFormat))
Nicolas Capensf160b172014-11-26 11:58:23 -05001263 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001264 return;
Nicolas Capensf160b172014-11-26 11:58:23 -05001265 }
John Bauman66b8ab22014-05-06 15:57:45 -04001266
Nicolas Capensf160b172014-11-26 11:58:23 -05001267 if(target == GL_TEXTURE_2D)
1268 {
1269 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001270
Nicolas Capensf160b172014-11-26 11:58:23 -05001271 if(!texture)
1272 {
1273 return error(GL_INVALID_OPERATION);
1274 }
John Bauman66b8ab22014-05-06 15:57:45 -04001275
Nicolas Capensf160b172014-11-26 11:58:23 -05001276 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1277 }
1278 else if(es2::IsCubemapTextureTarget(target))
1279 {
1280 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001281
Nicolas Capensf160b172014-11-26 11:58:23 -05001282 if(!texture)
1283 {
1284 return error(GL_INVALID_OPERATION);
1285 }
John Bauman66b8ab22014-05-06 15:57:45 -04001286
Nicolas Capensf160b172014-11-26 11:58:23 -05001287 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1288 }
1289 else UNREACHABLE();
1290 }
John Bauman66b8ab22014-05-06 15:57:45 -04001291}
1292
1293void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1294{
Nicolas Capensf160b172014-11-26 11:58:23 -05001295 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1296 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1297 target, level, xoffset, yoffset, x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04001298
Nicolas Capensf160b172014-11-26 11:58:23 -05001299 if(!es2::IsTextureTarget(target))
1300 {
1301 return error(GL_INVALID_ENUM);
1302 }
John Bauman66b8ab22014-05-06 15:57:45 -04001303
Nicolas Capensf160b172014-11-26 11:58:23 -05001304 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1305 {
1306 return error(GL_INVALID_VALUE);
1307 }
John Bauman66b8ab22014-05-06 15:57:45 -04001308
Nicolas Capensf160b172014-11-26 11:58:23 -05001309 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1310 {
1311 return error(GL_INVALID_VALUE);
1312 }
John Bauman66b8ab22014-05-06 15:57:45 -04001313
Nicolas Capensf160b172014-11-26 11:58:23 -05001314 if(width == 0 || height == 0)
1315 {
1316 return;
1317 }
John Bauman66b8ab22014-05-06 15:57:45 -04001318
Nicolas Capensf160b172014-11-26 11:58:23 -05001319 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001320
Nicolas Capensf160b172014-11-26 11:58:23 -05001321 if(context)
1322 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001323 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001324 {
1325 return error(GL_INVALID_VALUE);
1326 }
John Bauman66b8ab22014-05-06 15:57:45 -04001327
Nicolas Capensf160b172014-11-26 11:58:23 -05001328 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
John Bauman66b8ab22014-05-06 15:57:45 -04001329
Nicolas Capensf160b172014-11-26 11:58:23 -05001330 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1331 {
1332 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1333 }
John Bauman66b8ab22014-05-06 15:57:45 -04001334
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001335 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capensf160b172014-11-26 11:58:23 -05001336 {
1337 return error(GL_INVALID_OPERATION);
1338 }
John Bauman66b8ab22014-05-06 15:57:45 -04001339
Nicolas Capensf160b172014-11-26 11:58:23 -05001340 es2::Renderbuffer *source = framebuffer->getColorbuffer();
1341 GLenum colorbufferFormat = source->getFormat();
1342 es2::Texture *texture = NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04001343
Nicolas Capensf160b172014-11-26 11:58:23 -05001344 if(target == GL_TEXTURE_2D)
1345 {
1346 texture = context->getTexture2D();
1347 }
1348 else if(es2::IsCubemapTextureTarget(target))
1349 {
1350 texture = context->getTextureCubeMap();
1351 }
1352 else UNREACHABLE();
John Bauman66b8ab22014-05-06 15:57:45 -04001353
Nicolas Capensf160b172014-11-26 11:58:23 -05001354 if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
1355 {
1356 return;
1357 }
1358
1359 GLenum textureFormat = texture->getFormat(target, level);
1360
Alexis Hetub027aa92015-01-19 15:56:12 -05001361 if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
Nicolas Capensf160b172014-11-26 11:58:23 -05001362 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001363 return;
Nicolas Capensf160b172014-11-26 11:58:23 -05001364 }
John Bauman66b8ab22014-05-06 15:57:45 -04001365
Alexis Hetub027aa92015-01-19 15:56:12 -05001366 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
Nicolas Capensf160b172014-11-26 11:58:23 -05001367 }
John Bauman66b8ab22014-05-06 15:57:45 -04001368}
1369
1370GLuint GL_APIENTRY glCreateProgram(void)
1371{
Nicolas Capensf160b172014-11-26 11:58:23 -05001372 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04001373
Nicolas Capensf160b172014-11-26 11:58:23 -05001374 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001375
Nicolas Capensf160b172014-11-26 11:58:23 -05001376 if(context)
1377 {
1378 return context->createProgram();
1379 }
John Bauman66b8ab22014-05-06 15:57:45 -04001380
Nicolas Capensf160b172014-11-26 11:58:23 -05001381 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -04001382}
1383
1384GLuint GL_APIENTRY glCreateShader(GLenum type)
1385{
Nicolas Capensf160b172014-11-26 11:58:23 -05001386 TRACE("(GLenum type = 0x%X)", type);
John Bauman66b8ab22014-05-06 15:57:45 -04001387
Nicolas Capensf160b172014-11-26 11:58:23 -05001388 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001389
Nicolas Capensf160b172014-11-26 11:58:23 -05001390 if(context)
1391 {
1392 switch(type)
1393 {
1394 case GL_FRAGMENT_SHADER:
1395 case GL_VERTEX_SHADER:
1396 return context->createShader(type);
1397 default:
1398 return error(GL_INVALID_ENUM, 0);
1399 }
1400 }
John Bauman66b8ab22014-05-06 15:57:45 -04001401
Nicolas Capensf160b172014-11-26 11:58:23 -05001402 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -04001403}
1404
1405void GL_APIENTRY glCullFace(GLenum mode)
1406{
Nicolas Capensf160b172014-11-26 11:58:23 -05001407 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04001408
Nicolas Capensf160b172014-11-26 11:58:23 -05001409 switch(mode)
1410 {
1411 case GL_FRONT:
1412 case GL_BACK:
1413 case GL_FRONT_AND_BACK:
1414 {
1415 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001416
Nicolas Capensf160b172014-11-26 11:58:23 -05001417 if(context)
1418 {
1419 context->setCullMode(mode);
1420 }
1421 }
1422 break;
1423 default:
1424 return error(GL_INVALID_ENUM);
1425 }
John Bauman66b8ab22014-05-06 15:57:45 -04001426}
1427
1428void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
1429{
Nicolas Capensf160b172014-11-26 11:58:23 -05001430 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001431
Nicolas Capensf160b172014-11-26 11:58:23 -05001432 if(n < 0)
1433 {
1434 return error(GL_INVALID_VALUE);
1435 }
John Bauman66b8ab22014-05-06 15:57:45 -04001436
Nicolas Capensf160b172014-11-26 11:58:23 -05001437 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001438
Nicolas Capensf160b172014-11-26 11:58:23 -05001439 if(context)
1440 {
1441 for(int i = 0; i < n; i++)
1442 {
1443 context->deleteBuffer(buffers[i]);
1444 }
1445 }
John Bauman66b8ab22014-05-06 15:57:45 -04001446}
1447
1448void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
1449{
Nicolas Capensf160b172014-11-26 11:58:23 -05001450 TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04001451
Nicolas Capensf160b172014-11-26 11:58:23 -05001452 if(n < 0)
1453 {
1454 return error(GL_INVALID_VALUE);
1455 }
John Bauman66b8ab22014-05-06 15:57:45 -04001456
Nicolas Capensf160b172014-11-26 11:58:23 -05001457 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001458
Nicolas Capensf160b172014-11-26 11:58:23 -05001459 if(context)
1460 {
1461 for(int i = 0; i < n; i++)
1462 {
1463 context->deleteFence(fences[i]);
1464 }
1465 }
John Bauman66b8ab22014-05-06 15:57:45 -04001466}
1467
1468void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1469{
Nicolas Capensf160b172014-11-26 11:58:23 -05001470 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001471
Nicolas Capensf160b172014-11-26 11:58:23 -05001472 if(n < 0)
1473 {
1474 return error(GL_INVALID_VALUE);
1475 }
John Bauman66b8ab22014-05-06 15:57:45 -04001476
Nicolas Capensf160b172014-11-26 11:58:23 -05001477 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001478
Nicolas Capensf160b172014-11-26 11:58:23 -05001479 if(context)
1480 {
1481 for(int i = 0; i < n; i++)
1482 {
1483 if(framebuffers[i] != 0)
1484 {
1485 context->deleteFramebuffer(framebuffers[i]);
1486 }
1487 }
1488 }
John Bauman66b8ab22014-05-06 15:57:45 -04001489}
1490
1491void GL_APIENTRY glDeleteProgram(GLuint program)
1492{
Nicolas Capensf160b172014-11-26 11:58:23 -05001493 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04001494
Nicolas Capensf160b172014-11-26 11:58:23 -05001495 if(program == 0)
1496 {
1497 return;
1498 }
John Bauman66b8ab22014-05-06 15:57:45 -04001499
Nicolas Capensf160b172014-11-26 11:58:23 -05001500 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001501
Nicolas Capensf160b172014-11-26 11:58:23 -05001502 if(context)
1503 {
1504 if(!context->getProgram(program))
1505 {
1506 if(context->getShader(program))
1507 {
1508 return error(GL_INVALID_OPERATION);
1509 }
1510 else
1511 {
1512 return error(GL_INVALID_VALUE);
1513 }
1514 }
John Bauman66b8ab22014-05-06 15:57:45 -04001515
Nicolas Capensf160b172014-11-26 11:58:23 -05001516 context->deleteProgram(program);
1517 }
John Bauman66b8ab22014-05-06 15:57:45 -04001518}
1519
1520void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
1521{
Nicolas Capensf160b172014-11-26 11:58:23 -05001522 TRACE("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04001523
Nicolas Capensf160b172014-11-26 11:58:23 -05001524 if(n < 0)
1525 {
1526 return error(GL_INVALID_VALUE);
1527 }
John Bauman66b8ab22014-05-06 15:57:45 -04001528
Nicolas Capensf160b172014-11-26 11:58:23 -05001529 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001530
Nicolas Capensf160b172014-11-26 11:58:23 -05001531 if(context)
1532 {
1533 for(int i = 0; i < n; i++)
1534 {
1535 context->deleteQuery(ids[i]);
1536 }
1537 }
John Bauman66b8ab22014-05-06 15:57:45 -04001538}
1539
1540void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1541{
Nicolas Capensf160b172014-11-26 11:58:23 -05001542 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001543
Nicolas Capensf160b172014-11-26 11:58:23 -05001544 if(n < 0)
1545 {
1546 return error(GL_INVALID_VALUE);
1547 }
John Bauman66b8ab22014-05-06 15:57:45 -04001548
Nicolas Capensf160b172014-11-26 11:58:23 -05001549 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001550
Nicolas Capensf160b172014-11-26 11:58:23 -05001551 if(context)
1552 {
1553 for(int i = 0; i < n; i++)
1554 {
1555 context->deleteRenderbuffer(renderbuffers[i]);
1556 }
1557 }
John Bauman66b8ab22014-05-06 15:57:45 -04001558}
1559
1560void GL_APIENTRY glDeleteShader(GLuint shader)
1561{
Nicolas Capensf160b172014-11-26 11:58:23 -05001562 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04001563
Nicolas Capensf160b172014-11-26 11:58:23 -05001564 if(shader == 0)
1565 {
1566 return;
1567 }
John Bauman66b8ab22014-05-06 15:57:45 -04001568
Nicolas Capensf160b172014-11-26 11:58:23 -05001569 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001570
Nicolas Capensf160b172014-11-26 11:58:23 -05001571 if(context)
1572 {
1573 if(!context->getShader(shader))
1574 {
1575 if(context->getProgram(shader))
1576 {
1577 return error(GL_INVALID_OPERATION);
1578 }
1579 else
1580 {
1581 return error(GL_INVALID_VALUE);
1582 }
1583 }
John Bauman66b8ab22014-05-06 15:57:45 -04001584
Nicolas Capensf160b172014-11-26 11:58:23 -05001585 context->deleteShader(shader);
1586 }
John Bauman66b8ab22014-05-06 15:57:45 -04001587}
1588
1589void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
1590{
Nicolas Capensf160b172014-11-26 11:58:23 -05001591 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04001592
Nicolas Capensf160b172014-11-26 11:58:23 -05001593 if(n < 0)
1594 {
1595 return error(GL_INVALID_VALUE);
1596 }
John Bauman66b8ab22014-05-06 15:57:45 -04001597
Nicolas Capensf160b172014-11-26 11:58:23 -05001598 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001599
Nicolas Capensf160b172014-11-26 11:58:23 -05001600 if(context)
1601 {
1602 for(int i = 0; i < n; i++)
1603 {
1604 if(textures[i] != 0)
1605 {
1606 context->deleteTexture(textures[i]);
1607 }
1608 }
1609 }
John Bauman66b8ab22014-05-06 15:57:45 -04001610}
1611
1612void GL_APIENTRY glDepthFunc(GLenum func)
1613{
Nicolas Capensf160b172014-11-26 11:58:23 -05001614 TRACE("(GLenum func = 0x%X)", func);
John Bauman66b8ab22014-05-06 15:57:45 -04001615
Nicolas Capensf160b172014-11-26 11:58:23 -05001616 switch(func)
1617 {
1618 case GL_NEVER:
1619 case GL_ALWAYS:
1620 case GL_LESS:
1621 case GL_LEQUAL:
1622 case GL_EQUAL:
1623 case GL_GREATER:
1624 case GL_GEQUAL:
1625 case GL_NOTEQUAL:
1626 break;
1627 default:
1628 return error(GL_INVALID_ENUM);
1629 }
John Bauman66b8ab22014-05-06 15:57:45 -04001630
Nicolas Capensf160b172014-11-26 11:58:23 -05001631 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001632
Nicolas Capensf160b172014-11-26 11:58:23 -05001633 if(context)
1634 {
1635 context->setDepthFunc(func);
1636 }
John Bauman66b8ab22014-05-06 15:57:45 -04001637}
1638
1639void GL_APIENTRY glDepthMask(GLboolean flag)
1640{
Nicolas Capensf160b172014-11-26 11:58:23 -05001641 TRACE("(GLboolean flag = %d)", flag);
John Bauman66b8ab22014-05-06 15:57:45 -04001642
Nicolas Capensf160b172014-11-26 11:58:23 -05001643 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001644
Nicolas Capensf160b172014-11-26 11:58:23 -05001645 if(context)
1646 {
1647 context->setDepthMask(flag != GL_FALSE);
1648 }
John Bauman66b8ab22014-05-06 15:57:45 -04001649}
1650
1651void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
1652{
Nicolas Capensf160b172014-11-26 11:58:23 -05001653 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
John Bauman66b8ab22014-05-06 15:57:45 -04001654
Nicolas Capensf160b172014-11-26 11:58:23 -05001655 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001656
Nicolas Capensf160b172014-11-26 11:58:23 -05001657 if(context)
1658 {
1659 context->setDepthRange(zNear, zFar);
1660 }
John Bauman66b8ab22014-05-06 15:57:45 -04001661}
1662
1663void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
1664{
Nicolas Capensf160b172014-11-26 11:58:23 -05001665 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
John Bauman66b8ab22014-05-06 15:57:45 -04001666
Nicolas Capensf160b172014-11-26 11:58:23 -05001667 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001668
Nicolas Capensf160b172014-11-26 11:58:23 -05001669 if(context)
1670 {
John Bauman66b8ab22014-05-06 15:57:45 -04001671
Nicolas Capensf160b172014-11-26 11:58:23 -05001672 es2::Program *programObject = context->getProgram(program);
1673 es2::Shader *shaderObject = context->getShader(shader);
Nicolas Capens08e90f02014-11-21 12:49:12 -05001674
Nicolas Capensf160b172014-11-26 11:58:23 -05001675 if(!programObject)
1676 {
1677 es2::Shader *shaderByProgramHandle;
1678 shaderByProgramHandle = context->getShader(program);
1679 if(!shaderByProgramHandle)
1680 {
1681 return error(GL_INVALID_VALUE);
1682 }
1683 else
1684 {
1685 return error(GL_INVALID_OPERATION);
1686 }
1687 }
John Bauman66b8ab22014-05-06 15:57:45 -04001688
Nicolas Capensf160b172014-11-26 11:58:23 -05001689 if(!shaderObject)
1690 {
1691 es2::Program *programByShaderHandle = context->getProgram(shader);
1692 if(!programByShaderHandle)
1693 {
1694 return error(GL_INVALID_VALUE);
1695 }
1696 else
1697 {
1698 return error(GL_INVALID_OPERATION);
1699 }
1700 }
John Bauman66b8ab22014-05-06 15:57:45 -04001701
Nicolas Capensf160b172014-11-26 11:58:23 -05001702 if(!programObject->detachShader(shaderObject))
1703 {
1704 return error(GL_INVALID_OPERATION);
1705 }
1706 }
John Bauman66b8ab22014-05-06 15:57:45 -04001707}
1708
1709void GL_APIENTRY glDisable(GLenum cap)
1710{
Nicolas Capensf160b172014-11-26 11:58:23 -05001711 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04001712
Nicolas Capensf160b172014-11-26 11:58:23 -05001713 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001714
Nicolas Capensf160b172014-11-26 11:58:23 -05001715 if(context)
1716 {
1717 switch(cap)
1718 {
1719 case GL_CULL_FACE: context->setCullFace(false); break;
1720 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1721 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1722 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1723 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1724 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1725 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1726 case GL_BLEND: context->setBlend(false); break;
1727 case GL_DITHER: context->setDither(false); break;
Alexis Hetufceb1832015-03-10 16:42:04 -04001728 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndex(false); break;
1729 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscard(false); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05001730 default:
1731 return error(GL_INVALID_ENUM);
1732 }
1733 }
John Bauman66b8ab22014-05-06 15:57:45 -04001734}
1735
1736void GL_APIENTRY glDisableVertexAttribArray(GLuint index)
1737{
Nicolas Capensf160b172014-11-26 11:58:23 -05001738 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04001739
Nicolas Capensf160b172014-11-26 11:58:23 -05001740 if(index >= es2::MAX_VERTEX_ATTRIBS)
1741 {
1742 return error(GL_INVALID_VALUE);
1743 }
John Bauman66b8ab22014-05-06 15:57:45 -04001744
Nicolas Capensf160b172014-11-26 11:58:23 -05001745 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001746
Nicolas Capensf160b172014-11-26 11:58:23 -05001747 if(context)
1748 {
1749 context->setEnableVertexAttribArray(index, false);
1750 }
John Bauman66b8ab22014-05-06 15:57:45 -04001751}
1752
1753void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
1754{
Nicolas Capensf160b172014-11-26 11:58:23 -05001755 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
John Bauman66b8ab22014-05-06 15:57:45 -04001756
Alexis Hetued306182015-04-02 12:02:28 -04001757 switch(mode)
1758 {
1759 case GL_POINTS:
1760 case GL_LINES:
1761 case GL_LINE_LOOP:
1762 case GL_LINE_STRIP:
1763 case GL_TRIANGLES:
1764 case GL_TRIANGLE_FAN:
1765 case GL_TRIANGLE_STRIP:
1766 break;
1767 default:
1768 return error(GL_INVALID_ENUM);
1769 }
1770
Nicolas Capensf160b172014-11-26 11:58:23 -05001771 if(count < 0 || first < 0)
1772 {
1773 return error(GL_INVALID_VALUE);
1774 }
John Bauman66b8ab22014-05-06 15:57:45 -04001775
Nicolas Capensf160b172014-11-26 11:58:23 -05001776 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001777
Nicolas Capensf160b172014-11-26 11:58:23 -05001778 if(context)
1779 {
1780 context->drawArrays(mode, first, count);
1781 }
John Bauman66b8ab22014-05-06 15:57:45 -04001782}
1783
1784void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
1785{
Nicolas Capensf160b172014-11-26 11:58:23 -05001786 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
1787 mode, count, type, indices);
John Bauman66b8ab22014-05-06 15:57:45 -04001788
Alexis Hetued306182015-04-02 12:02:28 -04001789 switch(mode)
1790 {
1791 case GL_POINTS:
1792 case GL_LINES:
1793 case GL_LINE_LOOP:
1794 case GL_LINE_STRIP:
1795 case GL_TRIANGLES:
1796 case GL_TRIANGLE_FAN:
1797 case GL_TRIANGLE_STRIP:
1798 break;
1799 default:
1800 return error(GL_INVALID_ENUM);
1801 }
1802
Nicolas Capensf160b172014-11-26 11:58:23 -05001803 if(count < 0)
1804 {
1805 return error(GL_INVALID_VALUE);
1806 }
John Bauman66b8ab22014-05-06 15:57:45 -04001807
Nicolas Capensf160b172014-11-26 11:58:23 -05001808 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001809
Nicolas Capensf160b172014-11-26 11:58:23 -05001810 if(context)
1811 {
1812 switch(type)
1813 {
1814 case GL_UNSIGNED_BYTE:
1815 case GL_UNSIGNED_SHORT:
1816 case GL_UNSIGNED_INT:
1817 break;
1818 default:
1819 return error(GL_INVALID_ENUM);
1820 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05001821
Alexis Hetu07334692015-04-10 14:51:27 -04001822 context->drawElements(mode, 0, UINT_MAX, count, type, indices);
Nicolas Capensf160b172014-11-26 11:58:23 -05001823 }
John Bauman66b8ab22014-05-06 15:57:45 -04001824}
1825
Alexis Hetue8af6d12015-04-17 16:58:45 -04001826void GL_APIENTRY glDrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1827{
1828 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1829 mode, first, count, instanceCount);
1830
1831 switch(mode)
1832 {
1833 case GL_POINTS:
1834 case GL_LINES:
1835 case GL_LINE_LOOP:
1836 case GL_LINE_STRIP:
1837 case GL_TRIANGLES:
1838 case GL_TRIANGLE_FAN:
1839 case GL_TRIANGLE_STRIP:
1840 break;
1841 default:
1842 return error(GL_INVALID_ENUM);
1843 }
1844
1845 if(count < 0 || instanceCount < 0)
1846 {
1847 return error(GL_INVALID_VALUE);
1848 }
1849
1850 es2::Context *context = es2::getContext();
1851
1852 if(context)
1853 {
1854 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1855 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1856 {
1857 return error(GL_INVALID_OPERATION);
1858 }
1859
1860 context->drawArrays(mode, first, count, instanceCount);
1861 }
1862}
1863
1864void GL_APIENTRY glDrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
1865{
1866 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = 0x%0.8p, GLsizei instanceCount = %d)",
1867 mode, count, type, indices, instanceCount);
1868
1869 switch(mode)
1870 {
1871 case GL_POINTS:
1872 case GL_LINES:
1873 case GL_LINE_LOOP:
1874 case GL_LINE_STRIP:
1875 case GL_TRIANGLES:
1876 case GL_TRIANGLE_FAN:
1877 case GL_TRIANGLE_STRIP:
1878 break;
1879 default:
1880 return error(GL_INVALID_ENUM);
1881 }
1882
1883 switch(type)
1884 {
1885 case GL_UNSIGNED_BYTE:
1886 case GL_UNSIGNED_SHORT:
1887 case GL_UNSIGNED_INT:
1888 break;
1889 default:
1890 return error(GL_INVALID_ENUM);
1891 }
1892
1893 if(count < 0 || instanceCount < 0)
1894 {
1895 return error(GL_INVALID_VALUE);
1896 }
1897
1898 es2::Context *context = es2::getContext();
1899
1900 if(context)
1901 {
1902 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1903 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1904 {
1905 return error(GL_INVALID_OPERATION);
1906 }
1907
1908 context->drawElements(mode, 0, UINT_MAX, count, type, indices, instanceCount);
1909 }
1910}
1911
1912void GL_APIENTRY glVertexAttribDivisorEXT(GLuint index, GLuint divisor)
1913{
1914 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1915
1916 es2::Context *context = es2::getContext();
1917
1918 if(context)
1919 {
1920 if(index >= es2::MAX_VERTEX_ATTRIBS)
1921 {
1922 return error(GL_INVALID_VALUE);
1923 }
1924
1925 context->setVertexAttribDivisor(index, divisor);
1926 }
1927}
1928
John Bauman66b8ab22014-05-06 15:57:45 -04001929void GL_APIENTRY glEnable(GLenum cap)
1930{
Nicolas Capensf160b172014-11-26 11:58:23 -05001931 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04001932
Nicolas Capensf160b172014-11-26 11:58:23 -05001933 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001934
Nicolas Capensf160b172014-11-26 11:58:23 -05001935 if(context)
1936 {
1937 switch(cap)
1938 {
1939 case GL_CULL_FACE: context->setCullFace(true); break;
1940 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1941 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1942 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1943 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1944 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1945 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1946 case GL_BLEND: context->setBlend(true); break;
1947 case GL_DITHER: context->setDither(true); break;
Alexis Hetufceb1832015-03-10 16:42:04 -04001948 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndex(true); break;
1949 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscard(true); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05001950 default:
1951 return error(GL_INVALID_ENUM);
1952 }
1953 }
John Bauman66b8ab22014-05-06 15:57:45 -04001954}
1955
1956void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
1957{
Nicolas Capensf160b172014-11-26 11:58:23 -05001958 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04001959
Nicolas Capensf160b172014-11-26 11:58:23 -05001960 if(index >= es2::MAX_VERTEX_ATTRIBS)
1961 {
1962 return error(GL_INVALID_VALUE);
1963 }
John Bauman66b8ab22014-05-06 15:57:45 -04001964
Nicolas Capensf160b172014-11-26 11:58:23 -05001965 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001966
Nicolas Capensf160b172014-11-26 11:58:23 -05001967 if(context)
1968 {
1969 context->setEnableVertexAttribArray(index, true);
1970 }
John Bauman66b8ab22014-05-06 15:57:45 -04001971}
1972
1973void GL_APIENTRY glEndQueryEXT(GLenum target)
1974{
Nicolas Capensf160b172014-11-26 11:58:23 -05001975 TRACE("GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04001976
Nicolas Capensf160b172014-11-26 11:58:23 -05001977 switch(target)
1978 {
1979 case GL_ANY_SAMPLES_PASSED_EXT:
1980 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1981 break;
1982 default:
1983 return error(GL_INVALID_ENUM);
1984 }
John Bauman66b8ab22014-05-06 15:57:45 -04001985
Nicolas Capensf160b172014-11-26 11:58:23 -05001986 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001987
Nicolas Capensf160b172014-11-26 11:58:23 -05001988 if(context)
1989 {
1990 context->endQuery(target);
1991 }
John Bauman66b8ab22014-05-06 15:57:45 -04001992}
1993
1994void GL_APIENTRY glFinishFenceNV(GLuint fence)
1995{
Nicolas Capensf160b172014-11-26 11:58:23 -05001996 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04001997
Nicolas Capensf160b172014-11-26 11:58:23 -05001998 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001999
Nicolas Capensf160b172014-11-26 11:58:23 -05002000 if(context)
2001 {
2002 es2::Fence* fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002003
Nicolas Capensf160b172014-11-26 11:58:23 -05002004 if(fenceObject == NULL)
2005 {
2006 return error(GL_INVALID_OPERATION);
2007 }
John Bauman66b8ab22014-05-06 15:57:45 -04002008
Nicolas Capensf160b172014-11-26 11:58:23 -05002009 fenceObject->finishFence();
2010 }
John Bauman66b8ab22014-05-06 15:57:45 -04002011}
2012
2013void GL_APIENTRY glFinish(void)
2014{
Nicolas Capensf160b172014-11-26 11:58:23 -05002015 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002016
Nicolas Capensf160b172014-11-26 11:58:23 -05002017 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002018
Nicolas Capensf160b172014-11-26 11:58:23 -05002019 if(context)
2020 {
2021 context->finish();
2022 }
John Bauman66b8ab22014-05-06 15:57:45 -04002023}
2024
2025void GL_APIENTRY glFlush(void)
2026{
Nicolas Capensf160b172014-11-26 11:58:23 -05002027 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002028
Nicolas Capensf160b172014-11-26 11:58:23 -05002029 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002030
Nicolas Capensf160b172014-11-26 11:58:23 -05002031 if(context)
2032 {
2033 context->flush();
2034 }
John Bauman66b8ab22014-05-06 15:57:45 -04002035}
2036
2037void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2038{
Nicolas Capensf160b172014-11-26 11:58:23 -05002039 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
2040 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04002041
Nicolas Capensf160b172014-11-26 11:58:23 -05002042 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
2043 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
2044 {
2045 return error(GL_INVALID_ENUM);
2046 }
John Bauman66b8ab22014-05-06 15:57:45 -04002047
Nicolas Capensf160b172014-11-26 11:58:23 -05002048 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002049
Nicolas Capensf160b172014-11-26 11:58:23 -05002050 if(context)
2051 {
2052 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002053 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002054 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2055 {
2056 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002057 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002058 }
2059 else
2060 {
2061 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002062 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002063 }
John Bauman66b8ab22014-05-06 15:57:45 -04002064
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002065 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capensf160b172014-11-26 11:58:23 -05002066 {
2067 return error(GL_INVALID_OPERATION);
2068 }
John Bauman66b8ab22014-05-06 15:57:45 -04002069
Nicolas Capensf160b172014-11-26 11:58:23 -05002070 switch(attachment)
2071 {
2072 case GL_COLOR_ATTACHMENT0:
2073 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2074 break;
2075 case GL_DEPTH_ATTACHMENT:
2076 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2077 break;
2078 case GL_STENCIL_ATTACHMENT:
2079 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2080 break;
2081 default:
2082 return error(GL_INVALID_ENUM);
2083 }
2084 }
John Bauman66b8ab22014-05-06 15:57:45 -04002085}
2086
2087void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2088{
Nicolas Capensf160b172014-11-26 11:58:23 -05002089 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
2090 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
John Bauman66b8ab22014-05-06 15:57:45 -04002091
Nicolas Capensf160b172014-11-26 11:58:23 -05002092 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2093 {
2094 return error(GL_INVALID_ENUM);
2095 }
John Bauman66b8ab22014-05-06 15:57:45 -04002096
Nicolas Capensf160b172014-11-26 11:58:23 -05002097 switch(attachment)
2098 {
2099 case GL_COLOR_ATTACHMENT0:
2100 case GL_DEPTH_ATTACHMENT:
2101 case GL_STENCIL_ATTACHMENT:
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 if(texture == 0)
2112 {
2113 textarget = GL_NONE;
2114 }
2115 else
2116 {
2117 es2::Texture *tex = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04002118
Nicolas Capensf160b172014-11-26 11:58:23 -05002119 if(tex == NULL)
2120 {
2121 return error(GL_INVALID_OPERATION);
2122 }
John Bauman66b8ab22014-05-06 15:57:45 -04002123
Nicolas Capensf160b172014-11-26 11:58:23 -05002124 if(tex->isCompressed(textarget, level))
2125 {
2126 return error(GL_INVALID_OPERATION);
2127 }
John Bauman66b8ab22014-05-06 15:57:45 -04002128
Nicolas Capensf160b172014-11-26 11:58:23 -05002129 switch(textarget)
2130 {
2131 case GL_TEXTURE_2D:
2132 if(tex->getTarget() != GL_TEXTURE_2D)
2133 {
2134 return error(GL_INVALID_OPERATION);
2135 }
2136 break;
2137 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2138 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2139 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2140 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2141 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2142 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2143 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2144 {
2145 return error(GL_INVALID_OPERATION);
2146 }
2147 break;
2148 default:
2149 return error(GL_INVALID_ENUM);
2150 }
John Bauman66b8ab22014-05-06 15:57:45 -04002151
Nicolas Capensf160b172014-11-26 11:58:23 -05002152 if(level != 0)
2153 {
2154 return error(GL_INVALID_VALUE);
2155 }
2156 }
John Bauman66b8ab22014-05-06 15:57:45 -04002157
Nicolas Capensf160b172014-11-26 11:58:23 -05002158 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002159 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002160 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2161 {
2162 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002163 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002164 }
2165 else
2166 {
2167 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002168 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002169 }
John Bauman66b8ab22014-05-06 15:57:45 -04002170
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002171 if(framebufferName == 0 || !framebuffer)
Nicolas Capensf160b172014-11-26 11:58:23 -05002172 {
2173 return error(GL_INVALID_OPERATION);
2174 }
John Bauman66b8ab22014-05-06 15:57:45 -04002175
Nicolas Capensf160b172014-11-26 11:58:23 -05002176 switch(attachment)
2177 {
2178 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2179 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2180 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2181 }
2182 }
John Bauman66b8ab22014-05-06 15:57:45 -04002183}
2184
2185void GL_APIENTRY glFrontFace(GLenum mode)
2186{
Nicolas Capensf160b172014-11-26 11:58:23 -05002187 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04002188
Nicolas Capensf160b172014-11-26 11:58:23 -05002189 switch(mode)
2190 {
2191 case GL_CW:
2192 case GL_CCW:
2193 {
2194 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002195
Nicolas Capensf160b172014-11-26 11:58:23 -05002196 if(context)
2197 {
2198 context->setFrontFace(mode);
2199 }
2200 }
2201 break;
2202 default:
2203 return error(GL_INVALID_ENUM);
2204 }
John Bauman66b8ab22014-05-06 15:57:45 -04002205}
2206
2207void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
2208{
Nicolas Capensf160b172014-11-26 11:58:23 -05002209 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002210
Nicolas Capensf160b172014-11-26 11:58:23 -05002211 if(n < 0)
2212 {
2213 return error(GL_INVALID_VALUE);
2214 }
John Bauman66b8ab22014-05-06 15:57:45 -04002215
Nicolas Capensf160b172014-11-26 11:58:23 -05002216 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002217
Nicolas Capensf160b172014-11-26 11:58:23 -05002218 if(context)
2219 {
2220 for(int i = 0; i < n; i++)
2221 {
2222 buffers[i] = context->createBuffer();
2223 }
2224 }
John Bauman66b8ab22014-05-06 15:57:45 -04002225}
2226
2227void GL_APIENTRY glGenerateMipmap(GLenum target)
2228{
Nicolas Capensf160b172014-11-26 11:58:23 -05002229 TRACE("(GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04002230
Nicolas Capensf160b172014-11-26 11:58:23 -05002231 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002232
Nicolas Capensf160b172014-11-26 11:58:23 -05002233 if(context)
2234 {
Alexis Hetued306182015-04-02 12:02:28 -04002235 es2::Texture *texture = nullptr;
2236
2237 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04002238
Nicolas Capensf160b172014-11-26 11:58:23 -05002239 switch(target)
2240 {
2241 case GL_TEXTURE_2D:
2242 texture = context->getTexture2D();
2243 break;
2244 case GL_TEXTURE_CUBE_MAP:
2245 texture = context->getTextureCubeMap();
2246 break;
Alexis Hetued306182015-04-02 12:02:28 -04002247 case GL_TEXTURE_2D_ARRAY:
2248 if(clientVersion < 3)
2249 {
2250 return error(GL_INVALID_ENUM);
2251 }
2252 else
2253 {
2254 UNIMPLEMENTED();
2255 texture = context->getTexture3D();
2256 break;
2257 }
2258 case GL_TEXTURE_3D_OES:
2259 texture = context->getTexture3D();
2260 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05002261 default:
2262 return error(GL_INVALID_ENUM);
2263 }
John Bauman66b8ab22014-05-06 15:57:45 -04002264
Nicolas Capensf160b172014-11-26 11:58:23 -05002265 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2266 {
2267 return error(GL_INVALID_OPERATION);
2268 }
John Bauman66b8ab22014-05-06 15:57:45 -04002269
Nicolas Capensf160b172014-11-26 11:58:23 -05002270 texture->generateMipmaps();
2271 }
John Bauman66b8ab22014-05-06 15:57:45 -04002272}
2273
2274void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
2275{
Nicolas Capensf160b172014-11-26 11:58:23 -05002276 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04002277
Nicolas Capensf160b172014-11-26 11:58:23 -05002278 if(n < 0)
2279 {
2280 return error(GL_INVALID_VALUE);
2281 }
John Bauman66b8ab22014-05-06 15:57:45 -04002282
Nicolas Capensf160b172014-11-26 11:58:23 -05002283 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002284
Nicolas Capensf160b172014-11-26 11:58:23 -05002285 if(context)
2286 {
2287 for(int i = 0; i < n; i++)
2288 {
2289 fences[i] = context->createFence();
2290 }
2291 }
John Bauman66b8ab22014-05-06 15:57:45 -04002292}
2293
2294void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2295{
Nicolas Capensf160b172014-11-26 11:58:23 -05002296 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002297
Nicolas Capensf160b172014-11-26 11:58:23 -05002298 if(n < 0)
2299 {
2300 return error(GL_INVALID_VALUE);
2301 }
John Bauman66b8ab22014-05-06 15:57:45 -04002302
Nicolas Capensf160b172014-11-26 11:58:23 -05002303 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002304
Nicolas Capensf160b172014-11-26 11:58:23 -05002305 if(context)
2306 {
2307 for(int i = 0; i < n; i++)
2308 {
2309 framebuffers[i] = context->createFramebuffer();
2310 }
2311 }
John Bauman66b8ab22014-05-06 15:57:45 -04002312}
2313
2314void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
2315{
Nicolas Capensf160b172014-11-26 11:58:23 -05002316 TRACE("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04002317
Nicolas Capensf160b172014-11-26 11:58:23 -05002318 if(n < 0)
2319 {
2320 return error(GL_INVALID_VALUE);
2321 }
John Bauman66b8ab22014-05-06 15:57:45 -04002322
Nicolas Capensf160b172014-11-26 11:58:23 -05002323 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002324
Nicolas Capensf160b172014-11-26 11:58:23 -05002325 if(context)
2326 {
2327 for(int i = 0; i < n; i++)
2328 {
2329 ids[i] = context->createQuery();
2330 }
2331 }
John Bauman66b8ab22014-05-06 15:57:45 -04002332}
2333
2334void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2335{
Nicolas Capensf160b172014-11-26 11:58:23 -05002336 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002337
Nicolas Capensf160b172014-11-26 11:58:23 -05002338 if(n < 0)
2339 {
2340 return error(GL_INVALID_VALUE);
2341 }
John Bauman66b8ab22014-05-06 15:57:45 -04002342
Nicolas Capensf160b172014-11-26 11:58:23 -05002343 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002344
Nicolas Capensf160b172014-11-26 11:58:23 -05002345 if(context)
2346 {
2347 for(int i = 0; i < n; i++)
2348 {
2349 renderbuffers[i] = context->createRenderbuffer();
2350 }
2351 }
John Bauman66b8ab22014-05-06 15:57:45 -04002352}
2353
2354void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
2355{
Nicolas Capensf160b172014-11-26 11:58:23 -05002356 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04002357
Nicolas Capensf160b172014-11-26 11:58:23 -05002358 if(n < 0)
2359 {
2360 return error(GL_INVALID_VALUE);
2361 }
John Bauman66b8ab22014-05-06 15:57:45 -04002362
Nicolas Capensf160b172014-11-26 11:58:23 -05002363 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002364
Nicolas Capensf160b172014-11-26 11:58:23 -05002365 if(context)
2366 {
2367 for(int i = 0; i < n; i++)
2368 {
2369 textures[i] = context->createTexture();
2370 }
2371 }
John Bauman66b8ab22014-05-06 15:57:45 -04002372}
2373
2374void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
2375{
Nicolas Capensf160b172014-11-26 11:58:23 -05002376 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2377 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
2378 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002379
Nicolas Capensf160b172014-11-26 11:58:23 -05002380 if(bufsize < 0)
2381 {
2382 return error(GL_INVALID_VALUE);
2383 }
John Bauman66b8ab22014-05-06 15:57:45 -04002384
Nicolas Capensf160b172014-11-26 11:58:23 -05002385 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002386
Nicolas Capensf160b172014-11-26 11:58:23 -05002387 if(context)
2388 {
2389 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002390
Nicolas Capensf160b172014-11-26 11:58:23 -05002391 if(!programObject)
2392 {
2393 if(context->getShader(program))
2394 {
2395 return error(GL_INVALID_OPERATION);
2396 }
2397 else
2398 {
2399 return error(GL_INVALID_VALUE);
2400 }
2401 }
John Bauman66b8ab22014-05-06 15:57:45 -04002402
Nicolas Capensf160b172014-11-26 11:58:23 -05002403 if(index >= (GLuint)programObject->getActiveAttributeCount())
2404 {
2405 return error(GL_INVALID_VALUE);
2406 }
John Bauman66b8ab22014-05-06 15:57:45 -04002407
Nicolas Capensf160b172014-11-26 11:58:23 -05002408 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2409 }
John Bauman66b8ab22014-05-06 15:57:45 -04002410}
2411
2412void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
2413{
Nicolas Capensf160b172014-11-26 11:58:23 -05002414 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2415 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = %s)",
2416 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002417
Nicolas Capensf160b172014-11-26 11:58:23 -05002418 if(bufsize < 0)
2419 {
2420 return error(GL_INVALID_VALUE);
2421 }
John Bauman66b8ab22014-05-06 15:57:45 -04002422
Nicolas Capensf160b172014-11-26 11:58:23 -05002423 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002424
Nicolas Capensf160b172014-11-26 11:58:23 -05002425 if(context)
2426 {
2427 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002428
Nicolas Capensf160b172014-11-26 11:58:23 -05002429 if(!programObject)
2430 {
2431 if(context->getShader(program))
2432 {
2433 return error(GL_INVALID_OPERATION);
2434 }
2435 else
2436 {
2437 return error(GL_INVALID_VALUE);
2438 }
2439 }
John Bauman66b8ab22014-05-06 15:57:45 -04002440
Nicolas Capensf160b172014-11-26 11:58:23 -05002441 if(index >= (GLuint)programObject->getActiveUniformCount())
2442 {
2443 return error(GL_INVALID_VALUE);
2444 }
John Bauman66b8ab22014-05-06 15:57:45 -04002445
Nicolas Capensf160b172014-11-26 11:58:23 -05002446 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2447 }
John Bauman66b8ab22014-05-06 15:57:45 -04002448}
2449
2450void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2451{
Nicolas Capensf160b172014-11-26 11:58:23 -05002452 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2453 program, maxcount, count, shaders);
John Bauman66b8ab22014-05-06 15:57:45 -04002454
Nicolas Capensf160b172014-11-26 11:58:23 -05002455 if(maxcount < 0)
2456 {
2457 return error(GL_INVALID_VALUE);
2458 }
John Bauman66b8ab22014-05-06 15:57:45 -04002459
Nicolas Capensf160b172014-11-26 11:58:23 -05002460 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002461
Nicolas Capensf160b172014-11-26 11:58:23 -05002462 if(context)
2463 {
2464 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002465
Nicolas Capensf160b172014-11-26 11:58:23 -05002466 if(!programObject)
2467 {
2468 if(context->getShader(program))
2469 {
2470 return error(GL_INVALID_OPERATION);
2471 }
2472 else
2473 {
2474 return error(GL_INVALID_VALUE);
2475 }
2476 }
John Bauman66b8ab22014-05-06 15:57:45 -04002477
Nicolas Capensf160b172014-11-26 11:58:23 -05002478 return programObject->getAttachedShaders(maxcount, count, shaders);
2479 }
John Bauman66b8ab22014-05-06 15:57:45 -04002480}
2481
2482int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
2483{
Nicolas Capensf160b172014-11-26 11:58:23 -05002484 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002485
Nicolas Capensf160b172014-11-26 11:58:23 -05002486 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002487
Nicolas Capensf160b172014-11-26 11:58:23 -05002488 if(context)
2489 {
John Bauman66b8ab22014-05-06 15:57:45 -04002490
Nicolas Capensf160b172014-11-26 11:58:23 -05002491 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002492
Nicolas Capensf160b172014-11-26 11:58:23 -05002493 if(!programObject)
2494 {
2495 if(context->getShader(program))
2496 {
2497 return error(GL_INVALID_OPERATION, -1);
2498 }
2499 else
2500 {
2501 return error(GL_INVALID_VALUE, -1);
2502 }
2503 }
John Bauman66b8ab22014-05-06 15:57:45 -04002504
Nicolas Capensf160b172014-11-26 11:58:23 -05002505 if(!programObject->isLinked())
2506 {
2507 return error(GL_INVALID_OPERATION, -1);
2508 }
John Bauman66b8ab22014-05-06 15:57:45 -04002509
Nicolas Capensf160b172014-11-26 11:58:23 -05002510 return programObject->getAttributeLocation(name);
2511 }
John Bauman66b8ab22014-05-06 15:57:45 -04002512
Nicolas Capensf160b172014-11-26 11:58:23 -05002513 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04002514}
2515
2516void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
2517{
Nicolas Capensf160b172014-11-26 11:58:23 -05002518 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002519
Nicolas Capensf160b172014-11-26 11:58:23 -05002520 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002521
Nicolas Capensf160b172014-11-26 11:58:23 -05002522 if(context)
2523 {
2524 if(!(context->getBooleanv(pname, params)))
2525 {
2526 GLenum nativeType;
2527 unsigned int numParams = 0;
2528 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2529 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002530
Nicolas Capensf160b172014-11-26 11:58:23 -05002531 if(numParams == 0)
2532 return; // it is known that the pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04002533
Nicolas Capensf160b172014-11-26 11:58:23 -05002534 if(nativeType == GL_FLOAT)
2535 {
2536 GLfloat *floatParams = NULL;
2537 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002538
Nicolas Capensf160b172014-11-26 11:58:23 -05002539 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002540
Nicolas Capensf160b172014-11-26 11:58:23 -05002541 for(unsigned int i = 0; i < numParams; ++i)
2542 {
2543 if(floatParams[i] == 0.0f)
2544 params[i] = GL_FALSE;
2545 else
2546 params[i] = GL_TRUE;
2547 }
John Bauman66b8ab22014-05-06 15:57:45 -04002548
Nicolas Capensf160b172014-11-26 11:58:23 -05002549 delete [] floatParams;
2550 }
2551 else if(nativeType == GL_INT)
2552 {
2553 GLint *intParams = NULL;
2554 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002555
Nicolas Capensf160b172014-11-26 11:58:23 -05002556 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002557
Nicolas Capensf160b172014-11-26 11:58:23 -05002558 for(unsigned int i = 0; i < numParams; ++i)
2559 {
2560 if(intParams[i] == 0)
2561 params[i] = GL_FALSE;
2562 else
2563 params[i] = GL_TRUE;
2564 }
John Bauman66b8ab22014-05-06 15:57:45 -04002565
Nicolas Capensf160b172014-11-26 11:58:23 -05002566 delete [] intParams;
2567 }
2568 }
2569 }
John Bauman66b8ab22014-05-06 15:57:45 -04002570}
2571
2572void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2573{
Nicolas Capensf160b172014-11-26 11:58:23 -05002574 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002575
Nicolas Capensf160b172014-11-26 11:58:23 -05002576 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002577
Nicolas Capensf160b172014-11-26 11:58:23 -05002578 if(context)
2579 {
2580 es2::Buffer *buffer;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -04002581 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -05002582 {
Nicolas Capensf160b172014-11-26 11:58:23 -05002583 return error(GL_INVALID_ENUM);
2584 }
John Bauman66b8ab22014-05-06 15:57:45 -04002585
Nicolas Capensf160b172014-11-26 11:58:23 -05002586 if(!buffer)
2587 {
2588 // A null buffer means that "0" is bound to the requested buffer target
2589 return error(GL_INVALID_OPERATION);
2590 }
John Bauman66b8ab22014-05-06 15:57:45 -04002591
Alexis Hetued306182015-04-02 12:02:28 -04002592 egl::GLint clientVersion = context->getClientVersion();
2593
Nicolas Capensf160b172014-11-26 11:58:23 -05002594 switch(pname)
2595 {
2596 case GL_BUFFER_USAGE:
2597 *params = buffer->usage();
2598 break;
2599 case GL_BUFFER_SIZE:
2600 *params = buffer->size();
2601 break;
Alexis Hetued306182015-04-02 12:02:28 -04002602 case GL_BUFFER_ACCESS_FLAGS:
2603 if(clientVersion >= 3)
2604 {
2605 *params = buffer->access();
2606 break;
2607 }
2608 else return error(GL_INVALID_ENUM);
2609 case GL_BUFFER_MAPPED:
2610 if(clientVersion >= 3)
2611 {
2612 *params = buffer->isMapped();
2613 break;
2614 }
2615 else return error(GL_INVALID_ENUM);
2616 case GL_BUFFER_MAP_LENGTH:
2617 if(clientVersion >= 3)
2618 {
2619 *params = buffer->length();
2620 break;
2621 }
2622 else return error(GL_INVALID_ENUM);
2623 case GL_BUFFER_MAP_OFFSET:
2624 if(clientVersion >= 3)
2625 {
2626 *params = buffer->offset();
2627 break;
2628 }
2629 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05002630 default:
2631 return error(GL_INVALID_ENUM);
2632 }
2633 }
John Bauman66b8ab22014-05-06 15:57:45 -04002634}
2635
2636GLenum GL_APIENTRY glGetError(void)
2637{
Nicolas Capensf160b172014-11-26 11:58:23 -05002638 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002639
Nicolas Capensf160b172014-11-26 11:58:23 -05002640 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002641
Nicolas Capensf160b172014-11-26 11:58:23 -05002642 if(context)
2643 {
2644 return context->getError();
2645 }
John Bauman66b8ab22014-05-06 15:57:45 -04002646
Nicolas Capensf160b172014-11-26 11:58:23 -05002647 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002648}
2649
2650void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2651{
Nicolas Capensf160b172014-11-26 11:58:23 -05002652 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002653
Nicolas Capensf160b172014-11-26 11:58:23 -05002654 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002655
Nicolas Capensf160b172014-11-26 11:58:23 -05002656 if(context)
2657 {
2658 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002659
Nicolas Capensf160b172014-11-26 11:58:23 -05002660 if(fenceObject == NULL)
2661 {
2662 return error(GL_INVALID_OPERATION);
2663 }
John Bauman66b8ab22014-05-06 15:57:45 -04002664
Nicolas Capensf160b172014-11-26 11:58:23 -05002665 fenceObject->getFenceiv(pname, params);
2666 }
John Bauman66b8ab22014-05-06 15:57:45 -04002667}
2668
2669void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
2670{
Nicolas Capensf160b172014-11-26 11:58:23 -05002671 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002672
Nicolas Capensf160b172014-11-26 11:58:23 -05002673 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002674
Nicolas Capensf160b172014-11-26 11:58:23 -05002675 if(context)
2676 {
2677 if(!(context->getFloatv(pname, params)))
2678 {
2679 GLenum nativeType;
2680 unsigned int numParams = 0;
2681 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2682 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002683
Nicolas Capensf160b172014-11-26 11:58:23 -05002684 if(numParams == 0)
2685 return; // it is known that the pname is valid, but that there are no parameters to return.
John Bauman66b8ab22014-05-06 15:57:45 -04002686
Nicolas Capensf160b172014-11-26 11:58:23 -05002687 if(nativeType == GL_BOOL)
2688 {
2689 GLboolean *boolParams = NULL;
2690 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002691
Nicolas Capensf160b172014-11-26 11:58:23 -05002692 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002693
Nicolas Capensf160b172014-11-26 11:58:23 -05002694 for(unsigned int i = 0; i < numParams; ++i)
2695 {
2696 if(boolParams[i] == GL_FALSE)
2697 params[i] = 0.0f;
2698 else
2699 params[i] = 1.0f;
2700 }
John Bauman66b8ab22014-05-06 15:57:45 -04002701
Nicolas Capensf160b172014-11-26 11:58:23 -05002702 delete [] boolParams;
2703 }
2704 else if(nativeType == GL_INT)
2705 {
2706 GLint *intParams = NULL;
2707 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002708
Nicolas Capensf160b172014-11-26 11:58:23 -05002709 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002710
Nicolas Capensf160b172014-11-26 11:58:23 -05002711 for(unsigned int i = 0; i < numParams; ++i)
2712 {
2713 params[i] = (GLfloat)intParams[i];
2714 }
John Bauman66b8ab22014-05-06 15:57:45 -04002715
Nicolas Capensf160b172014-11-26 11:58:23 -05002716 delete [] intParams;
2717 }
2718 }
2719 }
John Bauman66b8ab22014-05-06 15:57:45 -04002720}
2721
2722void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2723{
Nicolas Capensf160b172014-11-26 11:58:23 -05002724 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2725 target, attachment, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002726
Nicolas Capensf160b172014-11-26 11:58:23 -05002727 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002728
Nicolas Capensf160b172014-11-26 11:58:23 -05002729 if(context)
2730 {
2731 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2732 {
2733 return error(GL_INVALID_ENUM);
2734 }
John Bauman66b8ab22014-05-06 15:57:45 -04002735
Nicolas Capensf160b172014-11-26 11:58:23 -05002736 es2::Framebuffer *framebuffer = NULL;
2737 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2738 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002739 if(context->getReadFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002740 {
2741 return error(GL_INVALID_OPERATION);
2742 }
John Bauman66b8ab22014-05-06 15:57:45 -04002743
Nicolas Capensf160b172014-11-26 11:58:23 -05002744 framebuffer = context->getReadFramebuffer();
2745 }
2746 else
2747 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002748 if(context->getDrawFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002749 {
2750 return error(GL_INVALID_OPERATION);
2751 }
John Bauman66b8ab22014-05-06 15:57:45 -04002752
Nicolas Capensf160b172014-11-26 11:58:23 -05002753 framebuffer = context->getDrawFramebuffer();
2754 }
John Bauman66b8ab22014-05-06 15:57:45 -04002755
Nicolas Capensf160b172014-11-26 11:58:23 -05002756 GLenum attachmentType;
2757 GLuint attachmentHandle;
2758 switch(attachment)
2759 {
2760 case GL_COLOR_ATTACHMENT0:
2761 attachmentType = framebuffer->getColorbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002762 attachmentHandle = framebuffer->getColorbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002763 break;
2764 case GL_DEPTH_ATTACHMENT:
2765 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002766 attachmentHandle = framebuffer->getDepthbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002767 break;
2768 case GL_STENCIL_ATTACHMENT:
2769 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002770 attachmentHandle = framebuffer->getStencilbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002771 break;
2772 default:
2773 return error(GL_INVALID_ENUM);
2774 }
John Bauman66b8ab22014-05-06 15:57:45 -04002775
Nicolas Capensf160b172014-11-26 11:58:23 -05002776 GLenum attachmentObjectType; // Type category
2777 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2778 {
2779 attachmentObjectType = attachmentType;
2780 }
2781 else if(es2::IsTextureTarget(attachmentType))
2782 {
2783 attachmentObjectType = GL_TEXTURE;
2784 }
2785 else UNREACHABLE();
John Bauman66b8ab22014-05-06 15:57:45 -04002786
Nicolas Capensf160b172014-11-26 11:58:23 -05002787 switch(pname)
2788 {
2789 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2790 *params = attachmentObjectType;
2791 break;
2792 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2793 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2794 {
2795 *params = attachmentHandle;
2796 }
2797 else
2798 {
2799 return error(GL_INVALID_ENUM);
2800 }
2801 break;
2802 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2803 if(attachmentObjectType == GL_TEXTURE)
2804 {
2805 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2806 }
2807 else
2808 {
2809 return error(GL_INVALID_ENUM);
2810 }
2811 break;
2812 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2813 if(attachmentObjectType == GL_TEXTURE)
2814 {
2815 if(es2::IsCubemapTextureTarget(attachmentType))
2816 {
2817 *params = attachmentType;
2818 }
2819 else
2820 {
2821 *params = 0;
2822 }
2823 }
2824 else
2825 {
2826 return error(GL_INVALID_ENUM);
2827 }
2828 break;
2829 default:
2830 return error(GL_INVALID_ENUM);
2831 }
2832 }
John Bauman66b8ab22014-05-06 15:57:45 -04002833}
2834
2835GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
2836{
Nicolas Capensf160b172014-11-26 11:58:23 -05002837 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002838
Nicolas Capensf160b172014-11-26 11:58:23 -05002839 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002840}
2841
2842void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
2843{
Nicolas Capensf160b172014-11-26 11:58:23 -05002844 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002845
Nicolas Capensf160b172014-11-26 11:58:23 -05002846 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002847
Nicolas Capens7ae353d2015-03-13 17:59:58 -04002848 if(!context)
2849 {
Greg Hartman6074f122015-04-08 09:57:16 -07002850 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
2851 #ifdef __ANDROID__
2852 ALOGI("expected_badness glGetIntegerv() called without current context.");
2853 #else
2854 ERR("glGetIntegerv() called without current context.");
2855 #endif
Nicolas Capens7ae353d2015-03-13 17:59:58 -04002856
2857 // This is not spec compliant! When there is no current GL context, functions should
2858 // have no side effects. Google Maps queries these values before creating a context,
2859 // so we need this as a bug-compatible workaround.
2860 switch(pname)
2861 {
2862 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return;
2863 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return;
2864 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
2865 case GL_STENCIL_BITS: *params = 8; return;
2866 case GL_ALIASED_LINE_WIDTH_RANGE:
2867 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
2868 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
2869 return;
2870 }
2871 }
2872
Nicolas Capensf160b172014-11-26 11:58:23 -05002873 if(context)
2874 {
2875 if(!(context->getIntegerv(pname, params)))
2876 {
2877 GLenum nativeType;
2878 unsigned int numParams = 0;
2879 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2880 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002881
Nicolas Capensf160b172014-11-26 11:58:23 -05002882 if(numParams == 0)
2883 return; // it is known that pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04002884
Nicolas Capensf160b172014-11-26 11:58:23 -05002885 if(nativeType == GL_BOOL)
2886 {
2887 GLboolean *boolParams = NULL;
2888 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002889
Nicolas Capensf160b172014-11-26 11:58:23 -05002890 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002891
Nicolas Capensf160b172014-11-26 11:58:23 -05002892 for(unsigned int i = 0; i < numParams; ++i)
2893 {
Alexis Hetued306182015-04-02 12:02:28 -04002894 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
Nicolas Capensf160b172014-11-26 11:58:23 -05002895 }
John Bauman66b8ab22014-05-06 15:57:45 -04002896
Nicolas Capensf160b172014-11-26 11:58:23 -05002897 delete [] boolParams;
2898 }
2899 else if(nativeType == GL_FLOAT)
2900 {
2901 GLfloat *floatParams = NULL;
2902 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002903
Nicolas Capensf160b172014-11-26 11:58:23 -05002904 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002905
Nicolas Capensf160b172014-11-26 11:58:23 -05002906 for(unsigned int i = 0; i < numParams; ++i)
2907 {
2908 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
2909 {
Alexis Hetued306182015-04-02 12:02:28 -04002910 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) * 0.5f);
Nicolas Capensf160b172014-11-26 11:58:23 -05002911 }
2912 else
2913 {
2914 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2915 }
2916 }
John Bauman66b8ab22014-05-06 15:57:45 -04002917
Nicolas Capensf160b172014-11-26 11:58:23 -05002918 delete [] floatParams;
2919 }
2920 }
2921 }
John Bauman66b8ab22014-05-06 15:57:45 -04002922}
2923
2924void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2925{
Nicolas Capensf160b172014-11-26 11:58:23 -05002926 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", program, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002927
Nicolas Capensf160b172014-11-26 11:58:23 -05002928 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002929
Nicolas Capensf160b172014-11-26 11:58:23 -05002930 if(context)
2931 {
2932 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002933
Nicolas Capensf160b172014-11-26 11:58:23 -05002934 if(!programObject)
2935 {
2936 return error(GL_INVALID_VALUE);
2937 }
John Bauman66b8ab22014-05-06 15:57:45 -04002938
Nicolas Capensf160b172014-11-26 11:58:23 -05002939 switch(pname)
2940 {
2941 case GL_DELETE_STATUS:
2942 *params = programObject->isFlaggedForDeletion();
2943 return;
2944 case GL_LINK_STATUS:
2945 *params = programObject->isLinked();
2946 return;
2947 case GL_VALIDATE_STATUS:
2948 *params = programObject->isValidated();
2949 return;
2950 case GL_INFO_LOG_LENGTH:
2951 *params = programObject->getInfoLogLength();
2952 return;
2953 case GL_ATTACHED_SHADERS:
2954 *params = programObject->getAttachedShadersCount();
2955 return;
2956 case GL_ACTIVE_ATTRIBUTES:
2957 *params = programObject->getActiveAttributeCount();
2958 return;
2959 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2960 *params = programObject->getActiveAttributeMaxLength();
2961 return;
2962 case GL_ACTIVE_UNIFORMS:
2963 *params = programObject->getActiveUniformCount();
2964 return;
2965 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2966 *params = programObject->getActiveUniformMaxLength();
2967 return;
2968 default:
2969 return error(GL_INVALID_ENUM);
2970 }
2971 }
John Bauman66b8ab22014-05-06 15:57:45 -04002972}
2973
2974void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
2975{
Nicolas Capensf160b172014-11-26 11:58:23 -05002976 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
2977 program, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04002978
Nicolas Capensf160b172014-11-26 11:58:23 -05002979 if(bufsize < 0)
2980 {
2981 return error(GL_INVALID_VALUE);
2982 }
John Bauman66b8ab22014-05-06 15:57:45 -04002983
Nicolas Capensf160b172014-11-26 11:58:23 -05002984 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002985
Nicolas Capensf160b172014-11-26 11:58:23 -05002986 if(context)
2987 {
2988 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002989
Nicolas Capensf160b172014-11-26 11:58:23 -05002990 if(!programObject)
2991 {
2992 return error(GL_INVALID_VALUE);
2993 }
John Bauman66b8ab22014-05-06 15:57:45 -04002994
Nicolas Capensf160b172014-11-26 11:58:23 -05002995 programObject->getInfoLog(bufsize, length, infolog);
2996 }
John Bauman66b8ab22014-05-06 15:57:45 -04002997}
2998
2999void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3000{
Nicolas Capensf160b172014-11-26 11:58:23 -05003001 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003002
Nicolas Capensf160b172014-11-26 11:58:23 -05003003 switch(pname)
3004 {
3005 case GL_CURRENT_QUERY_EXT:
3006 break;
3007 default:
3008 return error(GL_INVALID_ENUM);
3009 }
John Bauman66b8ab22014-05-06 15:57:45 -04003010
Nicolas Capensf160b172014-11-26 11:58:23 -05003011 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003012
Nicolas Capensf160b172014-11-26 11:58:23 -05003013 if(context)
3014 {
3015 params[0] = context->getActiveQuery(target);
3016 }
John Bauman66b8ab22014-05-06 15:57:45 -04003017}
3018
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003019void GL_APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04003020{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003021 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", name, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003022
Nicolas Capensf160b172014-11-26 11:58:23 -05003023 switch(pname)
3024 {
3025 case GL_QUERY_RESULT_EXT:
3026 case GL_QUERY_RESULT_AVAILABLE_EXT:
3027 break;
3028 default:
3029 return error(GL_INVALID_ENUM);
3030 }
John Bauman66b8ab22014-05-06 15:57:45 -04003031
Nicolas Capensf160b172014-11-26 11:58:23 -05003032 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003033
Nicolas Capensf160b172014-11-26 11:58:23 -05003034 if(context)
3035 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003036 es2::Query *queryObject = context->getQuery(name, false, GL_NONE);
John Bauman66b8ab22014-05-06 15:57:45 -04003037
Nicolas Capensf160b172014-11-26 11:58:23 -05003038 if(!queryObject)
3039 {
3040 return error(GL_INVALID_OPERATION);
3041 }
John Bauman66b8ab22014-05-06 15:57:45 -04003042
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003043 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capensf160b172014-11-26 11:58:23 -05003044 {
3045 return error(GL_INVALID_OPERATION);
3046 }
John Bauman66b8ab22014-05-06 15:57:45 -04003047
Nicolas Capensf160b172014-11-26 11:58:23 -05003048 switch(pname)
3049 {
3050 case GL_QUERY_RESULT_EXT:
3051 params[0] = queryObject->getResult();
3052 break;
3053 case GL_QUERY_RESULT_AVAILABLE_EXT:
3054 params[0] = queryObject->isResultAvailable();
3055 break;
3056 default:
3057 ASSERT(false);
3058 }
3059 }
John Bauman66b8ab22014-05-06 15:57:45 -04003060}
3061
3062void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3063{
Nicolas Capensf160b172014-11-26 11:58:23 -05003064 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003065
Nicolas Capensf160b172014-11-26 11:58:23 -05003066 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003067
Nicolas Capensf160b172014-11-26 11:58:23 -05003068 if(context)
3069 {
3070 if(target != GL_RENDERBUFFER)
3071 {
3072 return error(GL_INVALID_ENUM);
3073 }
John Bauman66b8ab22014-05-06 15:57:45 -04003074
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003075 if(context->getRenderbufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05003076 {
3077 return error(GL_INVALID_OPERATION);
3078 }
John Bauman66b8ab22014-05-06 15:57:45 -04003079
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003080 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
John Bauman66b8ab22014-05-06 15:57:45 -04003081
Nicolas Capensf160b172014-11-26 11:58:23 -05003082 switch(pname)
3083 {
3084 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3085 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3086 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
3087 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3088 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3089 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3090 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3091 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3092 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
3093 case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break;
3094 default:
3095 return error(GL_INVALID_ENUM);
3096 }
3097 }
John Bauman66b8ab22014-05-06 15:57:45 -04003098}
3099
3100void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3101{
Nicolas Capensf160b172014-11-26 11:58:23 -05003102 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003103
Nicolas Capensf160b172014-11-26 11:58:23 -05003104 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003105
Nicolas Capensf160b172014-11-26 11:58:23 -05003106 if(context)
3107 {
3108 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003109
Nicolas Capensf160b172014-11-26 11:58:23 -05003110 if(!shaderObject)
3111 {
3112 return error(GL_INVALID_VALUE);
3113 }
John Bauman66b8ab22014-05-06 15:57:45 -04003114
Nicolas Capensf160b172014-11-26 11:58:23 -05003115 switch(pname)
3116 {
3117 case GL_SHADER_TYPE:
3118 *params = shaderObject->getType();
3119 return;
3120 case GL_DELETE_STATUS:
3121 *params = shaderObject->isFlaggedForDeletion();
3122 return;
3123 case GL_COMPILE_STATUS:
3124 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3125 return;
3126 case GL_INFO_LOG_LENGTH:
3127 *params = shaderObject->getInfoLogLength();
3128 return;
3129 case GL_SHADER_SOURCE_LENGTH:
3130 *params = shaderObject->getSourceLength();
3131 return;
3132 default:
3133 return error(GL_INVALID_ENUM);
3134 }
3135 }
John Bauman66b8ab22014-05-06 15:57:45 -04003136}
3137
3138void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3139{
Nicolas Capensf160b172014-11-26 11:58:23 -05003140 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
3141 shader, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04003142
Nicolas Capensf160b172014-11-26 11:58:23 -05003143 if(bufsize < 0)
3144 {
3145 return error(GL_INVALID_VALUE);
3146 }
John Bauman66b8ab22014-05-06 15:57:45 -04003147
Nicolas Capensf160b172014-11-26 11:58:23 -05003148 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003149
Nicolas Capensf160b172014-11-26 11:58:23 -05003150 if(context)
3151 {
3152 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003153
Nicolas Capensf160b172014-11-26 11:58:23 -05003154 if(!shaderObject)
3155 {
3156 return error(GL_INVALID_VALUE);
3157 }
John Bauman66b8ab22014-05-06 15:57:45 -04003158
Nicolas Capensf160b172014-11-26 11:58:23 -05003159 shaderObject->getInfoLog(bufsize, length, infolog);
3160 }
John Bauman66b8ab22014-05-06 15:57:45 -04003161}
3162
3163void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3164{
Nicolas Capensf160b172014-11-26 11:58:23 -05003165 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3166 shadertype, precisiontype, range, precision);
John Bauman66b8ab22014-05-06 15:57:45 -04003167
Nicolas Capensf160b172014-11-26 11:58:23 -05003168 switch(shadertype)
3169 {
3170 case GL_VERTEX_SHADER:
3171 case GL_FRAGMENT_SHADER:
3172 break;
3173 default:
3174 return error(GL_INVALID_ENUM);
3175 }
John Bauman66b8ab22014-05-06 15:57:45 -04003176
Nicolas Capensf160b172014-11-26 11:58:23 -05003177 switch(precisiontype)
3178 {
3179 case GL_LOW_FLOAT:
3180 case GL_MEDIUM_FLOAT:
3181 case GL_HIGH_FLOAT:
3182 // IEEE 754 single-precision
3183 range[0] = 127;
3184 range[1] = 127;
3185 *precision = 23;
3186 break;
3187 case GL_LOW_INT:
3188 case GL_MEDIUM_INT:
3189 case GL_HIGH_INT:
3190 // Single-precision floating-point numbers can accurately represent integers up to +/-16777216
3191 range[0] = 24;
3192 range[1] = 24;
3193 *precision = 0;
3194 break;
3195 default:
3196 return error(GL_INVALID_ENUM);
3197 }
John Bauman66b8ab22014-05-06 15:57:45 -04003198}
3199
3200void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3201{
Nicolas Capensf160b172014-11-26 11:58:23 -05003202 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3203 shader, bufsize, length, source);
John Bauman66b8ab22014-05-06 15:57:45 -04003204
Nicolas Capensf160b172014-11-26 11:58:23 -05003205 if(bufsize < 0)
3206 {
3207 return error(GL_INVALID_VALUE);
3208 }
John Bauman66b8ab22014-05-06 15:57:45 -04003209
Nicolas Capensf160b172014-11-26 11:58:23 -05003210 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003211
Nicolas Capensf160b172014-11-26 11:58:23 -05003212 if(context)
3213 {
3214 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003215
Nicolas Capensf160b172014-11-26 11:58:23 -05003216 if(!shaderObject)
3217 {
3218 return error(GL_INVALID_OPERATION);
3219 }
John Bauman66b8ab22014-05-06 15:57:45 -04003220
Nicolas Capensf160b172014-11-26 11:58:23 -05003221 shaderObject->getSource(bufsize, length, source);
3222 }
John Bauman66b8ab22014-05-06 15:57:45 -04003223}
3224
3225const GLubyte* GL_APIENTRY glGetString(GLenum name)
3226{
Nicolas Capensf160b172014-11-26 11:58:23 -05003227 TRACE("(GLenum name = 0x%X)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04003228
Nicolas Capensf160b172014-11-26 11:58:23 -05003229 switch(name)
3230 {
3231 case GL_VENDOR:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003232 return (GLubyte*)"Google Inc.";
Nicolas Capensf160b172014-11-26 11:58:23 -05003233 case GL_RENDERER:
3234 return (GLubyte*)"SwiftShader";
3235 case GL_VERSION:
3236 return (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3237 case GL_SHADING_LANGUAGE_VERSION:
3238 return (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3239 case GL_EXTENSIONS:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003240 {
3241 es2::Context *context = es2::getContext();
3242 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)NULL;
3243 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003244 default:
3245 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3246 }
John Bauman66b8ab22014-05-06 15:57:45 -04003247}
3248
3249void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3250{
Nicolas Capensf160b172014-11-26 11:58:23 -05003251 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003252
Nicolas Capensf160b172014-11-26 11:58:23 -05003253 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003254
Nicolas Capensf160b172014-11-26 11:58:23 -05003255 if(context)
3256 {
3257 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003258
Alexis Hetued306182015-04-02 12:02:28 -04003259 egl::GLint clientVersion = context->getClientVersion();
3260
Nicolas Capensf160b172014-11-26 11:58:23 -05003261 switch(target)
3262 {
3263 case GL_TEXTURE_2D:
3264 texture = context->getTexture2D();
3265 break;
3266 case GL_TEXTURE_CUBE_MAP:
3267 texture = context->getTextureCubeMap();
3268 break;
3269 case GL_TEXTURE_EXTERNAL_OES:
3270 texture = context->getTextureExternal();
3271 break;
Alexis Hetued306182015-04-02 12:02:28 -04003272 case GL_TEXTURE_2D_ARRAY:
3273 if(clientVersion < 3)
3274 {
3275 return error(GL_INVALID_ENUM);
3276 }
3277 else
3278 {
3279 UNIMPLEMENTED();
3280 texture = context->getTexture3D();
3281 break;
3282 }
3283 case GL_TEXTURE_3D_OES:
3284 texture = context->getTexture3D();
3285 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003286 default:
3287 return error(GL_INVALID_ENUM);
3288 }
John Bauman66b8ab22014-05-06 15:57:45 -04003289
Nicolas Capensf160b172014-11-26 11:58:23 -05003290 switch(pname)
3291 {
3292 case GL_TEXTURE_MAG_FILTER:
3293 *params = (GLfloat)texture->getMagFilter();
3294 break;
3295 case GL_TEXTURE_MIN_FILTER:
3296 *params = (GLfloat)texture->getMinFilter();
3297 break;
3298 case GL_TEXTURE_WRAP_S:
3299 *params = (GLfloat)texture->getWrapS();
3300 break;
3301 case GL_TEXTURE_WRAP_T:
3302 *params = (GLfloat)texture->getWrapT();
3303 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003304 case GL_TEXTURE_WRAP_R_OES:
3305 *params = (GLfloat)texture->getWrapR();
3306 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003307 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3308 *params = texture->getMaxAnisotropy();
3309 break;
3310 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3311 *params = (GLfloat)1;
3312 break;
Alexis Hetued306182015-04-02 12:02:28 -04003313 case GL_TEXTURE_BASE_LEVEL:
3314 if(clientVersion >= 3)
3315 {
3316 *params = (GLfloat)texture->getBaseLevel();
3317 break;
3318 }
3319 else return error(GL_INVALID_ENUM);
3320 case GL_TEXTURE_COMPARE_FUNC:
3321 if(clientVersion >= 3)
3322 {
3323 *params = (GLfloat)texture->getCompareFunc();
3324 break;
3325 }
3326 else return error(GL_INVALID_ENUM);
3327 case GL_TEXTURE_COMPARE_MODE:
3328 if(clientVersion >= 3)
3329 {
3330 *params = (GLfloat)texture->getCompareMode();
3331 break;
3332 }
3333 else return error(GL_INVALID_ENUM);
3334 case GL_TEXTURE_IMMUTABLE_FORMAT:
3335 if(clientVersion >= 3)
3336 {
3337 *params = (GLfloat)texture->getImmutableFormat();
3338 break;
3339 }
3340 else return error(GL_INVALID_ENUM);
3341 case GL_TEXTURE_MAX_LEVEL:
3342 if(clientVersion >= 3)
3343 {
3344 *params = (GLfloat)texture->getMaxLevel();
3345 break;
3346 }
3347 else return error(GL_INVALID_ENUM);
3348 case GL_TEXTURE_MAX_LOD:
3349 if(clientVersion >= 3)
3350 {
3351 *params = texture->getMaxLOD();
3352 break;
3353 }
3354 else return error(GL_INVALID_ENUM);
3355 case GL_TEXTURE_MIN_LOD:
3356 if(clientVersion >= 3)
3357 {
3358 *params = texture->getMinLOD();
3359 break;
3360 }
3361 else return error(GL_INVALID_ENUM);
3362 case GL_TEXTURE_SWIZZLE_R:
3363 if(clientVersion >= 3)
3364 {
3365 *params = (GLfloat)texture->getSwizzleR();
3366 break;
3367 }
3368 else return error(GL_INVALID_ENUM);
3369 case GL_TEXTURE_SWIZZLE_G:
3370 if(clientVersion >= 3)
3371 {
3372 *params = (GLfloat)texture->getSwizzleG();
3373 break;
3374 }
3375 else return error(GL_INVALID_ENUM);
3376 case GL_TEXTURE_SWIZZLE_B:
3377 if(clientVersion >= 3)
3378 {
3379 *params = (GLfloat)texture->getSwizzleB();
3380 break;
3381 }
3382 else return error(GL_INVALID_ENUM);
3383 case GL_TEXTURE_SWIZZLE_A:
3384 if(clientVersion >= 3)
3385 {
3386 *params = (GLfloat)texture->getSwizzleA();
3387 break;
3388 }
3389 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003390 default:
3391 return error(GL_INVALID_ENUM);
3392 }
3393 }
John Bauman66b8ab22014-05-06 15:57:45 -04003394}
3395
3396void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3397{
Nicolas Capensf160b172014-11-26 11:58:23 -05003398 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003399
Nicolas Capensf160b172014-11-26 11:58:23 -05003400 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003401
Nicolas Capensf160b172014-11-26 11:58:23 -05003402 if(context)
3403 {
3404 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003405
Alexis Hetued306182015-04-02 12:02:28 -04003406 egl::GLint clientVersion = context->getClientVersion();
3407
Nicolas Capensf160b172014-11-26 11:58:23 -05003408 switch(target)
3409 {
3410 case GL_TEXTURE_2D:
3411 texture = context->getTexture2D();
3412 break;
3413 case GL_TEXTURE_CUBE_MAP:
3414 texture = context->getTextureCubeMap();
3415 break;
3416 case GL_TEXTURE_EXTERNAL_OES:
3417 texture = context->getTextureExternal();
3418 break;
Alexis Hetued306182015-04-02 12:02:28 -04003419 case GL_TEXTURE_2D_ARRAY:
3420 if(clientVersion < 3)
3421 {
3422 return error(GL_INVALID_ENUM);
3423 }
3424 else
3425 {
3426 UNIMPLEMENTED();
3427 texture = context->getTexture3D();
3428 break;
3429 }
3430 case GL_TEXTURE_3D_OES:
3431 texture = context->getTexture3D();
3432 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003433 default:
3434 return error(GL_INVALID_ENUM);
3435 }
John Bauman66b8ab22014-05-06 15:57:45 -04003436
Nicolas Capensf160b172014-11-26 11:58:23 -05003437 switch(pname)
3438 {
3439 case GL_TEXTURE_MAG_FILTER:
3440 *params = texture->getMagFilter();
3441 break;
3442 case GL_TEXTURE_MIN_FILTER:
3443 *params = texture->getMinFilter();
3444 break;
3445 case GL_TEXTURE_WRAP_S:
3446 *params = texture->getWrapS();
3447 break;
3448 case GL_TEXTURE_WRAP_T:
3449 *params = texture->getWrapT();
3450 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003451 case GL_TEXTURE_WRAP_R_OES:
3452 *params = texture->getWrapR();
3453 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003454 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3455 *params = (GLint)texture->getMaxAnisotropy();
3456 break;
3457 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3458 *params = 1;
3459 break;
Alexis Hetued306182015-04-02 12:02:28 -04003460 case GL_TEXTURE_BASE_LEVEL:
3461 if(clientVersion >= 3)
3462 {
3463 *params = texture->getBaseLevel();
3464 break;
3465 }
3466 else return error(GL_INVALID_ENUM);
3467 case GL_TEXTURE_COMPARE_FUNC:
3468 if(clientVersion >= 3)
3469 {
3470 *params = (GLint)texture->getCompareFunc();
3471 break;
3472 }
3473 else return error(GL_INVALID_ENUM);
3474 case GL_TEXTURE_COMPARE_MODE:
3475 if(clientVersion >= 3)
3476 {
3477 *params = (GLint)texture->getCompareMode();
3478 break;
3479 }
3480 else return error(GL_INVALID_ENUM);
3481 case GL_TEXTURE_IMMUTABLE_FORMAT:
3482 if(clientVersion >= 3)
3483 {
3484 *params = (GLint)texture->getImmutableFormat();
3485 break;
3486 }
3487 else return error(GL_INVALID_ENUM);
3488 case GL_TEXTURE_MAX_LEVEL:
3489 if(clientVersion >= 3)
3490 {
3491 *params = texture->getMaxLevel();
3492 break;
3493 }
3494 else return error(GL_INVALID_ENUM);
3495 case GL_TEXTURE_MAX_LOD:
3496 if(clientVersion >= 3)
3497 {
3498 *params = (GLint)texture->getMaxLOD();
3499 break;
3500 }
3501 else return error(GL_INVALID_ENUM);
3502 case GL_TEXTURE_MIN_LOD:
3503 if(clientVersion >= 3)
3504 {
3505 *params = (GLint)texture->getMinLOD();
3506 break;
3507 }
3508 else return error(GL_INVALID_ENUM);
3509 case GL_TEXTURE_SWIZZLE_R:
3510 if(clientVersion >= 3)
3511 {
3512 *params = (GLint)texture->getSwizzleR();
3513 break;
3514 }
3515 else return error(GL_INVALID_ENUM);
3516 case GL_TEXTURE_SWIZZLE_G:
3517 if(clientVersion >= 3)
3518 {
3519 *params = (GLint)texture->getSwizzleG();
3520 break;
3521 }
3522 else return error(GL_INVALID_ENUM);
3523 case GL_TEXTURE_SWIZZLE_B:
3524 if(clientVersion >= 3)
3525 {
3526 *params = (GLint)texture->getSwizzleB();
3527 break;
3528 }
3529 else return error(GL_INVALID_ENUM);
3530 case GL_TEXTURE_SWIZZLE_A:
3531 if(clientVersion >= 3)
3532 {
3533 *params = (GLint)texture->getSwizzleA();
3534 break;
3535 }
3536 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003537 default:
3538 return error(GL_INVALID_ENUM);
3539 }
3540 }
John Bauman66b8ab22014-05-06 15:57:45 -04003541}
3542
3543void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3544{
Nicolas Capensf160b172014-11-26 11:58:23 -05003545 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3546 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003547
Nicolas Capensf160b172014-11-26 11:58:23 -05003548 if(bufSize < 0)
3549 {
3550 return error(GL_INVALID_VALUE);
3551 }
John Bauman66b8ab22014-05-06 15:57:45 -04003552
Nicolas Capensf160b172014-11-26 11:58:23 -05003553 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003554
Nicolas Capensf160b172014-11-26 11:58:23 -05003555 if(context)
3556 {
3557 if(program == 0)
3558 {
3559 return error(GL_INVALID_VALUE);
3560 }
John Bauman66b8ab22014-05-06 15:57:45 -04003561
Nicolas Capensf160b172014-11-26 11:58:23 -05003562 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003563
Nicolas Capensf160b172014-11-26 11:58:23 -05003564 if(!programObject || !programObject->isLinked())
3565 {
3566 return error(GL_INVALID_OPERATION);
3567 }
John Bauman66b8ab22014-05-06 15:57:45 -04003568
Nicolas Capensf160b172014-11-26 11:58:23 -05003569 if(!programObject->getUniformfv(location, &bufSize, params))
3570 {
3571 return error(GL_INVALID_OPERATION);
3572 }
3573 }
John Bauman66b8ab22014-05-06 15:57:45 -04003574}
3575
3576void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3577{
Nicolas Capensf160b172014-11-26 11:58:23 -05003578 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003579
Nicolas Capensf160b172014-11-26 11:58:23 -05003580 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003581
Nicolas Capensf160b172014-11-26 11:58:23 -05003582 if(context)
3583 {
3584 if(program == 0)
3585 {
3586 return error(GL_INVALID_VALUE);
3587 }
John Bauman66b8ab22014-05-06 15:57:45 -04003588
Nicolas Capensf160b172014-11-26 11:58:23 -05003589 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003590
Nicolas Capensf160b172014-11-26 11:58:23 -05003591 if(!programObject || !programObject->isLinked())
3592 {
3593 return error(GL_INVALID_OPERATION);
3594 }
John Bauman66b8ab22014-05-06 15:57:45 -04003595
Nicolas Capensf160b172014-11-26 11:58:23 -05003596 if(!programObject->getUniformfv(location, NULL, params))
3597 {
3598 return error(GL_INVALID_OPERATION);
3599 }
3600 }
John Bauman66b8ab22014-05-06 15:57:45 -04003601}
3602
3603void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3604{
Nicolas Capensf160b172014-11-26 11:58:23 -05003605 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3606 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003607
Nicolas Capensf160b172014-11-26 11:58:23 -05003608 if(bufSize < 0)
3609 {
3610 return error(GL_INVALID_VALUE);
3611 }
John Bauman66b8ab22014-05-06 15:57:45 -04003612
Nicolas Capensf160b172014-11-26 11:58:23 -05003613 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003614
Nicolas Capensf160b172014-11-26 11:58:23 -05003615 if(context)
3616 {
3617 if(program == 0)
3618 {
3619 return error(GL_INVALID_VALUE);
3620 }
John Bauman66b8ab22014-05-06 15:57:45 -04003621
Nicolas Capensf160b172014-11-26 11:58:23 -05003622 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003623
Nicolas Capensf160b172014-11-26 11:58:23 -05003624 if(!programObject || !programObject->isLinked())
3625 {
3626 return error(GL_INVALID_OPERATION);
3627 }
John Bauman66b8ab22014-05-06 15:57:45 -04003628
Nicolas Capensf160b172014-11-26 11:58:23 -05003629 if(!programObject)
3630 {
3631 return error(GL_INVALID_OPERATION);
3632 }
John Bauman66b8ab22014-05-06 15:57:45 -04003633
Nicolas Capensf160b172014-11-26 11:58:23 -05003634 if(!programObject->getUniformiv(location, &bufSize, params))
3635 {
3636 return error(GL_INVALID_OPERATION);
3637 }
3638 }
John Bauman66b8ab22014-05-06 15:57:45 -04003639}
3640
3641void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
3642{
Nicolas Capensf160b172014-11-26 11:58:23 -05003643 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003644
Nicolas Capensf160b172014-11-26 11:58:23 -05003645 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003646
Nicolas Capensf160b172014-11-26 11:58:23 -05003647 if(context)
3648 {
3649 if(program == 0)
3650 {
3651 return error(GL_INVALID_VALUE);
3652 }
John Bauman66b8ab22014-05-06 15:57:45 -04003653
Nicolas Capensf160b172014-11-26 11:58:23 -05003654 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003655
Nicolas Capensf160b172014-11-26 11:58:23 -05003656 if(!programObject || !programObject->isLinked())
3657 {
3658 return error(GL_INVALID_OPERATION);
3659 }
John Bauman66b8ab22014-05-06 15:57:45 -04003660
Nicolas Capensf160b172014-11-26 11:58:23 -05003661 if(!programObject)
3662 {
3663 return error(GL_INVALID_OPERATION);
3664 }
John Bauman66b8ab22014-05-06 15:57:45 -04003665
Nicolas Capensf160b172014-11-26 11:58:23 -05003666 if(!programObject->getUniformiv(location, NULL, params))
3667 {
3668 return error(GL_INVALID_OPERATION);
3669 }
3670 }
John Bauman66b8ab22014-05-06 15:57:45 -04003671}
3672
3673int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
3674{
Nicolas Capensf160b172014-11-26 11:58:23 -05003675 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04003676
Nicolas Capensf160b172014-11-26 11:58:23 -05003677 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003678
Nicolas Capensf160b172014-11-26 11:58:23 -05003679 if(strstr(name, "gl_") == name)
3680 {
3681 return -1;
3682 }
John Bauman66b8ab22014-05-06 15:57:45 -04003683
Nicolas Capensf160b172014-11-26 11:58:23 -05003684 if(context)
3685 {
3686 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003687
Nicolas Capensf160b172014-11-26 11:58:23 -05003688 if(!programObject)
3689 {
3690 if(context->getShader(program))
3691 {
3692 return error(GL_INVALID_OPERATION, -1);
3693 }
3694 else
3695 {
3696 return error(GL_INVALID_VALUE, -1);
3697 }
3698 }
John Bauman66b8ab22014-05-06 15:57:45 -04003699
Nicolas Capensf160b172014-11-26 11:58:23 -05003700 if(!programObject->isLinked())
3701 {
3702 return error(GL_INVALID_OPERATION, -1);
3703 }
John Bauman66b8ab22014-05-06 15:57:45 -04003704
Nicolas Capensf160b172014-11-26 11:58:23 -05003705 return programObject->getUniformLocation(name);
3706 }
John Bauman66b8ab22014-05-06 15:57:45 -04003707
Nicolas Capensf160b172014-11-26 11:58:23 -05003708 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04003709}
3710
3711void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3712{
Nicolas Capensf160b172014-11-26 11:58:23 -05003713 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003714
Nicolas Capensf160b172014-11-26 11:58:23 -05003715 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003716
Nicolas Capensf160b172014-11-26 11:58:23 -05003717 if(context)
3718 {
3719 if(index >= es2::MAX_VERTEX_ATTRIBS)
3720 {
3721 return error(GL_INVALID_VALUE);
3722 }
John Bauman66b8ab22014-05-06 15:57:45 -04003723
Nicolas Capensf160b172014-11-26 11:58:23 -05003724 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
Alexis Hetued306182015-04-02 12:02:28 -04003725
3726 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04003727
Nicolas Capensf160b172014-11-26 11:58:23 -05003728 switch(pname)
3729 {
3730 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3731 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3732 break;
3733 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3734 *params = (GLfloat)attribState.mSize;
3735 break;
3736 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3737 *params = (GLfloat)attribState.mStride;
3738 break;
3739 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3740 *params = (GLfloat)attribState.mType;
3741 break;
3742 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3743 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3744 break;
3745 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003746 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003747 break;
3748 case GL_CURRENT_VERTEX_ATTRIB:
3749 for(int i = 0; i < 4; ++i)
3750 {
Alexis Hetu93ae1032015-04-10 14:31:01 -04003751 params[i] = attribState.getCurrentValue(i);
Nicolas Capensf160b172014-11-26 11:58:23 -05003752 }
3753 break;
Alexis Hetued306182015-04-02 12:02:28 -04003754 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3755 if(clientVersion >= 3)
3756 {
3757 switch(attribState.mType)
3758 {
3759 case GL_BYTE:
3760 case GL_UNSIGNED_BYTE:
3761 case GL_SHORT:
3762 case GL_UNSIGNED_SHORT:
3763 case GL_INT:
3764 case GL_INT_2_10_10_10_REV:
3765 case GL_UNSIGNED_INT:
3766 case GL_FIXED:
3767 *params = (GLfloat)GL_TRUE;
3768 break;
3769 default:
3770 *params = (GLfloat)GL_FALSE;
3771 break;
3772 }
3773 break;
3774 }
3775 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003776 default: return error(GL_INVALID_ENUM);
3777 }
3778 }
John Bauman66b8ab22014-05-06 15:57:45 -04003779}
3780
3781void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3782{
Nicolas Capensf160b172014-11-26 11:58:23 -05003783 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003784
Nicolas Capensf160b172014-11-26 11:58:23 -05003785 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003786
Nicolas Capensf160b172014-11-26 11:58:23 -05003787 if(context)
3788 {
3789 if(index >= es2::MAX_VERTEX_ATTRIBS)
3790 {
3791 return error(GL_INVALID_VALUE);
3792 }
John Bauman66b8ab22014-05-06 15:57:45 -04003793
Nicolas Capensf160b172014-11-26 11:58:23 -05003794 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
John Bauman66b8ab22014-05-06 15:57:45 -04003795
Alexis Hetued306182015-04-02 12:02:28 -04003796 egl::GLint clientVersion = context->getClientVersion();
3797
Nicolas Capensf160b172014-11-26 11:58:23 -05003798 switch(pname)
3799 {
3800 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3801 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3802 break;
3803 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3804 *params = attribState.mSize;
3805 break;
3806 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3807 *params = attribState.mStride;
3808 break;
3809 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3810 *params = attribState.mType;
3811 break;
3812 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3813 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3814 break;
3815 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003816 *params = attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003817 break;
3818 case GL_CURRENT_VERTEX_ATTRIB:
3819 for(int i = 0; i < 4; ++i)
3820 {
Alexis Hetu93ae1032015-04-10 14:31:01 -04003821 float currentValue = attribState.getCurrentValue(i);
Nicolas Capensf160b172014-11-26 11:58:23 -05003822 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3823 }
3824 break;
Alexis Hetued306182015-04-02 12:02:28 -04003825 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3826 if(clientVersion >= 3)
3827 {
3828 switch(attribState.mType)
3829 {
3830 case GL_BYTE:
3831 case GL_UNSIGNED_BYTE:
3832 case GL_SHORT:
3833 case GL_UNSIGNED_SHORT:
3834 case GL_INT:
3835 case GL_INT_2_10_10_10_REV:
3836 case GL_UNSIGNED_INT:
3837 case GL_FIXED:
3838 *params = GL_TRUE;
3839 break;
3840 default:
3841 *params = GL_FALSE;
3842 break;
3843 }
3844 break;
3845 }
3846 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003847 default: return error(GL_INVALID_ENUM);
3848 }
3849 }
John Bauman66b8ab22014-05-06 15:57:45 -04003850}
3851
3852void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
3853{
Nicolas Capensf160b172014-11-26 11:58:23 -05003854 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
John Bauman66b8ab22014-05-06 15:57:45 -04003855
Nicolas Capensf160b172014-11-26 11:58:23 -05003856 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003857
Nicolas Capensf160b172014-11-26 11:58:23 -05003858 if(context)
3859 {
3860 if(index >= es2::MAX_VERTEX_ATTRIBS)
3861 {
3862 return error(GL_INVALID_VALUE);
3863 }
John Bauman66b8ab22014-05-06 15:57:45 -04003864
Nicolas Capensf160b172014-11-26 11:58:23 -05003865 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3866 {
3867 return error(GL_INVALID_ENUM);
3868 }
John Bauman66b8ab22014-05-06 15:57:45 -04003869
Nicolas Capensf160b172014-11-26 11:58:23 -05003870 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3871 }
John Bauman66b8ab22014-05-06 15:57:45 -04003872}
3873
3874void GL_APIENTRY glHint(GLenum target, GLenum mode)
3875{
Nicolas Capensf160b172014-11-26 11:58:23 -05003876 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
John Bauman66b8ab22014-05-06 15:57:45 -04003877
Nicolas Capensf160b172014-11-26 11:58:23 -05003878 switch(mode)
3879 {
3880 case GL_FASTEST:
3881 case GL_NICEST:
3882 case GL_DONT_CARE:
3883 break;
3884 default:
3885 return error(GL_INVALID_ENUM);
3886 }
John Bauman66b8ab22014-05-06 15:57:45 -04003887
Nicolas Capensf160b172014-11-26 11:58:23 -05003888 es2::Context *context = es2::getContext();
3889 switch(target)
3890 {
3891 case GL_GENERATE_MIPMAP_HINT:
3892 if(context) context->setGenerateMipmapHint(mode);
3893 break;
3894 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3895 if(context) context->setFragmentShaderDerivativeHint(mode);
3896 break;
3897 default:
3898 return error(GL_INVALID_ENUM);
3899 }
John Bauman66b8ab22014-05-06 15:57:45 -04003900}
3901
3902GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
3903{
Nicolas Capensf160b172014-11-26 11:58:23 -05003904 TRACE("(GLuint buffer = %d)", buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003905
Nicolas Capensf160b172014-11-26 11:58:23 -05003906 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003907
Nicolas Capensf160b172014-11-26 11:58:23 -05003908 if(context && buffer)
3909 {
3910 es2::Buffer *bufferObject = context->getBuffer(buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003911
Nicolas Capensf160b172014-11-26 11:58:23 -05003912 if(bufferObject)
3913 {
3914 return GL_TRUE;
3915 }
3916 }
John Bauman66b8ab22014-05-06 15:57:45 -04003917
Nicolas Capensf160b172014-11-26 11:58:23 -05003918 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003919}
3920
3921GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
3922{
Nicolas Capensf160b172014-11-26 11:58:23 -05003923 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04003924
Nicolas Capensf160b172014-11-26 11:58:23 -05003925 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003926
Nicolas Capensf160b172014-11-26 11:58:23 -05003927 if(context)
3928 {
3929 switch(cap)
3930 {
3931 case GL_CULL_FACE: return context->isCullFaceEnabled();
3932 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3933 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3934 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3935 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3936 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3937 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3938 case GL_BLEND: return context->isBlendEnabled();
3939 case GL_DITHER: return context->isDitherEnabled();
3940 default:
3941 return error(GL_INVALID_ENUM, false);
3942 }
3943 }
John Bauman66b8ab22014-05-06 15:57:45 -04003944
Nicolas Capensf160b172014-11-26 11:58:23 -05003945 return false;
John Bauman66b8ab22014-05-06 15:57:45 -04003946}
3947
3948GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
3949{
Nicolas Capensf160b172014-11-26 11:58:23 -05003950 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04003951
Nicolas Capensf160b172014-11-26 11:58:23 -05003952 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003953
Nicolas Capensf160b172014-11-26 11:58:23 -05003954 if(context)
3955 {
3956 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04003957
Nicolas Capensf160b172014-11-26 11:58:23 -05003958 if(fenceObject == NULL)
3959 {
3960 return GL_FALSE;
3961 }
John Bauman66b8ab22014-05-06 15:57:45 -04003962
Nicolas Capensf160b172014-11-26 11:58:23 -05003963 return fenceObject->isFence();
3964 }
John Bauman66b8ab22014-05-06 15:57:45 -04003965
Nicolas Capensf160b172014-11-26 11:58:23 -05003966 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003967}
3968
3969GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
3970{
Nicolas Capensf160b172014-11-26 11:58:23 -05003971 TRACE("(GLuint framebuffer = %d)", framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003972
Nicolas Capensf160b172014-11-26 11:58:23 -05003973 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003974
Nicolas Capensf160b172014-11-26 11:58:23 -05003975 if(context && framebuffer)
3976 {
3977 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003978
Nicolas Capensf160b172014-11-26 11:58:23 -05003979 if(framebufferObject)
3980 {
3981 return GL_TRUE;
3982 }
3983 }
John Bauman66b8ab22014-05-06 15:57:45 -04003984
Nicolas Capensf160b172014-11-26 11:58:23 -05003985 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003986}
3987
3988GLboolean GL_APIENTRY glIsProgram(GLuint program)
3989{
Nicolas Capensf160b172014-11-26 11:58:23 -05003990 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04003991
Nicolas Capensf160b172014-11-26 11:58:23 -05003992 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003993
Nicolas Capensf160b172014-11-26 11:58:23 -05003994 if(context && program)
3995 {
3996 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003997
Nicolas Capensf160b172014-11-26 11:58:23 -05003998 if(programObject)
3999 {
4000 return GL_TRUE;
4001 }
4002 }
John Bauman66b8ab22014-05-06 15:57:45 -04004003
Nicolas Capensf160b172014-11-26 11:58:23 -05004004 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004005}
4006
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004007GLboolean GL_APIENTRY glIsQueryEXT(GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -04004008{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004009 TRACE("(GLuint name = %d)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04004010
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004011 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05004012 {
4013 return GL_FALSE;
4014 }
John Bauman66b8ab22014-05-06 15:57:45 -04004015
Nicolas Capensf160b172014-11-26 11:58:23 -05004016 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004017
Nicolas Capensf160b172014-11-26 11:58:23 -05004018 if(context)
4019 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004020 es2::Query *queryObject = context->getQuery(name, false, GL_NONE);
John Bauman66b8ab22014-05-06 15:57:45 -04004021
Nicolas Capensf160b172014-11-26 11:58:23 -05004022 if(queryObject)
4023 {
4024 return GL_TRUE;
4025 }
4026 }
John Bauman66b8ab22014-05-06 15:57:45 -04004027
Nicolas Capensf160b172014-11-26 11:58:23 -05004028 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004029}
4030
4031GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
4032{
Nicolas Capensf160b172014-11-26 11:58:23 -05004033 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004034
Nicolas Capensf160b172014-11-26 11:58:23 -05004035 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004036
Nicolas Capensf160b172014-11-26 11:58:23 -05004037 if(context && renderbuffer)
4038 {
4039 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004040
Nicolas Capensf160b172014-11-26 11:58:23 -05004041 if(renderbufferObject)
4042 {
4043 return GL_TRUE;
4044 }
4045 }
John Bauman66b8ab22014-05-06 15:57:45 -04004046
Nicolas Capensf160b172014-11-26 11:58:23 -05004047 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004048}
4049
4050GLboolean GL_APIENTRY glIsShader(GLuint shader)
4051{
Nicolas Capensf160b172014-11-26 11:58:23 -05004052 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004053
Nicolas Capensf160b172014-11-26 11:58:23 -05004054 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004055
Nicolas Capensf160b172014-11-26 11:58:23 -05004056 if(context && shader)
4057 {
4058 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004059
Nicolas Capensf160b172014-11-26 11:58:23 -05004060 if(shaderObject)
4061 {
4062 return GL_TRUE;
4063 }
4064 }
John Bauman66b8ab22014-05-06 15:57:45 -04004065
Nicolas Capensf160b172014-11-26 11:58:23 -05004066 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004067}
4068
4069GLboolean GL_APIENTRY glIsTexture(GLuint texture)
4070{
Nicolas Capensf160b172014-11-26 11:58:23 -05004071 TRACE("(GLuint texture = %d)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004072
Nicolas Capensf160b172014-11-26 11:58:23 -05004073 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004074
Nicolas Capensf160b172014-11-26 11:58:23 -05004075 if(context && texture)
4076 {
4077 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004078
Nicolas Capensf160b172014-11-26 11:58:23 -05004079 if(textureObject)
4080 {
4081 return GL_TRUE;
4082 }
4083 }
John Bauman66b8ab22014-05-06 15:57:45 -04004084
Nicolas Capensf160b172014-11-26 11:58:23 -05004085 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004086}
4087
4088void GL_APIENTRY glLineWidth(GLfloat width)
4089{
Nicolas Capensf160b172014-11-26 11:58:23 -05004090 TRACE("(GLfloat width = %f)", width);
John Bauman66b8ab22014-05-06 15:57:45 -04004091
Nicolas Capensf160b172014-11-26 11:58:23 -05004092 if(width <= 0.0f)
4093 {
4094 return error(GL_INVALID_VALUE);
4095 }
John Bauman66b8ab22014-05-06 15:57:45 -04004096
Nicolas Capensf160b172014-11-26 11:58:23 -05004097 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004098
Nicolas Capensf160b172014-11-26 11:58:23 -05004099 if(context)
4100 {
4101 context->setLineWidth(width);
4102 }
John Bauman66b8ab22014-05-06 15:57:45 -04004103}
4104
4105void GL_APIENTRY glLinkProgram(GLuint program)
4106{
Nicolas Capensf160b172014-11-26 11:58:23 -05004107 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004108
Nicolas Capensf160b172014-11-26 11:58:23 -05004109 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004110
Nicolas Capensf160b172014-11-26 11:58:23 -05004111 if(context)
4112 {
4113 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004114
Nicolas Capensf160b172014-11-26 11:58:23 -05004115 if(!programObject)
4116 {
4117 if(context->getShader(program))
4118 {
4119 return error(GL_INVALID_OPERATION);
4120 }
4121 else
4122 {
4123 return error(GL_INVALID_VALUE);
4124 }
4125 }
John Bauman66b8ab22014-05-06 15:57:45 -04004126
Nicolas Capensf160b172014-11-26 11:58:23 -05004127 programObject->link();
4128 }
John Bauman66b8ab22014-05-06 15:57:45 -04004129}
4130
4131void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
4132{
Nicolas Capensf160b172014-11-26 11:58:23 -05004133 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04004134
Nicolas Capensf160b172014-11-26 11:58:23 -05004135 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004136
Nicolas Capensf160b172014-11-26 11:58:23 -05004137 if(context)
4138 {
Alexis Hetued306182015-04-02 12:02:28 -04004139 egl::GLint clientVersion = context->getClientVersion();
4140
Nicolas Capensf160b172014-11-26 11:58:23 -05004141 switch(pname)
4142 {
4143 case GL_UNPACK_ALIGNMENT:
4144 if(param != 1 && param != 2 && param != 4 && param != 8)
4145 {
4146 return error(GL_INVALID_VALUE);
4147 }
4148 context->setUnpackAlignment(param);
4149 break;
4150 case GL_PACK_ALIGNMENT:
4151 if(param != 1 && param != 2 && param != 4 && param != 8)
4152 {
4153 return error(GL_INVALID_VALUE);
4154 }
4155 context->setPackAlignment(param);
4156 break;
Alexis Hetued306182015-04-02 12:02:28 -04004157 case GL_PACK_ROW_LENGTH:
4158 case GL_PACK_SKIP_PIXELS:
4159 case GL_PACK_SKIP_ROWS:
4160 case GL_UNPACK_ROW_LENGTH:
4161 case GL_UNPACK_IMAGE_HEIGHT:
4162 case GL_UNPACK_SKIP_PIXELS:
4163 case GL_UNPACK_SKIP_ROWS:
4164 case GL_UNPACK_SKIP_IMAGES:
4165 if(clientVersion >= 3)
4166 {
4167 UNIMPLEMENTED();
4168 break;
4169 }
4170 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05004171 default:
4172 return error(GL_INVALID_ENUM);
4173 }
4174 }
John Bauman66b8ab22014-05-06 15:57:45 -04004175}
4176
4177void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
4178{
Nicolas Capensf160b172014-11-26 11:58:23 -05004179 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
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)
4184 {
4185 context->setPolygonOffsetParams(factor, units);
4186 }
John Bauman66b8ab22014-05-06 15:57:45 -04004187}
4188
4189void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05004190 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
John Bauman66b8ab22014-05-06 15:57:45 -04004191{
Nicolas Capensf160b172014-11-26 11:58:23 -05004192 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4193 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4194 x, y, width, height, format, type, bufSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04004195
Nicolas Capensf160b172014-11-26 11:58:23 -05004196 if(width < 0 || height < 0 || bufSize < 0)
4197 {
4198 return error(GL_INVALID_VALUE);
4199 }
John Bauman66b8ab22014-05-06 15:57:45 -04004200
Nicolas Capensf160b172014-11-26 11:58:23 -05004201 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004202
Nicolas Capensf160b172014-11-26 11:58:23 -05004203 if(context)
4204 {
4205 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4206 }
John Bauman66b8ab22014-05-06 15:57:45 -04004207}
4208
4209void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
4210{
Nicolas Capensf160b172014-11-26 11:58:23 -05004211 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4212 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
4213 x, y, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004214
Nicolas Capensf160b172014-11-26 11:58:23 -05004215 if(width < 0 || height < 0)
4216 {
4217 return error(GL_INVALID_VALUE);
4218 }
John Bauman66b8ab22014-05-06 15:57:45 -04004219
Nicolas Capensf160b172014-11-26 11:58:23 -05004220 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004221
Nicolas Capensf160b172014-11-26 11:58:23 -05004222 if(context)
4223 {
4224 context->readPixels(x, y, width, height, format, type, NULL, pixels);
4225 }
John Bauman66b8ab22014-05-06 15:57:45 -04004226}
4227
4228void GL_APIENTRY glReleaseShaderCompiler(void)
4229{
Nicolas Capensf160b172014-11-26 11:58:23 -05004230 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04004231
Nicolas Capensf160b172014-11-26 11:58:23 -05004232 es2::Shader::releaseCompiler();
John Bauman66b8ab22014-05-06 15:57:45 -04004233}
4234
4235void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4236{
Nicolas Capensf160b172014-11-26 11:58:23 -05004237 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4238 target, samples, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004239
Nicolas Capensf160b172014-11-26 11:58:23 -05004240 switch(target)
4241 {
4242 case GL_RENDERBUFFER:
4243 break;
4244 default:
4245 return error(GL_INVALID_ENUM);
4246 }
John Bauman66b8ab22014-05-06 15:57:45 -04004247
Nicolas Capensf160b172014-11-26 11:58:23 -05004248 if(!es2::IsColorRenderable(internalformat) && !es2::IsDepthRenderable(internalformat) && !es2::IsStencilRenderable(internalformat))
4249 {
4250 return error(GL_INVALID_ENUM);
4251 }
John Bauman66b8ab22014-05-06 15:57:45 -04004252
Nicolas Capensf160b172014-11-26 11:58:23 -05004253 if(width < 0 || height < 0 || samples < 0)
4254 {
4255 return error(GL_INVALID_VALUE);
4256 }
John Bauman66b8ab22014-05-06 15:57:45 -04004257
Nicolas Capensf160b172014-11-26 11:58:23 -05004258 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004259
Nicolas Capensf160b172014-11-26 11:58:23 -05004260 if(context)
4261 {
4262 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4263 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4264 samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4265 {
4266 return error(GL_INVALID_VALUE);
4267 }
John Bauman66b8ab22014-05-06 15:57:45 -04004268
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004269 GLuint handle = context->getRenderbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05004270 if(handle == 0)
4271 {
4272 return error(GL_INVALID_OPERATION);
4273 }
John Bauman66b8ab22014-05-06 15:57:45 -04004274
Nicolas Capensf160b172014-11-26 11:58:23 -05004275 switch(internalformat)
4276 {
4277 case GL_DEPTH_COMPONENT16:
4278 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, samples));
4279 break;
4280 case GL_RGBA4:
4281 case GL_RGB5_A1:
4282 case GL_RGB565:
4283 case GL_RGB8_OES:
4284 case GL_RGBA8_OES:
4285 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4286 break;
4287 case GL_STENCIL_INDEX8:
4288 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4289 break;
4290 case GL_DEPTH24_STENCIL8_OES:
4291 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, samples));
4292 break;
4293 default:
4294 return error(GL_INVALID_ENUM);
4295 }
4296 }
John Bauman66b8ab22014-05-06 15:57:45 -04004297}
4298
4299void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4300{
Nicolas Capensf160b172014-11-26 11:58:23 -05004301 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004302}
4303
4304void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
4305{
Nicolas Capensf160b172014-11-26 11:58:23 -05004306 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
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->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4313 }
John Bauman66b8ab22014-05-06 15:57:45 -04004314}
4315
4316void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
4317{
Nicolas Capensf160b172014-11-26 11:58:23 -05004318 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
John Bauman66b8ab22014-05-06 15:57:45 -04004319
Nicolas Capensf160b172014-11-26 11:58:23 -05004320 if(condition != GL_ALL_COMPLETED_NV)
4321 {
4322 return error(GL_INVALID_ENUM);
4323 }
John Bauman66b8ab22014-05-06 15:57:45 -04004324
Nicolas Capensf160b172014-11-26 11:58:23 -05004325 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004326
Nicolas Capensf160b172014-11-26 11:58:23 -05004327 if(context)
4328 {
4329 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004330
Nicolas Capensf160b172014-11-26 11:58:23 -05004331 if(fenceObject == NULL)
4332 {
4333 return error(GL_INVALID_OPERATION);
4334 }
John Bauman66b8ab22014-05-06 15:57:45 -04004335
Nicolas Capensf160b172014-11-26 11:58:23 -05004336 fenceObject->setFence(condition);
4337 }
John Bauman66b8ab22014-05-06 15:57:45 -04004338}
4339
4340void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4341{
Nicolas Capensf160b172014-11-26 11:58:23 -05004342 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004343
Nicolas Capensf160b172014-11-26 11:58:23 -05004344 if(width < 0 || height < 0)
4345 {
4346 return error(GL_INVALID_VALUE);
4347 }
John Bauman66b8ab22014-05-06 15:57:45 -04004348
Nicolas Capensf160b172014-11-26 11:58:23 -05004349 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004350
Nicolas Capensf160b172014-11-26 11:58:23 -05004351 if(context)
4352 {
4353 context->setScissorParams(x, y, width, height);
4354 }
John Bauman66b8ab22014-05-06 15:57:45 -04004355}
4356
4357void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4358{
Nicolas Capensf160b172014-11-26 11:58:23 -05004359 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
4360 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
4361 n, shaders, binaryformat, binary, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004362
Nicolas Capensf160b172014-11-26 11:58:23 -05004363 // No binary shader formats are supported.
4364 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04004365}
4366
Nicolas Capensb0e93552014-10-28 11:54:43 -04004367void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
John Bauman66b8ab22014-05-06 15:57:45 -04004368{
Nicolas Capensf160b172014-11-26 11:58:23 -05004369 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
4370 shader, count, string, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004371
Nicolas Capensf160b172014-11-26 11:58:23 -05004372 if(count < 0)
4373 {
4374 return error(GL_INVALID_VALUE);
4375 }
John Bauman66b8ab22014-05-06 15:57:45 -04004376
Nicolas Capensf160b172014-11-26 11:58:23 -05004377 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004378
Nicolas Capensf160b172014-11-26 11:58:23 -05004379 if(context)
4380 {
4381 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004382
Nicolas Capensf160b172014-11-26 11:58:23 -05004383 if(!shaderObject)
4384 {
4385 if(context->getProgram(shader))
4386 {
4387 return error(GL_INVALID_OPERATION);
4388 }
4389 else
4390 {
4391 return error(GL_INVALID_VALUE);
4392 }
4393 }
John Bauman66b8ab22014-05-06 15:57:45 -04004394
Nicolas Capensf160b172014-11-26 11:58:23 -05004395 shaderObject->setSource(count, string, length);
4396 }
John Bauman66b8ab22014-05-06 15:57:45 -04004397}
4398
4399void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
4400{
Nicolas Capensf160b172014-11-26 11:58:23 -05004401 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004402}
4403
4404void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4405{
Nicolas Capensf160b172014-11-26 11:58:23 -05004406 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 -04004407
Nicolas Capensf160b172014-11-26 11:58:23 -05004408 switch(face)
4409 {
4410 case GL_FRONT:
4411 case GL_BACK:
4412 case GL_FRONT_AND_BACK:
4413 break;
4414 default:
4415 return error(GL_INVALID_ENUM);
4416 }
John Bauman66b8ab22014-05-06 15:57:45 -04004417
Nicolas Capensf160b172014-11-26 11:58:23 -05004418 switch(func)
4419 {
4420 case GL_NEVER:
4421 case GL_ALWAYS:
4422 case GL_LESS:
4423 case GL_LEQUAL:
4424 case GL_EQUAL:
4425 case GL_GEQUAL:
4426 case GL_GREATER:
4427 case GL_NOTEQUAL:
4428 break;
4429 default:
4430 return error(GL_INVALID_ENUM);
4431 }
John Bauman66b8ab22014-05-06 15:57:45 -04004432
Nicolas Capensf160b172014-11-26 11:58:23 -05004433 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004434
Nicolas Capensf160b172014-11-26 11:58:23 -05004435 if(context)
4436 {
4437 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4438 {
4439 context->setStencilParams(func, ref, mask);
4440 }
John Bauman66b8ab22014-05-06 15:57:45 -04004441
Nicolas Capensf160b172014-11-26 11:58:23 -05004442 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4443 {
4444 context->setStencilBackParams(func, ref, mask);
4445 }
4446 }
John Bauman66b8ab22014-05-06 15:57:45 -04004447}
4448
4449void GL_APIENTRY glStencilMask(GLuint mask)
4450{
Nicolas Capensf160b172014-11-26 11:58:23 -05004451 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004452}
4453
4454void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
4455{
Nicolas Capensf160b172014-11-26 11:58:23 -05004456 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004457
Nicolas Capensf160b172014-11-26 11:58:23 -05004458 switch(face)
4459 {
4460 case GL_FRONT:
4461 case GL_BACK:
4462 case GL_FRONT_AND_BACK:
4463 break;
4464 default:
4465 return error(GL_INVALID_ENUM);
4466 }
John Bauman66b8ab22014-05-06 15:57:45 -04004467
Nicolas Capensf160b172014-11-26 11:58:23 -05004468 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004469
Nicolas Capensf160b172014-11-26 11:58:23 -05004470 if(context)
4471 {
4472 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4473 {
4474 context->setStencilWritemask(mask);
4475 }
John Bauman66b8ab22014-05-06 15:57:45 -04004476
Nicolas Capensf160b172014-11-26 11:58:23 -05004477 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4478 {
4479 context->setStencilBackWritemask(mask);
4480 }
4481 }
John Bauman66b8ab22014-05-06 15:57:45 -04004482}
4483
4484void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4485{
Nicolas Capensf160b172014-11-26 11:58:23 -05004486 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004487}
4488
4489void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4490{
Nicolas Capensf160b172014-11-26 11:58:23 -05004491 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4492 face, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004493
Nicolas Capensf160b172014-11-26 11:58:23 -05004494 switch(face)
4495 {
4496 case GL_FRONT:
4497 case GL_BACK:
4498 case GL_FRONT_AND_BACK:
4499 break;
4500 default:
4501 return error(GL_INVALID_ENUM);
4502 }
John Bauman66b8ab22014-05-06 15:57:45 -04004503
Nicolas Capensf160b172014-11-26 11:58:23 -05004504 switch(fail)
4505 {
4506 case GL_ZERO:
4507 case GL_KEEP:
4508 case GL_REPLACE:
4509 case GL_INCR:
4510 case GL_DECR:
4511 case GL_INVERT:
4512 case GL_INCR_WRAP:
4513 case GL_DECR_WRAP:
4514 break;
4515 default:
4516 return error(GL_INVALID_ENUM);
4517 }
John Bauman66b8ab22014-05-06 15:57:45 -04004518
Nicolas Capensf160b172014-11-26 11:58:23 -05004519 switch(zfail)
4520 {
4521 case GL_ZERO:
4522 case GL_KEEP:
4523 case GL_REPLACE:
4524 case GL_INCR:
4525 case GL_DECR:
4526 case GL_INVERT:
4527 case GL_INCR_WRAP:
4528 case GL_DECR_WRAP:
4529 break;
4530 default:
4531 return error(GL_INVALID_ENUM);
4532 }
John Bauman66b8ab22014-05-06 15:57:45 -04004533
Nicolas Capensf160b172014-11-26 11:58:23 -05004534 switch(zpass)
4535 {
4536 case GL_ZERO:
4537 case GL_KEEP:
4538 case GL_REPLACE:
4539 case GL_INCR:
4540 case GL_DECR:
4541 case GL_INVERT:
4542 case GL_INCR_WRAP:
4543 case GL_DECR_WRAP:
4544 break;
4545 default:
4546 return error(GL_INVALID_ENUM);
4547 }
John Bauman66b8ab22014-05-06 15:57:45 -04004548
Nicolas Capensf160b172014-11-26 11:58:23 -05004549 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004550
Nicolas Capensf160b172014-11-26 11:58:23 -05004551 if(context)
4552 {
4553 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4554 {
4555 context->setStencilOperations(fail, zfail, zpass);
4556 }
John Bauman66b8ab22014-05-06 15:57:45 -04004557
Nicolas Capensf160b172014-11-26 11:58:23 -05004558 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4559 {
4560 context->setStencilBackOperations(fail, zfail, zpass);
4561 }
4562 }
John Bauman66b8ab22014-05-06 15:57:45 -04004563}
4564
4565GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
4566{
Nicolas Capensf160b172014-11-26 11:58:23 -05004567 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004568
Nicolas Capensf160b172014-11-26 11:58:23 -05004569 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004570
Nicolas Capensf160b172014-11-26 11:58:23 -05004571 if(context)
4572 {
4573 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004574
Nicolas Capensf160b172014-11-26 11:58:23 -05004575 if(fenceObject == NULL)
4576 {
4577 return error(GL_INVALID_OPERATION, GL_TRUE);
4578 }
John Bauman66b8ab22014-05-06 15:57:45 -04004579
Nicolas Capensf160b172014-11-26 11:58:23 -05004580 return fenceObject->testFence();
4581 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05004582
Nicolas Capensf160b172014-11-26 11:58:23 -05004583 return GL_TRUE;
John Bauman66b8ab22014-05-06 15:57:45 -04004584}
4585
4586void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4587 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4588{
Nicolas Capensf160b172014-11-26 11:58:23 -05004589 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4590 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
4591 target, level, internalformat, width, height, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004592
Nicolas Capensf160b172014-11-26 11:58:23 -05004593 if(!validImageSize(level, width, height))
4594 {
4595 return error(GL_INVALID_VALUE);
4596 }
John Bauman66b8ab22014-05-06 15:57:45 -04004597
Nicolas Capensf160b172014-11-26 11:58:23 -05004598 es2::Context *context = es2::getContext();
4599
4600 if(context)
4601 {
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004602 if(context->getClientVersion() < 3)
4603 {
4604 if(internalformat != format)
4605 {
4606 return error(GL_INVALID_OPERATION);
4607 }
4608 }
4609
4610 switch(format)
4611 {
4612 case GL_ALPHA:
4613 case GL_LUMINANCE:
4614 case GL_LUMINANCE_ALPHA:
4615 switch(type)
4616 {
4617 case GL_UNSIGNED_BYTE:
4618 case GL_FLOAT:
4619 case GL_HALF_FLOAT_OES:
4620 break;
4621 default:
4622 return error(GL_INVALID_ENUM);
4623 }
4624 break;
Alexis Hetued306182015-04-02 12:02:28 -04004625 case GL_RED:
4626 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004627 {
Alexis Hetued306182015-04-02 12:02:28 -04004628 case GL_R8:
4629 switch(type)
4630 {
4631 case GL_UNSIGNED_BYTE:
4632 break;
4633 default:
4634 return error(GL_INVALID_ENUM);
4635 }
4636 break;
4637 case GL_R8_SNORM:
4638 switch(type)
4639 {
4640 case GL_BYTE:
4641 break;
4642 default:
4643 return error(GL_INVALID_ENUM);
4644 }
4645 break;
4646 case GL_R16F:
4647 switch(type)
4648 {
4649 case GL_FLOAT:
4650 case GL_HALF_FLOAT:
4651 break;
4652 default:
4653 return error(GL_INVALID_ENUM);
4654 }
4655 break;
4656 case GL_R32F:
4657 switch(type)
4658 {
4659 case GL_FLOAT:
4660 break;
4661 default:
4662 return error(GL_INVALID_ENUM);
4663 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004664 break;
4665 default:
Alexis Hetued306182015-04-02 12:02:28 -04004666 return error(GL_INVALID_VALUE);
4667 }
4668 break;
4669 case GL_RED_INTEGER:
4670 switch(internalformat)
4671 {
4672 case GL_R8UI:
4673 switch(type)
4674 {
4675 case GL_UNSIGNED_BYTE:
4676 break;
4677 default:
4678 return error(GL_INVALID_ENUM);
4679 }
4680 break;
4681 case GL_R8I:
4682 switch(type)
4683 {
4684 case GL_BYTE:
4685 break;
4686 default:
4687 return error(GL_INVALID_ENUM);
4688 }
4689 break;
4690 case GL_R16UI:
4691 switch(type)
4692 {
4693 case GL_UNSIGNED_SHORT:
4694 break;
4695 default:
4696 return error(GL_INVALID_ENUM);
4697 }
4698 break;
4699 case GL_R16I:
4700 switch(type)
4701 {
4702 case GL_SHORT:
4703 break;
4704 default:
4705 return error(GL_INVALID_ENUM);
4706 }
4707 break;
4708 case GL_R32UI:
4709 switch(type)
4710 {
4711 case GL_UNSIGNED_INT:
4712 break;
4713 default:
4714 return error(GL_INVALID_ENUM);
4715 }
4716 break;
4717 case GL_R32I:
4718 switch(type)
4719 {
4720 case GL_INT:
4721 break;
4722 default:
4723 return error(GL_INVALID_ENUM);
4724 }
4725 break;
4726 default:
4727 return error(GL_INVALID_VALUE);
4728 }
4729 break;
4730 case GL_RG_INTEGER:
4731 switch(internalformat)
4732 {
4733 case GL_RG8UI:
4734 switch(type)
4735 {
4736 case GL_UNSIGNED_BYTE:
4737 break;
4738 default:
4739 return error(GL_INVALID_ENUM);
4740 }
4741 break;
4742 case GL_RG8I:
4743 switch(type)
4744 {
4745 case GL_BYTE:
4746 break;
4747 default:
4748 return error(GL_INVALID_ENUM);
4749 }
4750 break;
4751 case GL_RG16UI:
4752 switch(type)
4753 {
4754 case GL_UNSIGNED_SHORT:
4755 break;
4756 default:
4757 return error(GL_INVALID_ENUM);
4758 }
4759 break;
4760 case GL_RG16I:
4761 switch(type)
4762 {
4763 case GL_SHORT:
4764 break;
4765 default:
4766 return error(GL_INVALID_ENUM);
4767 }
4768 break;
4769 case GL_RG32UI:
4770 switch(type)
4771 {
4772 case GL_UNSIGNED_INT:
4773 break;
4774 default:
4775 return error(GL_INVALID_ENUM);
4776 }
4777 break;
4778 case GL_RG32I:
4779 switch(type)
4780 {
4781 case GL_INT:
4782 break;
4783 default:
4784 return error(GL_INVALID_ENUM);
4785 }
4786 break;
4787 default:
4788 return error(GL_INVALID_VALUE);
4789 }
4790 break;
4791 case GL_RGB_INTEGER:
4792 switch(internalformat)
4793 {
4794 case GL_RGB8UI:
4795 switch(type)
4796 {
4797 case GL_UNSIGNED_BYTE:
4798 break;
4799 default:
4800 return error(GL_INVALID_ENUM);
4801 }
4802 break;
4803 case GL_RGB8I:
4804 switch(type)
4805 {
4806 case GL_BYTE:
4807 break;
4808 default:
4809 return error(GL_INVALID_ENUM);
4810 }
4811 break;
4812 case GL_RGB16UI:
4813 switch(type)
4814 {
4815 case GL_UNSIGNED_SHORT:
4816 break;
4817 default:
4818 return error(GL_INVALID_ENUM);
4819 }
4820 break;
4821 case GL_RGB16I:
4822 switch(type)
4823 {
4824 case GL_SHORT:
4825 break;
4826 default:
4827 return error(GL_INVALID_ENUM);
4828 }
4829 break;
4830 case GL_RGB32UI:
4831 switch(type)
4832 {
4833 case GL_UNSIGNED_INT:
4834 break;
4835 default:
4836 return error(GL_INVALID_ENUM);
4837 }
4838 break;
4839 case GL_RGB32I:
4840 switch(type)
4841 {
4842 case GL_INT:
4843 break;
4844 default:
4845 return error(GL_INVALID_ENUM);
4846 }
4847 break;
4848 default:
4849 return error(GL_INVALID_VALUE);
4850 }
4851 break;
4852 case GL_RGBA_INTEGER:
4853 switch(internalformat)
4854 {
4855 case GL_RGBA8UI:
4856 switch(type)
4857 {
4858 case GL_UNSIGNED_BYTE:
4859 break;
4860 default:
4861 return error(GL_INVALID_ENUM);
4862 }
4863 break;
4864 case GL_RGBA8I:
4865 switch(type)
4866 {
4867 case GL_BYTE:
4868 break;
4869 default:
4870 return error(GL_INVALID_ENUM);
4871 }
4872 break;
4873 case GL_RGB10_A2UI:
4874 switch(type)
4875 {
4876 case GL_UNSIGNED_INT_2_10_10_10_REV:
4877 break;
4878 default:
4879 return error(GL_INVALID_ENUM);
4880 }
4881 break;
4882 case GL_RGBA16UI:
4883 switch(type)
4884 {
4885 case GL_UNSIGNED_SHORT:
4886 break;
4887 default:
4888 return error(GL_INVALID_ENUM);
4889 }
4890 break;
4891 case GL_RGBA16I:
4892 switch(type)
4893 {
4894 case GL_SHORT:
4895 break;
4896 default:
4897 return error(GL_INVALID_ENUM);
4898 }
4899 break;
4900 case GL_RGBA32UI:
4901 switch(type)
4902 {
4903 case GL_INT:
4904 break;
4905 default:
4906 return error(GL_INVALID_ENUM);
4907 }
4908 break;
4909 case GL_RGBA32I:
4910 switch(type)
4911 {
4912 case GL_UNSIGNED_INT:
4913 break;
4914 default:
4915 return error(GL_INVALID_ENUM);
4916 }
4917 break;
4918 default:
4919 return error(GL_INVALID_VALUE);
4920 }
4921 break;
4922 case GL_RG:
4923 switch(internalformat)
4924 {
4925 case GL_RG8:
4926 switch(type)
4927 {
4928 case GL_UNSIGNED_BYTE:
4929 break;
4930 default:
4931 return error(GL_INVALID_ENUM);
4932 }
4933 break;
4934 case GL_RG8_SNORM:
4935 switch(type)
4936 {
4937 case GL_BYTE:
4938 break;
4939 default:
4940 return error(GL_INVALID_ENUM);
4941 }
4942 break;
4943 case GL_RG16F:
4944 switch(type)
4945 {
4946 case GL_FLOAT:
4947 case GL_HALF_FLOAT:
4948 break;
4949 default:
4950 return error(GL_INVALID_ENUM);
4951 }
4952 break;
4953 case GL_RG32F:
4954 switch(type)
4955 {
4956 case GL_FLOAT:
4957 break;
4958 default:
4959 return error(GL_INVALID_ENUM);
4960 }
4961 break;
4962 default:
4963 return error(GL_INVALID_VALUE);
4964 }
4965 break;
4966 case GL_RGB:
4967 switch(internalformat)
4968 {
4969 case GL_RGB:
4970 switch(type)
4971 {
4972 case GL_UNSIGNED_BYTE:
4973 case GL_UNSIGNED_SHORT_5_6_5:
4974 case GL_FLOAT:
4975 case GL_HALF_FLOAT_OES:
4976 break;
4977 default:
4978 return error(GL_INVALID_ENUM);
4979 }
4980 break;
4981 case GL_RGB8:
4982 switch(type)
4983 {
4984 case GL_UNSIGNED_BYTE:
4985 break;
4986 default:
4987 return error(GL_INVALID_ENUM);
4988 }
4989 break;
4990 case GL_SRGB8:
4991 switch(type)
4992 {
4993 case GL_UNSIGNED_BYTE:
4994 break;
4995 default:
4996 return error(GL_INVALID_ENUM);
4997 }
4998 break;
4999 case GL_RGB565:
5000 switch(type)
5001 {
5002 case GL_UNSIGNED_BYTE:
5003 case GL_UNSIGNED_SHORT_5_6_5:
5004 break;
5005 default:
5006 return error(GL_INVALID_ENUM);
5007 }
5008 break;
5009 case GL_RGB8_SNORM:
5010 switch(type)
5011 {
5012 case GL_BYTE:
5013 break;
5014 default:
5015 return error(GL_INVALID_ENUM);
5016 }
5017 break;
5018 case GL_R11F_G11F_B10F:
5019 switch(type)
5020 {
5021 case GL_UNSIGNED_INT_10F_11F_11F_REV:
5022 case GL_FLOAT:
5023 case GL_HALF_FLOAT:
5024 break;
5025 default:
5026 return error(GL_INVALID_ENUM);
5027 }
5028 break;
5029 case GL_RGB9_E5:
5030 switch(type)
5031 {
5032 case GL_UNSIGNED_INT_5_9_9_9_REV:
5033 case GL_FLOAT:
5034 case GL_HALF_FLOAT:
5035 break;
5036 default:
5037 return error(GL_INVALID_ENUM);
5038 }
5039 break;
5040 case GL_RGB16F:
5041 switch(type)
5042 {
5043 case GL_FLOAT:
5044 case GL_HALF_FLOAT:
5045 break;
5046 default:
5047 return error(GL_INVALID_ENUM);
5048 }
5049 break;
5050 case GL_RGB32F:
5051 switch(type)
5052 {
5053 case GL_FLOAT:
5054 break;
5055 default:
5056 return error(GL_INVALID_ENUM);
5057 }
5058 break;
5059 default:
5060 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005061 }
5062 break;
5063 case GL_RGBA:
Alexis Hetued306182015-04-02 12:02:28 -04005064 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005065 {
Alexis Hetued306182015-04-02 12:02:28 -04005066 case GL_RGBA:
5067 switch(type)
5068 {
5069 case GL_UNSIGNED_BYTE:
5070 case GL_UNSIGNED_SHORT_4_4_4_4:
5071 case GL_UNSIGNED_SHORT_5_5_5_1:
5072 case GL_FLOAT:
5073 case GL_HALF_FLOAT_OES:
5074 break;
5075 default:
5076 return error(GL_INVALID_ENUM);
5077 }
5078 break;
5079 case GL_RGBA8:
5080 switch(type)
5081 {
5082 case GL_UNSIGNED_BYTE:
5083 break;
5084 default:
5085 return error(GL_INVALID_ENUM);
5086 }
5087 break;
5088 case GL_SRGB8_ALPHA8:
5089 switch(type)
5090 {
5091 case GL_UNSIGNED_BYTE:
5092 break;
5093 default:
5094 return error(GL_INVALID_ENUM);
5095 }
5096 break;
5097 case GL_RGB5_A1:
5098 switch(type)
5099 {
5100 case GL_UNSIGNED_BYTE:
5101 case GL_UNSIGNED_SHORT_5_5_5_1:
5102 case GL_UNSIGNED_INT_2_10_10_10_REV:
5103 break;
5104 default:
5105 return error(GL_INVALID_ENUM);
5106 }
5107 break;
5108 case GL_RGBA8_SNORM:
5109 switch(type)
5110 {
5111 case GL_BYTE:
5112 break;
5113 default:
5114 return error(GL_INVALID_ENUM);
5115 }
5116 break;
5117 case GL_RGBA4:
5118 switch(type)
5119 {
5120 case GL_UNSIGNED_BYTE:
5121 case GL_UNSIGNED_SHORT_4_4_4_4:
5122 break;
5123 default:
5124 return error(GL_INVALID_ENUM);
5125 }
5126 break;
5127 case GL_RGB10_A2:
5128 switch(type)
5129 {
5130 case GL_UNSIGNED_INT_2_10_10_10_REV:
5131 break;
5132 default:
5133 return error(GL_INVALID_ENUM);
5134 }
5135 break;
5136 case GL_RGBA16F:
5137 switch(type)
5138 {
5139 case GL_FLOAT:
5140 case GL_HALF_FLOAT:
5141 break;
5142 default:
5143 return error(GL_INVALID_ENUM);
5144 }
5145 break;
5146 case GL_RGBA32F:
5147 switch(type)
5148 {
5149 case GL_FLOAT:
5150 break;
5151 default:
5152 return error(GL_INVALID_ENUM);
5153 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005154 break;
5155 default:
Alexis Hetued306182015-04-02 12:02:28 -04005156 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005157 }
5158 break;
5159 case GL_BGRA_EXT:
5160 switch(type)
5161 {
5162 case GL_UNSIGNED_BYTE:
5163 break;
5164 default:
5165 return error(GL_INVALID_ENUM);
5166 }
5167 break;
5168 case GL_ETC1_RGB8_OES:
5169 return error(GL_INVALID_OPERATION);
5170 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5171 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5172 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5173 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5174 if(S3TC_SUPPORT)
5175 {
5176 return error(GL_INVALID_OPERATION);
5177 }
5178 else
5179 {
5180 return error(GL_INVALID_ENUM);
5181 }
5182 case GL_DEPTH_COMPONENT:
Alexis Hetued306182015-04-02 12:02:28 -04005183 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005184 {
Alexis Hetued306182015-04-02 12:02:28 -04005185 case GL_DEPTH_COMPONENT:
5186 case GL_DEPTH_COMPONENT16:
5187 switch(type)
5188 {
5189 case GL_UNSIGNED_SHORT:
5190 case GL_UNSIGNED_INT:
5191 break;
5192 default:
5193 return error(GL_INVALID_ENUM);
5194 }
5195 break;
5196 case GL_DEPTH_COMPONENT24:
5197 switch(type)
5198 {
5199 case GL_UNSIGNED_INT:
5200 break;
5201 default:
5202 return error(GL_INVALID_ENUM);
5203 }
5204 break;
5205 case GL_DEPTH_COMPONENT32F:
5206 switch(type)
5207 {
5208 case GL_UNSIGNED_INT:
5209 break;
5210 default:
5211 return error(GL_INVALID_ENUM);
5212 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005213 break;
5214 default:
Alexis Hetued306182015-04-02 12:02:28 -04005215 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005216 }
5217 break;
5218 case GL_DEPTH_STENCIL_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005219 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005220 {
Alexis Hetued306182015-04-02 12:02:28 -04005221 case GL_DEPTH_STENCIL_OES:
5222 case GL_DEPTH24_STENCIL8:
5223 switch(type)
5224 {
5225 case GL_UNSIGNED_INT_24_8_OES:
5226 break;
5227 default:
5228 return error(GL_INVALID_ENUM);
5229 }
5230 break;
5231 case GL_DEPTH32F_STENCIL8:
5232 switch(type)
5233 {
5234 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
5235 break;
5236 default:
5237 return error(GL_INVALID_ENUM);
5238 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005239 break;
5240 default:
Alexis Hetued306182015-04-02 12:02:28 -04005241 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005242 }
5243 break;
5244 default:
5245 return error(GL_INVALID_VALUE);
5246 }
5247
5248 if(border != 0)
5249 {
5250 return error(GL_INVALID_VALUE);
5251 }
5252
Nicolas Capensf160b172014-11-26 11:58:23 -05005253 switch(target)
5254 {
Nicolas Capens22658242014-11-29 00:31:41 -05005255 case GL_TEXTURE_2D:
Nicolas Capensf160b172014-11-26 11:58:23 -05005256 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5257 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
John Bauman66b8ab22014-05-06 15:57:45 -04005258 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005259 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005260 }
5261 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005262 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5263 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5264 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5265 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5266 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5267 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
Nicolas Capensf160b172014-11-26 11:58:23 -05005268 if(width != height)
John Bauman66b8ab22014-05-06 15:57:45 -04005269 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005270 return error(GL_INVALID_VALUE);
5271 }
5272
5273 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5274 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5275 {
5276 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005277 }
5278 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005279 default:
Nicolas Capensf160b172014-11-26 11:58:23 -05005280 return error(GL_INVALID_ENUM);
5281 }
John Bauman66b8ab22014-05-06 15:57:45 -04005282
Nicolas Capensf160b172014-11-26 11:58:23 -05005283 if(target == GL_TEXTURE_2D)
5284 {
5285 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005286
Nicolas Capensf160b172014-11-26 11:58:23 -05005287 if(!texture)
5288 {
5289 return error(GL_INVALID_OPERATION);
5290 }
John Bauman66b8ab22014-05-06 15:57:45 -04005291
Nicolas Capensf160b172014-11-26 11:58:23 -05005292 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
5293 }
5294 else
5295 {
5296 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04005297
Nicolas Capensf160b172014-11-26 11:58:23 -05005298 if(!texture)
5299 {
5300 return error(GL_INVALID_OPERATION);
5301 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005302
Nicolas Capensf160b172014-11-26 11:58:23 -05005303 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
5304 }
5305 }
John Bauman66b8ab22014-05-06 15:57:45 -04005306}
5307
5308void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5309{
Nicolas Capensf160b172014-11-26 11:58:23 -05005310 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005311
Nicolas Capensf160b172014-11-26 11:58:23 -05005312 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005313
Nicolas Capensf160b172014-11-26 11:58:23 -05005314 if(context)
5315 {
5316 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005317
Alexis Hetued306182015-04-02 12:02:28 -04005318 egl::GLint clientVersion = context->getClientVersion();
5319
Nicolas Capensf160b172014-11-26 11:58:23 -05005320 switch(target)
5321 {
5322 case GL_TEXTURE_2D:
5323 texture = context->getTexture2D();
5324 break;
Alexis Hetued306182015-04-02 12:02:28 -04005325 case GL_TEXTURE_2D_ARRAY:
5326 if(clientVersion < 3)
5327 {
5328 return error(GL_INVALID_ENUM);
5329 }
5330 else
5331 {
5332 UNIMPLEMENTED();
5333 texture = context->getTexture3D();
5334 break;
5335 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005336 case GL_TEXTURE_3D_OES:
5337 texture = context->getTexture3D();
5338 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005339 case GL_TEXTURE_CUBE_MAP:
5340 texture = context->getTextureCubeMap();
5341 break;
5342 case GL_TEXTURE_EXTERNAL_OES:
5343 texture = context->getTextureExternal();
5344 break;
5345 default:
5346 return error(GL_INVALID_ENUM);
5347 }
John Bauman66b8ab22014-05-06 15:57:45 -04005348
Nicolas Capensf160b172014-11-26 11:58:23 -05005349 switch(pname)
5350 {
5351 case GL_TEXTURE_WRAP_S:
5352 if(!texture->setWrapS((GLenum)param))
5353 {
5354 return error(GL_INVALID_ENUM);
5355 }
5356 break;
5357 case GL_TEXTURE_WRAP_T:
5358 if(!texture->setWrapT((GLenum)param))
5359 {
5360 return error(GL_INVALID_ENUM);
5361 }
5362 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005363 case GL_TEXTURE_WRAP_R_OES:
5364 if(!texture->setWrapR((GLenum)param))
5365 {
5366 return error(GL_INVALID_ENUM);
5367 }
5368 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005369 case GL_TEXTURE_MIN_FILTER:
5370 if(!texture->setMinFilter((GLenum)param))
5371 {
5372 return error(GL_INVALID_ENUM);
5373 }
5374 break;
5375 case GL_TEXTURE_MAG_FILTER:
5376 if(!texture->setMagFilter((GLenum)param))
5377 {
5378 return error(GL_INVALID_ENUM);
5379 }
5380 break;
5381 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5382 if(!texture->setMaxAnisotropy(param))
5383 {
5384 return error(GL_INVALID_VALUE);
5385 }
5386 break;
Alexis Hetued306182015-04-02 12:02:28 -04005387 case GL_TEXTURE_BASE_LEVEL:
5388 if(clientVersion < 3 || !texture->setBaseLevel((GLint)param))
5389 {
5390 return error(GL_INVALID_VALUE);
5391 }
5392 break;
5393 case GL_TEXTURE_COMPARE_FUNC:
5394 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5395 {
5396 return error(GL_INVALID_VALUE);
5397 }
5398 break;
5399 case GL_TEXTURE_COMPARE_MODE:
5400 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5401 {
5402 return error(GL_INVALID_VALUE);
5403 }
5404 break;
5405 case GL_TEXTURE_IMMUTABLE_FORMAT:
5406 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5407 {
5408 return error(GL_INVALID_VALUE);
5409 }
5410 break;
5411 case GL_TEXTURE_MAX_LEVEL:
5412 if(clientVersion < 3 || !texture->setMaxLevel((GLint)param))
5413 {
5414 return error(GL_INVALID_VALUE);
5415 }
5416 break;
5417 case GL_TEXTURE_MAX_LOD:
5418 if(clientVersion < 3 || !texture->setMaxLOD(param))
5419 {
5420 return error(GL_INVALID_VALUE);
5421 }
5422 break;
5423 case GL_TEXTURE_MIN_LOD:
5424 if(clientVersion < 3 || !texture->setMinLOD(param))
5425 {
5426 return error(GL_INVALID_VALUE);
5427 }
5428 break;
5429 case GL_TEXTURE_SWIZZLE_R:
5430 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5431 {
5432 return error(GL_INVALID_VALUE);
5433 }
5434 break;
5435 case GL_TEXTURE_SWIZZLE_G:
5436 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5437 {
5438 return error(GL_INVALID_VALUE);
5439 }
5440 break;
5441 case GL_TEXTURE_SWIZZLE_B:
5442 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5443 {
5444 return error(GL_INVALID_VALUE);
5445 }
5446 break;
5447 case GL_TEXTURE_SWIZZLE_A:
5448 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5449 {
5450 return error(GL_INVALID_VALUE);
5451 }
5452 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005453 default:
5454 return error(GL_INVALID_ENUM);
5455 }
5456 }
John Bauman66b8ab22014-05-06 15:57:45 -04005457}
5458
5459void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5460{
Nicolas Capensf160b172014-11-26 11:58:23 -05005461 glTexParameterf(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005462}
5463
5464void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
5465{
Nicolas Capensf160b172014-11-26 11:58:23 -05005466 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005467
Nicolas Capensf160b172014-11-26 11:58:23 -05005468 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005469
Nicolas Capensf160b172014-11-26 11:58:23 -05005470 if(context)
5471 {
5472 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005473
Alexis Hetued306182015-04-02 12:02:28 -04005474 egl::GLint clientVersion = context->getClientVersion();
5475
Nicolas Capensf160b172014-11-26 11:58:23 -05005476 switch(target)
5477 {
5478 case GL_TEXTURE_2D:
5479 texture = context->getTexture2D();
5480 break;
Alexis Hetued306182015-04-02 12:02:28 -04005481 case GL_TEXTURE_2D_ARRAY:
5482 if(clientVersion < 3)
5483 {
5484 return error(GL_INVALID_ENUM);
5485 }
5486 else
5487 {
5488 UNIMPLEMENTED();
5489 texture = context->getTexture3D();
5490 break;
5491 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005492 case GL_TEXTURE_3D_OES:
5493 texture = context->getTexture3D();
5494 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005495 case GL_TEXTURE_CUBE_MAP:
5496 texture = context->getTextureCubeMap();
5497 break;
5498 case GL_TEXTURE_EXTERNAL_OES:
Alexis Hetuf7be67f2015-02-11 16:11:07 -05005499 texture = context->getTextureExternal();
5500 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005501 default:
5502 return error(GL_INVALID_ENUM);
5503 }
John Bauman66b8ab22014-05-06 15:57:45 -04005504
Nicolas Capensf160b172014-11-26 11:58:23 -05005505 switch(pname)
5506 {
5507 case GL_TEXTURE_WRAP_S:
5508 if(!texture->setWrapS((GLenum)param))
5509 {
5510 return error(GL_INVALID_ENUM);
5511 }
5512 break;
5513 case GL_TEXTURE_WRAP_T:
5514 if(!texture->setWrapT((GLenum)param))
5515 {
5516 return error(GL_INVALID_ENUM);
5517 }
5518 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005519 case GL_TEXTURE_WRAP_R_OES:
5520 if(!texture->setWrapR((GLenum)param))
5521 {
5522 return error(GL_INVALID_ENUM);
5523 }
5524 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005525 case GL_TEXTURE_MIN_FILTER:
5526 if(!texture->setMinFilter((GLenum)param))
5527 {
5528 return error(GL_INVALID_ENUM);
5529 }
5530 break;
5531 case GL_TEXTURE_MAG_FILTER:
5532 if(!texture->setMagFilter((GLenum)param))
5533 {
5534 return error(GL_INVALID_ENUM);
5535 }
5536 break;
5537 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5538 if(!texture->setMaxAnisotropy((GLfloat)param))
5539 {
5540 return error(GL_INVALID_VALUE);
5541 }
5542 break;
Alexis Hetued306182015-04-02 12:02:28 -04005543 case GL_TEXTURE_BASE_LEVEL:
5544 if(clientVersion < 3 || !texture->setBaseLevel(param))
5545 {
5546 return error(GL_INVALID_VALUE);
5547 }
5548 break;
5549 case GL_TEXTURE_COMPARE_FUNC:
5550 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5551 {
5552 return error(GL_INVALID_VALUE);
5553 }
5554 break;
5555 case GL_TEXTURE_COMPARE_MODE:
5556 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5557 {
5558 return error(GL_INVALID_VALUE);
5559 }
5560 case GL_TEXTURE_IMMUTABLE_FORMAT:
5561 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5562 {
5563 return error(GL_INVALID_VALUE);
5564 }
5565 break;
5566 case GL_TEXTURE_MAX_LEVEL:
5567 if(clientVersion < 3 || !texture->setMaxLevel(param))
5568 {
5569 return error(GL_INVALID_VALUE);
5570 }
5571 break;
5572 case GL_TEXTURE_MAX_LOD:
5573 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5574 {
5575 return error(GL_INVALID_VALUE);
5576 }
5577 break;
5578 case GL_TEXTURE_MIN_LOD:
5579 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5580 {
5581 return error(GL_INVALID_VALUE);
5582 }
5583 break;
5584 case GL_TEXTURE_SWIZZLE_R:
5585 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5586 {
5587 return error(GL_INVALID_VALUE);
5588 }
5589 break;
5590 case GL_TEXTURE_SWIZZLE_G:
5591 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5592 {
5593 return error(GL_INVALID_VALUE);
5594 }
5595 break;
5596 case GL_TEXTURE_SWIZZLE_B:
5597 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5598 {
5599 return error(GL_INVALID_VALUE);
5600 }
5601 break;
5602 case GL_TEXTURE_SWIZZLE_A:
5603 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5604 {
5605 return error(GL_INVALID_VALUE);
5606 }
5607 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005608 default:
5609 return error(GL_INVALID_ENUM);
5610 }
5611 }
John Bauman66b8ab22014-05-06 15:57:45 -04005612}
5613
5614void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5615{
Nicolas Capensf160b172014-11-26 11:58:23 -05005616 glTexParameteri(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005617}
5618
5619void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05005620 GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04005621{
Nicolas Capensf160b172014-11-26 11:58:23 -05005622 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5623 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
5624 "const GLvoid* pixels = 0x%0.8p)",
5625 target, level, xoffset, yoffset, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04005626
Nicolas Capensf160b172014-11-26 11:58:23 -05005627 if(!es2::IsTextureTarget(target))
5628 {
5629 return error(GL_INVALID_ENUM);
5630 }
John Bauman66b8ab22014-05-06 15:57:45 -04005631
Nicolas Capensf160b172014-11-26 11:58:23 -05005632 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5633 {
5634 return error(GL_INVALID_VALUE);
5635 }
John Bauman66b8ab22014-05-06 15:57:45 -04005636
Nicolas Capensf160b172014-11-26 11:58:23 -05005637 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5638 {
5639 return error(GL_INVALID_VALUE);
5640 }
John Bauman66b8ab22014-05-06 15:57:45 -04005641
Nicolas Capensf160b172014-11-26 11:58:23 -05005642 if(!es2::CheckTextureFormatType(format, type))
5643 {
5644 return error(GL_INVALID_ENUM);
5645 }
John Bauman66b8ab22014-05-06 15:57:45 -04005646
Nicolas Capensf160b172014-11-26 11:58:23 -05005647 if(width == 0 || height == 0 || pixels == NULL)
5648 {
5649 return;
5650 }
John Bauman66b8ab22014-05-06 15:57:45 -04005651
Nicolas Capensf160b172014-11-26 11:58:23 -05005652 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005653
Nicolas Capensf160b172014-11-26 11:58:23 -05005654 if(context)
5655 {
Alexis Hetub027aa92015-01-19 15:56:12 -05005656 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05005657 {
5658 return error(GL_INVALID_VALUE);
5659 }
John Bauman66b8ab22014-05-06 15:57:45 -04005660
Nicolas Capensf160b172014-11-26 11:58:23 -05005661 if(target == GL_TEXTURE_2D)
5662 {
5663 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005664
Nicolas Capensf160b172014-11-26 11:58:23 -05005665 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5666 {
5667 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5668 }
5669 }
5670 else if(es2::IsCubemapTextureTarget(target))
5671 {
5672 es2::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens08e90f02014-11-21 12:49:12 -05005673
Nicolas Capensf160b172014-11-26 11:58:23 -05005674 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5675 {
5676 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5677 }
5678 }
5679 else
5680 {
5681 UNREACHABLE();
5682 }
5683 }
John Bauman66b8ab22014-05-06 15:57:45 -04005684}
5685
5686void GL_APIENTRY glUniform1f(GLint location, GLfloat x)
5687{
Nicolas Capensf160b172014-11-26 11:58:23 -05005688 glUniform1fv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005689}
5690
5691void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5692{
Nicolas Capensf160b172014-11-26 11:58:23 -05005693 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005694
Nicolas Capensf160b172014-11-26 11:58:23 -05005695 if(count < 0)
5696 {
5697 return error(GL_INVALID_VALUE);
5698 }
John Bauman66b8ab22014-05-06 15:57:45 -04005699
Nicolas Capensf160b172014-11-26 11:58:23 -05005700 if(location == -1)
5701 {
5702 return;
5703 }
John Bauman66b8ab22014-05-06 15:57:45 -04005704
Nicolas Capensf160b172014-11-26 11:58:23 -05005705 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005706
Nicolas Capensf160b172014-11-26 11:58:23 -05005707 if(context)
5708 {
5709 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005710
Nicolas Capensf160b172014-11-26 11:58:23 -05005711 if(!program)
5712 {
5713 return error(GL_INVALID_OPERATION);
5714 }
John Bauman66b8ab22014-05-06 15:57:45 -04005715
Nicolas Capensf160b172014-11-26 11:58:23 -05005716 if(!program->setUniform1fv(location, count, v))
5717 {
5718 return error(GL_INVALID_OPERATION);
5719 }
5720 }
John Bauman66b8ab22014-05-06 15:57:45 -04005721}
5722
5723void GL_APIENTRY glUniform1i(GLint location, GLint x)
5724{
Nicolas Capensf160b172014-11-26 11:58:23 -05005725 glUniform1iv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005726}
5727
5728void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
5729{
Nicolas Capensf160b172014-11-26 11:58:23 -05005730 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005731
Nicolas Capensf160b172014-11-26 11:58:23 -05005732 if(count < 0)
5733 {
5734 return error(GL_INVALID_VALUE);
5735 }
John Bauman66b8ab22014-05-06 15:57:45 -04005736
Nicolas Capensf160b172014-11-26 11:58:23 -05005737 if(location == -1)
5738 {
5739 return;
5740 }
John Bauman66b8ab22014-05-06 15:57:45 -04005741
Nicolas Capensf160b172014-11-26 11:58:23 -05005742 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005743
Nicolas Capensf160b172014-11-26 11:58:23 -05005744 if(context)
5745 {
5746 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005747
Nicolas Capensf160b172014-11-26 11:58:23 -05005748 if(!program)
5749 {
5750 return error(GL_INVALID_OPERATION);
5751 }
John Bauman66b8ab22014-05-06 15:57:45 -04005752
Nicolas Capensf160b172014-11-26 11:58:23 -05005753 if(!program->setUniform1iv(location, count, v))
5754 {
5755 return error(GL_INVALID_OPERATION);
5756 }
5757 }
John Bauman66b8ab22014-05-06 15:57:45 -04005758}
5759
5760void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
5761{
Nicolas Capensf160b172014-11-26 11:58:23 -05005762 GLfloat xy[2] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005763
Nicolas Capensf160b172014-11-26 11:58:23 -05005764 glUniform2fv(location, 1, (GLfloat*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005765}
5766
5767void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5768{
Nicolas Capensf160b172014-11-26 11:58:23 -05005769 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005770
Nicolas Capensf160b172014-11-26 11:58:23 -05005771 if(count < 0)
5772 {
5773 return error(GL_INVALID_VALUE);
5774 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005775
Nicolas Capensf160b172014-11-26 11:58:23 -05005776 if(location == -1)
5777 {
5778 return;
5779 }
John Bauman66b8ab22014-05-06 15:57:45 -04005780
Nicolas Capensf160b172014-11-26 11:58:23 -05005781 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005782
Nicolas Capensf160b172014-11-26 11:58:23 -05005783 if(context)
5784 {
5785 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005786
Nicolas Capensf160b172014-11-26 11:58:23 -05005787 if(!program)
5788 {
5789 return error(GL_INVALID_OPERATION);
5790 }
John Bauman66b8ab22014-05-06 15:57:45 -04005791
Nicolas Capensf160b172014-11-26 11:58:23 -05005792 if(!program->setUniform2fv(location, count, v))
5793 {
5794 return error(GL_INVALID_OPERATION);
5795 }
5796 }
John Bauman66b8ab22014-05-06 15:57:45 -04005797}
5798
5799void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)
5800{
Nicolas Capensf160b172014-11-26 11:58:23 -05005801 GLint xy[4] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005802
Nicolas Capensf160b172014-11-26 11:58:23 -05005803 glUniform2iv(location, 1, (GLint*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005804}
5805
5806void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
5807{
Nicolas Capensf160b172014-11-26 11:58:23 -05005808 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005809
Nicolas Capensf160b172014-11-26 11:58:23 -05005810 if(count < 0)
5811 {
5812 return error(GL_INVALID_VALUE);
5813 }
John Bauman66b8ab22014-05-06 15:57:45 -04005814
Nicolas Capensf160b172014-11-26 11:58:23 -05005815 if(location == -1)
5816 {
5817 return;
5818 }
John Bauman66b8ab22014-05-06 15:57:45 -04005819
Nicolas Capensf160b172014-11-26 11:58:23 -05005820 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005821
Nicolas Capensf160b172014-11-26 11:58:23 -05005822 if(context)
5823 {
5824 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005825
Nicolas Capensf160b172014-11-26 11:58:23 -05005826 if(!program)
5827 {
5828 return error(GL_INVALID_OPERATION);
5829 }
John Bauman66b8ab22014-05-06 15:57:45 -04005830
Nicolas Capensf160b172014-11-26 11:58:23 -05005831 if(!program->setUniform2iv(location, count, v))
5832 {
5833 return error(GL_INVALID_OPERATION);
5834 }
5835 }
John Bauman66b8ab22014-05-06 15:57:45 -04005836}
5837
5838void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5839{
Nicolas Capensf160b172014-11-26 11:58:23 -05005840 GLfloat xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04005841
Nicolas Capensf160b172014-11-26 11:58:23 -05005842 glUniform3fv(location, 1, (GLfloat*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04005843}
5844
5845void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5846{
Nicolas Capensf160b172014-11-26 11:58:23 -05005847 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005848
Nicolas Capensf160b172014-11-26 11:58:23 -05005849 if(count < 0)
5850 {
5851 return error(GL_INVALID_VALUE);
5852 }
John Bauman66b8ab22014-05-06 15:57:45 -04005853
Nicolas Capensf160b172014-11-26 11:58:23 -05005854 if(location == -1)
5855 {
5856 return;
5857 }
John Bauman66b8ab22014-05-06 15:57:45 -04005858
Nicolas Capensf160b172014-11-26 11:58:23 -05005859 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005860
Nicolas Capensf160b172014-11-26 11:58:23 -05005861 if(context)
5862 {
5863 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005864
Nicolas Capensf160b172014-11-26 11:58:23 -05005865 if(!program)
5866 {
5867 return error(GL_INVALID_OPERATION);
5868 }
John Bauman66b8ab22014-05-06 15:57:45 -04005869
Nicolas Capensf160b172014-11-26 11:58:23 -05005870 if(!program->setUniform3fv(location, count, v))
5871 {
5872 return error(GL_INVALID_OPERATION);
5873 }
5874 }
John Bauman66b8ab22014-05-06 15:57:45 -04005875}
5876
5877void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
5878{
Nicolas Capensf160b172014-11-26 11:58:23 -05005879 GLint xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04005880
Nicolas Capensf160b172014-11-26 11:58:23 -05005881 glUniform3iv(location, 1, (GLint*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04005882}
5883
5884void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
5885{
Nicolas Capensf160b172014-11-26 11:58:23 -05005886 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005887
Nicolas Capensf160b172014-11-26 11:58:23 -05005888 if(count < 0)
5889 {
5890 return error(GL_INVALID_VALUE);
5891 }
John Bauman66b8ab22014-05-06 15:57:45 -04005892
Nicolas Capensf160b172014-11-26 11:58:23 -05005893 if(location == -1)
5894 {
5895 return;
5896 }
John Bauman66b8ab22014-05-06 15:57:45 -04005897
Nicolas Capensf160b172014-11-26 11:58:23 -05005898 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005899
Nicolas Capensf160b172014-11-26 11:58:23 -05005900 if(context)
5901 {
5902 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005903
Nicolas Capensf160b172014-11-26 11:58:23 -05005904 if(!program)
5905 {
5906 return error(GL_INVALID_OPERATION);
5907 }
John Bauman66b8ab22014-05-06 15:57:45 -04005908
Nicolas Capensf160b172014-11-26 11:58:23 -05005909 if(!program->setUniform3iv(location, count, v))
5910 {
5911 return error(GL_INVALID_OPERATION);
5912 }
5913 }
John Bauman66b8ab22014-05-06 15:57:45 -04005914}
5915
5916void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5917{
Nicolas Capensf160b172014-11-26 11:58:23 -05005918 GLfloat xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04005919
Nicolas Capensf160b172014-11-26 11:58:23 -05005920 glUniform4fv(location, 1, (GLfloat*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04005921}
5922
5923void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5924{
Nicolas Capensf160b172014-11-26 11:58:23 -05005925 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005926
Nicolas Capensf160b172014-11-26 11:58:23 -05005927 if(count < 0)
5928 {
5929 return error(GL_INVALID_VALUE);
5930 }
John Bauman66b8ab22014-05-06 15:57:45 -04005931
Nicolas Capensf160b172014-11-26 11:58:23 -05005932 if(location == -1)
5933 {
5934 return;
5935 }
John Bauman66b8ab22014-05-06 15:57:45 -04005936
Nicolas Capensf160b172014-11-26 11:58:23 -05005937 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005938
Nicolas Capensf160b172014-11-26 11:58:23 -05005939 if(context)
5940 {
5941 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005942
Nicolas Capensf160b172014-11-26 11:58:23 -05005943 if(!program)
5944 {
5945 return error(GL_INVALID_OPERATION);
5946 }
John Bauman66b8ab22014-05-06 15:57:45 -04005947
Nicolas Capensf160b172014-11-26 11:58:23 -05005948 if(!program->setUniform4fv(location, count, v))
5949 {
5950 return error(GL_INVALID_OPERATION);
5951 }
5952 }
John Bauman66b8ab22014-05-06 15:57:45 -04005953}
5954
5955void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5956{
Nicolas Capensf160b172014-11-26 11:58:23 -05005957 GLint xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04005958
Nicolas Capensf160b172014-11-26 11:58:23 -05005959 glUniform4iv(location, 1, (GLint*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04005960}
5961
5962void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
5963{
Nicolas Capensf160b172014-11-26 11:58:23 -05005964 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005965
Nicolas Capensf160b172014-11-26 11:58:23 -05005966 if(count < 0)
5967 {
5968 return error(GL_INVALID_VALUE);
5969 }
John Bauman66b8ab22014-05-06 15:57:45 -04005970
Nicolas Capensf160b172014-11-26 11:58:23 -05005971 if(location == -1)
5972 {
5973 return;
5974 }
John Bauman66b8ab22014-05-06 15:57:45 -04005975
Nicolas Capensf160b172014-11-26 11:58:23 -05005976 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005977
Nicolas Capensf160b172014-11-26 11:58:23 -05005978 if(context)
5979 {
5980 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005981
Nicolas Capensf160b172014-11-26 11:58:23 -05005982 if(!program)
5983 {
5984 return error(GL_INVALID_OPERATION);
5985 }
John Bauman66b8ab22014-05-06 15:57:45 -04005986
Nicolas Capensf160b172014-11-26 11:58:23 -05005987 if(!program->setUniform4iv(location, count, v))
5988 {
5989 return error(GL_INVALID_OPERATION);
5990 }
5991 }
John Bauman66b8ab22014-05-06 15:57:45 -04005992}
5993
5994void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5995{
Nicolas Capensf160b172014-11-26 11:58:23 -05005996 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5997 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04005998
Nicolas Capensf160b172014-11-26 11:58:23 -05005999 if(count < 0 || transpose != GL_FALSE)
6000 {
6001 return error(GL_INVALID_VALUE);
6002 }
John Bauman66b8ab22014-05-06 15:57:45 -04006003
Nicolas Capensf160b172014-11-26 11:58:23 -05006004 if(location == -1)
6005 {
6006 return;
6007 }
John Bauman66b8ab22014-05-06 15:57:45 -04006008
Nicolas Capensf160b172014-11-26 11:58:23 -05006009 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006010
Nicolas Capensf160b172014-11-26 11:58:23 -05006011 if(context)
6012 {
6013 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006014
Nicolas Capensf160b172014-11-26 11:58:23 -05006015 if(!program)
6016 {
6017 return error(GL_INVALID_OPERATION);
6018 }
John Bauman66b8ab22014-05-06 15:57:45 -04006019
Nicolas Capensf160b172014-11-26 11:58:23 -05006020 if(!program->setUniformMatrix2fv(location, count, value))
6021 {
6022 return error(GL_INVALID_OPERATION);
6023 }
6024 }
John Bauman66b8ab22014-05-06 15:57:45 -04006025}
6026
6027void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6028{
Nicolas Capensf160b172014-11-26 11:58:23 -05006029 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
6030 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006031
Nicolas Capensf160b172014-11-26 11:58:23 -05006032 if(count < 0 || transpose != GL_FALSE)
6033 {
6034 return error(GL_INVALID_VALUE);
6035 }
John Bauman66b8ab22014-05-06 15:57:45 -04006036
Nicolas Capensf160b172014-11-26 11:58:23 -05006037 if(location == -1)
6038 {
6039 return;
6040 }
John Bauman66b8ab22014-05-06 15:57:45 -04006041
Nicolas Capensf160b172014-11-26 11:58:23 -05006042 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006043
Nicolas Capensf160b172014-11-26 11:58:23 -05006044 if(context)
6045 {
6046 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006047
Nicolas Capensf160b172014-11-26 11:58:23 -05006048 if(!program)
6049 {
6050 return error(GL_INVALID_OPERATION);
6051 }
John Bauman66b8ab22014-05-06 15:57:45 -04006052
Nicolas Capensf160b172014-11-26 11:58:23 -05006053 if(!program->setUniformMatrix3fv(location, count, value))
6054 {
6055 return error(GL_INVALID_OPERATION);
6056 }
6057 }
John Bauman66b8ab22014-05-06 15:57:45 -04006058}
6059
6060void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6061{
Nicolas Capensf160b172014-11-26 11:58:23 -05006062 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
6063 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006064
Nicolas Capensf160b172014-11-26 11:58:23 -05006065 if(count < 0 || transpose != GL_FALSE)
6066 {
6067 return error(GL_INVALID_VALUE);
6068 }
John Bauman66b8ab22014-05-06 15:57:45 -04006069
Nicolas Capensf160b172014-11-26 11:58:23 -05006070 if(location == -1)
6071 {
6072 return;
6073 }
John Bauman66b8ab22014-05-06 15:57:45 -04006074
Nicolas Capensf160b172014-11-26 11:58:23 -05006075 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006076
Nicolas Capensf160b172014-11-26 11:58:23 -05006077 if(context)
6078 {
6079 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006080
Nicolas Capensf160b172014-11-26 11:58:23 -05006081 if(!program)
6082 {
6083 return error(GL_INVALID_OPERATION);
6084 }
John Bauman66b8ab22014-05-06 15:57:45 -04006085
Nicolas Capensf160b172014-11-26 11:58:23 -05006086 if(!program->setUniformMatrix4fv(location, count, value))
6087 {
6088 return error(GL_INVALID_OPERATION);
6089 }
6090 }
John Bauman66b8ab22014-05-06 15:57:45 -04006091}
6092
6093void GL_APIENTRY glUseProgram(GLuint program)
6094{
Nicolas Capensf160b172014-11-26 11:58:23 -05006095 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006096
Nicolas Capensf160b172014-11-26 11:58:23 -05006097 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006098
Nicolas Capensf160b172014-11-26 11:58:23 -05006099 if(context)
6100 {
6101 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006102
Nicolas Capensf160b172014-11-26 11:58:23 -05006103 if(!programObject && program != 0)
6104 {
6105 if(context->getShader(program))
6106 {
6107 return error(GL_INVALID_OPERATION);
6108 }
6109 else
6110 {
6111 return error(GL_INVALID_VALUE);
6112 }
6113 }
John Bauman66b8ab22014-05-06 15:57:45 -04006114
Nicolas Capensf160b172014-11-26 11:58:23 -05006115 if(program != 0 && !programObject->isLinked())
6116 {
6117 return error(GL_INVALID_OPERATION);
6118 }
John Bauman66b8ab22014-05-06 15:57:45 -04006119
Nicolas Capensf160b172014-11-26 11:58:23 -05006120 context->useProgram(program);
6121 }
John Bauman66b8ab22014-05-06 15:57:45 -04006122}
6123
6124void GL_APIENTRY glValidateProgram(GLuint program)
6125{
Nicolas Capensf160b172014-11-26 11:58:23 -05006126 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006127
Nicolas Capensf160b172014-11-26 11:58:23 -05006128 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006129
Nicolas Capensf160b172014-11-26 11:58:23 -05006130 if(context)
6131 {
6132 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006133
Nicolas Capensf160b172014-11-26 11:58:23 -05006134 if(!programObject)
6135 {
6136 if(context->getShader(program))
6137 {
6138 return error(GL_INVALID_OPERATION);
6139 }
6140 else
6141 {
6142 return error(GL_INVALID_VALUE);
6143 }
6144 }
John Bauman66b8ab22014-05-06 15:57:45 -04006145
Nicolas Capensf160b172014-11-26 11:58:23 -05006146 programObject->validate();
6147 }
John Bauman66b8ab22014-05-06 15:57:45 -04006148}
6149
6150void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
6151{
Nicolas Capensf160b172014-11-26 11:58:23 -05006152 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
John Bauman66b8ab22014-05-06 15:57:45 -04006153
Nicolas Capensf160b172014-11-26 11:58:23 -05006154 if(index >= es2::MAX_VERTEX_ATTRIBS)
6155 {
6156 return error(GL_INVALID_VALUE);
6157 }
John Bauman66b8ab22014-05-06 15:57:45 -04006158
Nicolas Capensf160b172014-11-26 11:58:23 -05006159 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006160
Nicolas Capensf160b172014-11-26 11:58:23 -05006161 if(context)
6162 {
6163 GLfloat vals[4] = { x, 0, 0, 1 };
6164 context->setVertexAttrib(index, vals);
6165 }
John Bauman66b8ab22014-05-06 15:57:45 -04006166}
6167
6168void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
6169{
Nicolas Capensf160b172014-11-26 11:58:23 -05006170 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006171
Nicolas Capensf160b172014-11-26 11:58:23 -05006172 if(index >= es2::MAX_VERTEX_ATTRIBS)
6173 {
6174 return error(GL_INVALID_VALUE);
6175 }
John Bauman66b8ab22014-05-06 15:57:45 -04006176
Nicolas Capensf160b172014-11-26 11:58:23 -05006177 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006178
Nicolas Capensf160b172014-11-26 11:58:23 -05006179 if(context)
6180 {
6181 GLfloat vals[4] = { values[0], 0, 0, 1 };
6182 context->setVertexAttrib(index, vals);
6183 }
John Bauman66b8ab22014-05-06 15:57:45 -04006184}
6185
6186void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6187{
Nicolas Capensf160b172014-11-26 11:58:23 -05006188 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
John Bauman66b8ab22014-05-06 15:57:45 -04006189
Nicolas Capensf160b172014-11-26 11:58:23 -05006190 if(index >= es2::MAX_VERTEX_ATTRIBS)
6191 {
6192 return error(GL_INVALID_VALUE);
6193 }
John Bauman66b8ab22014-05-06 15:57:45 -04006194
Nicolas Capensf160b172014-11-26 11:58:23 -05006195 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006196
Nicolas Capensf160b172014-11-26 11:58:23 -05006197 if(context)
6198 {
6199 GLfloat vals[4] = { x, y, 0, 1 };
6200 context->setVertexAttrib(index, vals);
6201 }
John Bauman66b8ab22014-05-06 15:57:45 -04006202}
6203
6204void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
6205{
Nicolas Capensf160b172014-11-26 11:58:23 -05006206 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006207
Nicolas Capensf160b172014-11-26 11:58:23 -05006208 if(index >= es2::MAX_VERTEX_ATTRIBS)
6209 {
6210 return error(GL_INVALID_VALUE);
6211 }
John Bauman66b8ab22014-05-06 15:57:45 -04006212
Nicolas Capensf160b172014-11-26 11:58:23 -05006213 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006214
Nicolas Capensf160b172014-11-26 11:58:23 -05006215 if(context)
6216 {
6217 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6218 context->setVertexAttrib(index, vals);
6219 }
John Bauman66b8ab22014-05-06 15:57:45 -04006220}
6221
6222void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6223{
Nicolas Capensf160b172014-11-26 11:58:23 -05006224 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
John Bauman66b8ab22014-05-06 15:57:45 -04006225
Nicolas Capensf160b172014-11-26 11:58:23 -05006226 if(index >= es2::MAX_VERTEX_ATTRIBS)
6227 {
6228 return error(GL_INVALID_VALUE);
6229 }
John Bauman66b8ab22014-05-06 15:57:45 -04006230
Nicolas Capensf160b172014-11-26 11:58:23 -05006231 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006232
Nicolas Capensf160b172014-11-26 11:58:23 -05006233 if(context)
6234 {
6235 GLfloat vals[4] = { x, y, z, 1 };
6236 context->setVertexAttrib(index, vals);
6237 }
John Bauman66b8ab22014-05-06 15:57:45 -04006238}
6239
6240void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
6241{
Nicolas Capensf160b172014-11-26 11:58:23 -05006242 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006243
Nicolas Capensf160b172014-11-26 11:58:23 -05006244 if(index >= es2::MAX_VERTEX_ATTRIBS)
6245 {
6246 return error(GL_INVALID_VALUE);
6247 }
John Bauman66b8ab22014-05-06 15:57:45 -04006248
Nicolas Capensf160b172014-11-26 11:58:23 -05006249 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006250
Nicolas Capensf160b172014-11-26 11:58:23 -05006251 if(context)
6252 {
6253 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6254 context->setVertexAttrib(index, vals);
6255 }
John Bauman66b8ab22014-05-06 15:57:45 -04006256}
6257
6258void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6259{
Nicolas Capensf160b172014-11-26 11:58:23 -05006260 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 -04006261
Nicolas Capensf160b172014-11-26 11:58:23 -05006262 if(index >= es2::MAX_VERTEX_ATTRIBS)
6263 {
6264 return error(GL_INVALID_VALUE);
6265 }
John Bauman66b8ab22014-05-06 15:57:45 -04006266
Nicolas Capensf160b172014-11-26 11:58:23 -05006267 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006268
Nicolas Capensf160b172014-11-26 11:58:23 -05006269 if(context)
6270 {
6271 GLfloat vals[4] = { x, y, z, w };
6272 context->setVertexAttrib(index, vals);
6273 }
John Bauman66b8ab22014-05-06 15:57:45 -04006274}
6275
6276void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
6277{
Nicolas Capensf160b172014-11-26 11:58:23 -05006278 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006279
Nicolas Capensf160b172014-11-26 11:58:23 -05006280 if(index >= es2::MAX_VERTEX_ATTRIBS)
6281 {
6282 return error(GL_INVALID_VALUE);
6283 }
John Bauman66b8ab22014-05-06 15:57:45 -04006284
Nicolas Capensf160b172014-11-26 11:58:23 -05006285 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006286
Nicolas Capensf160b172014-11-26 11:58:23 -05006287 if(context)
6288 {
6289 context->setVertexAttrib(index, values);
6290 }
John Bauman66b8ab22014-05-06 15:57:45 -04006291}
6292
6293void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
6294{
Nicolas Capensf160b172014-11-26 11:58:23 -05006295 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
6296 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
6297 index, size, type, normalized, stride, ptr);
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 if(size < 1 || size > 4)
6305 {
6306 return error(GL_INVALID_VALUE);
6307 }
John Bauman66b8ab22014-05-06 15:57:45 -04006308
Alexis Hetued306182015-04-02 12:02:28 -04006309 egl::GLint clientVersion = egl::getClientVersion();
6310
Nicolas Capensf160b172014-11-26 11:58:23 -05006311 switch(type)
6312 {
6313 case GL_BYTE:
6314 case GL_UNSIGNED_BYTE:
6315 case GL_SHORT:
6316 case GL_UNSIGNED_SHORT:
6317 case GL_FIXED:
6318 case GL_FLOAT:
6319 break;
Alexis Hetued306182015-04-02 12:02:28 -04006320 case GL_INT_2_10_10_10_REV:
6321 case GL_UNSIGNED_INT_2_10_10_10_REV:
6322 if(clientVersion >= 3)
6323 {
6324 if(size != 4)
6325 {
6326 return error(GL_INVALID_OPERATION);
6327 }
6328 break;
6329 }
6330 else return error(GL_INVALID_ENUM);
6331 case GL_INT:
6332 case GL_UNSIGNED_INT:
6333 case GL_HALF_FLOAT:
6334 if(clientVersion >= 3)
6335 {
6336 break;
6337 }
6338 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05006339 default:
6340 return error(GL_INVALID_ENUM);
6341 }
John Bauman66b8ab22014-05-06 15:57:45 -04006342
Nicolas Capensf160b172014-11-26 11:58:23 -05006343 if(stride < 0)
6344 {
6345 return error(GL_INVALID_VALUE);
6346 }
John Bauman66b8ab22014-05-06 15:57:45 -04006347
Nicolas Capensf160b172014-11-26 11:58:23 -05006348 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006349
Nicolas Capensf160b172014-11-26 11:58:23 -05006350 if(context)
6351 {
6352 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6353 }
John Bauman66b8ab22014-05-06 15:57:45 -04006354}
6355
6356void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6357{
Nicolas Capensf160b172014-11-26 11:58:23 -05006358 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04006359
Nicolas Capensf160b172014-11-26 11:58:23 -05006360 if(width < 0 || height < 0)
6361 {
6362 return error(GL_INVALID_VALUE);
6363 }
John Bauman66b8ab22014-05-06 15:57:45 -04006364
Nicolas Capensf160b172014-11-26 11:58:23 -05006365 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006366
Nicolas Capensf160b172014-11-26 11:58:23 -05006367 if(context)
6368 {
6369 context->setViewportParams(x, y, width, height);
6370 }
John Bauman66b8ab22014-05-06 15:57:45 -04006371}
6372
Alexis Hetue9233fb2015-02-11 10:31:58 -05006373void GL_APIENTRY glBlitFramebufferNV(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 -04006374{
Nicolas Capensf160b172014-11-26 11:58:23 -05006375 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6376 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6377 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6378 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
John Bauman66b8ab22014-05-06 15:57:45 -04006379
Nicolas Capensf160b172014-11-26 11:58:23 -05006380 switch(filter)
6381 {
6382 case GL_NEAREST:
6383 break;
6384 default:
6385 return error(GL_INVALID_ENUM);
6386 }
John Bauman66b8ab22014-05-06 15:57:45 -04006387
Nicolas Capensf160b172014-11-26 11:58:23 -05006388 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6389 {
6390 return error(GL_INVALID_VALUE);
6391 }
John Bauman66b8ab22014-05-06 15:57:45 -04006392
Nicolas Capensf160b172014-11-26 11:58:23 -05006393 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006394
Nicolas Capensf160b172014-11-26 11:58:23 -05006395 if(context)
6396 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006397 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capensf160b172014-11-26 11:58:23 -05006398 {
6399 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6400 return error(GL_INVALID_OPERATION);
6401 }
John Bauman66b8ab22014-05-06 15:57:45 -04006402
Nicolas Capensf160b172014-11-26 11:58:23 -05006403 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6404 }
John Bauman66b8ab22014-05-06 15:57:45 -04006405}
6406
Alexis Hetue9233fb2015-02-11 10:31:58 -05006407void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6408 GLbitfield mask, GLenum filter)
6409{
6410 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6411 {
6412 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6413 return error(GL_INVALID_OPERATION);
6414 }
6415
6416 glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6417}
6418
John Bauman66b8ab22014-05-06 15:57:45 -04006419void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Nicolas Capensf160b172014-11-26 11:58:23 -05006420 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04006421{
Nicolas Capensf160b172014-11-26 11:58:23 -05006422 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6423 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
6424 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
6425 target, level, internalformat, width, height, depth, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04006426
Alexis Hetub027aa92015-01-19 15:56:12 -05006427 switch(target)
6428 {
6429 case GL_TEXTURE_3D_OES:
6430 switch(format)
6431 {
6432 case GL_DEPTH_COMPONENT:
6433 case GL_DEPTH_STENCIL_OES:
6434 return error(GL_INVALID_OPERATION);
6435 default:
6436 break;
6437 }
6438 break;
6439 default:
6440 return error(GL_INVALID_ENUM);
6441 }
6442
6443 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6444 {
6445 return error(GL_INVALID_ENUM);
6446 }
6447
6448 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6449 {
6450 return error(GL_INVALID_VALUE);
6451 }
6452
6453 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6454 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6455 {
6456 return error(GL_INVALID_VALUE);
6457 }
6458
6459 if(border != 0)
6460 {
6461 return error(GL_INVALID_VALUE);
6462 }
6463
6464 if(!ValidateInternalFormat3D(internalformat, format, type))
6465 {
6466 return error(GL_INVALID_OPERATION);
6467 }
6468
6469 es2::Context *context = es2::getContext();
6470
6471 if(context)
6472 {
6473 es2::Texture3D *texture = context->getTexture3D();
6474
6475 if(!texture)
6476 {
6477 return error(GL_INVALID_OPERATION);
6478 }
6479
6480 texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackAlignment(), pixels);
6481 }
John Bauman66b8ab22014-05-06 15:57:45 -04006482}
6483
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006484void GL_APIENTRY glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
6485{
Alexis Hetub027aa92015-01-19 15:56:12 -05006486 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6487 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6488 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006489 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
6490
Alexis Hetub027aa92015-01-19 15:56:12 -05006491 switch(target)
6492 {
6493 case GL_TEXTURE_3D_OES:
6494 break;
6495 default:
6496 return error(GL_INVALID_ENUM);
6497 }
6498
6499 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6500 {
6501 return error(GL_INVALID_ENUM);
6502 }
6503
6504 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6505 {
6506 return error(GL_INVALID_VALUE);
6507 }
6508
6509 if((width < 0) || (height < 0) || (depth < 0))
6510 {
6511 return error(GL_INVALID_VALUE);
6512 }
6513
6514 es2::Context *context = es2::getContext();
6515
6516 if(context)
6517 {
6518 es2::Texture3D *texture = context->getTexture3D();
6519
6520 if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))
6521 {
6522 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackAlignment(), pixels);
6523 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006524 }
6525}
6526
6527void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
6528{
Alexis Hetub027aa92015-01-19 15:56:12 -05006529 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6530 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006531 target, level, xoffset, yoffset, zoffset, x, y, width, height);
6532
Alexis Hetub027aa92015-01-19 15:56:12 -05006533 switch(target)
6534 {
6535 case GL_TEXTURE_3D_OES:
6536 break;
6537 default:
6538 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006539 }
6540
Alexis Hetub027aa92015-01-19 15:56:12 -05006541 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6542 {
6543 return error(GL_INVALID_VALUE);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006544 }
6545
Alexis Hetub027aa92015-01-19 15:56:12 -05006546 es2::Context *context = es2::getContext();
6547
6548 if(context)
6549 {
6550 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6551
6552 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
6553 {
6554 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6555 }
6556
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006557 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Alexis Hetub027aa92015-01-19 15:56:12 -05006558 {
6559 return error(GL_INVALID_OPERATION);
6560 }
6561
6562 es2::Renderbuffer *source = framebuffer->getColorbuffer();
6563 GLenum colorbufferFormat = source->getFormat();
6564 es2::Texture3D *texture = context->getTexture3D();
6565
6566 if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))
6567 {
6568 return;
6569 }
6570
6571 GLenum textureFormat = texture->getFormat(target, level);
6572
6573 if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
6574 {
6575 return;
6576 }
6577
6578 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006579 }
6580}
6581
6582void GL_APIENTRY glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
6583{
Alexis Hetub027aa92015-01-19 15:56:12 -05006584 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
6585 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
6586 target, level, internalformat, width, height, depth, border, imageSize, data);
6587
6588 switch(target)
6589 {
6590 case GL_TEXTURE_3D_OES:
6591 break;
6592 default:
6593 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006594 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006595
6596 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6597 {
6598 return error(GL_INVALID_VALUE);
6599 }
6600
6601 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6602 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6603 {
6604 return error(GL_INVALID_VALUE);
6605 }
6606
6607 switch(internalformat)
6608 {
6609 case GL_ETC1_RGB8_OES:
6610 break;
6611 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6612 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6613 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6614 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6615 if(!S3TC_SUPPORT)
6616 {
6617 return error(GL_INVALID_ENUM);
6618 }
6619 break;
6620 case GL_DEPTH_COMPONENT:
6621 case GL_DEPTH_COMPONENT16:
6622 case GL_DEPTH_COMPONENT32_OES:
6623 case GL_DEPTH_STENCIL_OES:
6624 case GL_DEPTH24_STENCIL8_OES:
6625 return error(GL_INVALID_OPERATION);
6626 default:
6627 return error(GL_INVALID_ENUM);
6628 }
6629
6630 if(imageSize != es2::ComputeCompressedSize(width, height, internalformat) * depth)
6631 {
6632 return error(GL_INVALID_VALUE);
6633 }
6634
6635 es2::Context *context = es2::getContext();
6636
6637 if(context)
6638 {
6639 es2::Texture3D *texture = context->getTexture3D();
6640
6641 if(!texture)
6642 {
6643 return error(GL_INVALID_OPERATION);
6644 }
6645
6646 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006647 }
6648}
6649
6650void GL_APIENTRY glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
6651{
Alexis Hetub027aa92015-01-19 15:56:12 -05006652 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6653 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6654 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = 0x%0.8p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006655 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6656
Alexis Hetub027aa92015-01-19 15:56:12 -05006657 switch(target)
6658 {
6659 case GL_TEXTURE_3D_OES:
6660 break;
6661 default:
6662 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006663 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006664
6665 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6666 {
6667 return error(GL_INVALID_VALUE);
6668 }
6669
6670 switch(format)
6671 {
6672 case GL_ETC1_RGB8_OES:
6673 break;
6674 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6675 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6676 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6677 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6678 if(!S3TC_SUPPORT)
6679 {
6680 return error(GL_INVALID_ENUM);
6681 }
6682 break;
6683 default:
6684 return error(GL_INVALID_ENUM);
6685 }
6686
6687 if(width == 0 || height == 0 || depth == 0 || data == NULL)
6688 {
6689 return;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006690 }
6691
Alexis Hetub027aa92015-01-19 15:56:12 -05006692 es2::Context *context = es2::getContext();
6693
6694 if(context)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006695 {
Alexis Hetub027aa92015-01-19 15:56:12 -05006696 es2::Texture3D *texture = context->getTexture3D();
6697
6698 if(!texture)
6699 {
6700 return error(GL_INVALID_OPERATION);
6701 }
6702
6703 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6704 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006705}
6706
6707void GL_APIENTRY glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
6708{
Alexis Hetub027aa92015-01-19 15:56:12 -05006709 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6710 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6711
6712 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
6713 {
6714 return error(GL_INVALID_ENUM);
6715 }
6716
6717 switch(attachment)
6718 {
6719 case GL_COLOR_ATTACHMENT0:
6720 case GL_DEPTH_ATTACHMENT:
6721 case GL_STENCIL_ATTACHMENT:
6722 break;
6723 default:
6724 return error(GL_INVALID_ENUM);
6725 }
6726
6727 es2::Context *context = es2::getContext();
6728
6729 if(context)
6730 {
6731 if(texture == 0)
6732 {
6733 textarget = GL_NONE;
6734 }
6735 else
6736 {
6737 es2::Texture *tex = context->getTexture(texture);
6738
6739 if(tex == NULL)
6740 {
6741 return error(GL_INVALID_OPERATION);
6742 }
6743
6744 if(tex->isCompressed(textarget, level))
6745 {
6746 return error(GL_INVALID_OPERATION);
6747 }
6748
6749 switch(textarget)
6750 {
6751 case GL_TEXTURE_3D_OES:
6752 if(tex->getTarget() != GL_TEXTURE_3D_OES)
6753 {
6754 return error(GL_INVALID_OPERATION);
6755 }
6756 break;
6757 default:
6758 return error(GL_INVALID_ENUM);
6759 }
6760
6761 if(level != 0)
6762 {
6763 return error(GL_INVALID_VALUE);
6764 }
6765 }
6766
6767 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006768 GLuint framebufferName = 0;
Alexis Hetub027aa92015-01-19 15:56:12 -05006769 if(target == GL_READ_FRAMEBUFFER_ANGLE)
6770 {
6771 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006772 framebufferName = context->getReadFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006773 }
6774 else
6775 {
6776 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006777 framebufferName = context->getDrawFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006778 }
6779
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006780 if(framebufferName == 0 || !framebuffer)
Alexis Hetub027aa92015-01-19 15:56:12 -05006781 {
6782 return error(GL_INVALID_OPERATION);
6783 }
6784
6785 switch(attachment)
6786 {
6787 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
6788 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
6789 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6790 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006791 }
6792}
Alexis Hetub027aa92015-01-19 15:56:12 -05006793
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006794void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
6795{
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006796 if(egl::getClientVersion() == 1)
6797 {
Nicolas Capensa2308052015-04-15 16:50:21 -04006798 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006799 }
6800
Nicolas Capensf160b172014-11-26 11:58:23 -05006801 TRACE("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006802
Nicolas Capensf160b172014-11-26 11:58:23 -05006803 switch(target)
6804 {
6805 case GL_TEXTURE_2D:
6806 case GL_TEXTURE_EXTERNAL_OES:
6807 break;
6808 default:
6809 return error(GL_INVALID_ENUM);
6810 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006811
Nicolas Capensf160b172014-11-26 11:58:23 -05006812 if(!image)
6813 {
6814 return error(GL_INVALID_OPERATION);
6815 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006816
Nicolas Capensf160b172014-11-26 11:58:23 -05006817 es2::Context *context = es2::getContext();
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006818
Nicolas Capensf160b172014-11-26 11:58:23 -05006819 if(context)
6820 {
6821 es2::Texture2D *texture = 0;
Nicolas Capens08e90f02014-11-21 12:49:12 -05006822
Nicolas Capensf160b172014-11-26 11:58:23 -05006823 switch(target)
6824 {
6825 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
6826 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
6827 default: UNREACHABLE();
6828 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006829
Nicolas Capensf160b172014-11-26 11:58:23 -05006830 if(!texture)
6831 {
6832 return error(GL_INVALID_OPERATION);
6833 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006834
Nicolas Capensf160b172014-11-26 11:58:23 -05006835 egl::Image *glImage = static_cast<egl::Image*>(image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006836
Nicolas Capensf160b172014-11-26 11:58:23 -05006837 texture->setImage(glImage);
6838 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006839}
6840
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006841void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
6842{
6843 TRACE("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
6844
6845 UNIMPLEMENTED();
6846}
6847
Nicolas Capensa2308052015-04-15 16:50:21 -04006848__eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
John Bauman66b8ab22014-05-06 15:57:45 -04006849{
Nicolas Capensf160b172014-11-26 11:58:23 -05006850 struct Extension
6851 {
6852 const char *name;
6853 __eglMustCastToProperFunctionPointerType address;
6854 };
John Bauman66b8ab22014-05-06 15:57:45 -04006855
Nicolas Capensf160b172014-11-26 11:58:23 -05006856 static const Extension glExtensions[] =
6857 {
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006858 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6859
Nicolas Capensf160b172014-11-26 11:58:23 -05006860 EXTENSION(glTexImage3DOES),
6861 EXTENSION(glBlitFramebufferANGLE),
Alexis Hetue9233fb2015-02-11 10:31:58 -05006862 EXTENSION(glBlitFramebufferNV),
Nicolas Capensf160b172014-11-26 11:58:23 -05006863 EXTENSION(glRenderbufferStorageMultisampleANGLE),
6864 EXTENSION(glDeleteFencesNV),
6865 EXTENSION(glGenFencesNV),
6866 EXTENSION(glIsFenceNV),
6867 EXTENSION(glTestFenceNV),
6868 EXTENSION(glGetFenceivNV),
6869 EXTENSION(glFinishFenceNV),
6870 EXTENSION(glSetFenceNV),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006871 EXTENSION(glGetGraphicsResetStatusEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05006872 EXTENSION(glReadnPixelsEXT),
6873 EXTENSION(glGetnUniformfvEXT),
6874 EXTENSION(glGetnUniformivEXT),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006875 EXTENSION(glGenQueriesEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05006876 EXTENSION(glDeleteQueriesEXT),
6877 EXTENSION(glIsQueryEXT),
6878 EXTENSION(glBeginQueryEXT),
6879 EXTENSION(glEndQueryEXT),
6880 EXTENSION(glGetQueryivEXT),
6881 EXTENSION(glGetQueryObjectuivEXT),
6882 EXTENSION(glEGLImageTargetTexture2DOES),
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006883 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
Alexis Hetue8af6d12015-04-17 16:58:45 -04006884 EXTENSION(glDrawElementsInstancedEXT),
6885 EXTENSION(glDrawArraysInstancedEXT),
6886 EXTENSION(glVertexAttribDivisorEXT),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006887
6888 #undef EXTENSION
Nicolas Capensf160b172014-11-26 11:58:23 -05006889 };
John Bauman66b8ab22014-05-06 15:57:45 -04006890
Nicolas Capensf160b172014-11-26 11:58:23 -05006891 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6892 {
6893 if(strcmp(procname, glExtensions[ext].name) == 0)
6894 {
6895 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6896 }
6897 }
John Bauman66b8ab22014-05-06 15:57:45 -04006898
Nicolas Capensf160b172014-11-26 11:58:23 -05006899 return NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04006900}
6901
John Baumand4ae8632014-05-06 16:18:33 -04006902void GL_APIENTRY Register(const char *licenseKey)
6903{
6904 RegisterLicenseKey(licenseKey);
6905}
6906
John Bauman66b8ab22014-05-06 15:57:45 -04006907}