blob: 34a096fc58e4e3d8885bf7ecfe63a97f6d108170 [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 {
Alexis Hetubcac6ff2015-04-22 08:29:22 -0400464 context->bindTransformFeedbackBuffer(buffer);
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400465 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 {
Alexis Hetubcac6ff2015-04-22 08:29:22 -04001780 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1781 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1782 {
1783 return error(GL_INVALID_OPERATION);
1784 }
1785
Nicolas Capensf160b172014-11-26 11:58:23 -05001786 context->drawArrays(mode, first, count);
1787 }
John Bauman66b8ab22014-05-06 15:57:45 -04001788}
1789
1790void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
1791{
Nicolas Capensf160b172014-11-26 11:58:23 -05001792 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
1793 mode, count, type, indices);
John Bauman66b8ab22014-05-06 15:57:45 -04001794
Alexis Hetued306182015-04-02 12:02:28 -04001795 switch(mode)
1796 {
1797 case GL_POINTS:
1798 case GL_LINES:
1799 case GL_LINE_LOOP:
1800 case GL_LINE_STRIP:
1801 case GL_TRIANGLES:
1802 case GL_TRIANGLE_FAN:
1803 case GL_TRIANGLE_STRIP:
1804 break;
1805 default:
1806 return error(GL_INVALID_ENUM);
1807 }
1808
Nicolas Capensf160b172014-11-26 11:58:23 -05001809 if(count < 0)
1810 {
1811 return error(GL_INVALID_VALUE);
1812 }
John Bauman66b8ab22014-05-06 15:57:45 -04001813
Nicolas Capensf160b172014-11-26 11:58:23 -05001814 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001815
Nicolas Capensf160b172014-11-26 11:58:23 -05001816 if(context)
1817 {
Alexis Hetubcac6ff2015-04-22 08:29:22 -04001818 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1819 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1820 {
1821 return error(GL_INVALID_OPERATION);
1822 }
1823
Nicolas Capensf160b172014-11-26 11:58:23 -05001824 switch(type)
1825 {
1826 case GL_UNSIGNED_BYTE:
1827 case GL_UNSIGNED_SHORT:
1828 case GL_UNSIGNED_INT:
1829 break;
1830 default:
1831 return error(GL_INVALID_ENUM);
1832 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05001833
Nicolas Capens22d07662015-04-25 11:34:50 -07001834 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices);
Nicolas Capensf160b172014-11-26 11:58:23 -05001835 }
John Bauman66b8ab22014-05-06 15:57:45 -04001836}
1837
Alexis Hetue8af6d12015-04-17 16:58:45 -04001838void GL_APIENTRY glDrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1839{
1840 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1841 mode, first, count, instanceCount);
1842
1843 switch(mode)
1844 {
1845 case GL_POINTS:
1846 case GL_LINES:
1847 case GL_LINE_LOOP:
1848 case GL_LINE_STRIP:
1849 case GL_TRIANGLES:
1850 case GL_TRIANGLE_FAN:
1851 case GL_TRIANGLE_STRIP:
1852 break;
1853 default:
1854 return error(GL_INVALID_ENUM);
1855 }
1856
1857 if(count < 0 || instanceCount < 0)
1858 {
1859 return error(GL_INVALID_VALUE);
1860 }
1861
1862 es2::Context *context = es2::getContext();
1863
1864 if(context)
1865 {
1866 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1867 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1868 {
1869 return error(GL_INVALID_OPERATION);
1870 }
1871
1872 context->drawArrays(mode, first, count, instanceCount);
1873 }
1874}
1875
1876void GL_APIENTRY glDrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
1877{
1878 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = 0x%0.8p, GLsizei instanceCount = %d)",
1879 mode, count, type, indices, instanceCount);
1880
1881 switch(mode)
1882 {
1883 case GL_POINTS:
1884 case GL_LINES:
1885 case GL_LINE_LOOP:
1886 case GL_LINE_STRIP:
1887 case GL_TRIANGLES:
1888 case GL_TRIANGLE_FAN:
1889 case GL_TRIANGLE_STRIP:
1890 break;
1891 default:
1892 return error(GL_INVALID_ENUM);
1893 }
1894
1895 switch(type)
1896 {
1897 case GL_UNSIGNED_BYTE:
1898 case GL_UNSIGNED_SHORT:
1899 case GL_UNSIGNED_INT:
1900 break;
1901 default:
1902 return error(GL_INVALID_ENUM);
1903 }
1904
1905 if(count < 0 || instanceCount < 0)
1906 {
1907 return error(GL_INVALID_VALUE);
1908 }
1909
1910 es2::Context *context = es2::getContext();
1911
1912 if(context)
1913 {
1914 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1915 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1916 {
1917 return error(GL_INVALID_OPERATION);
1918 }
1919
Nicolas Capens22d07662015-04-25 11:34:50 -07001920 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
Alexis Hetue8af6d12015-04-17 16:58:45 -04001921 }
1922}
1923
1924void GL_APIENTRY glVertexAttribDivisorEXT(GLuint index, GLuint divisor)
1925{
1926 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1927
1928 es2::Context *context = es2::getContext();
1929
1930 if(context)
1931 {
1932 if(index >= es2::MAX_VERTEX_ATTRIBS)
1933 {
1934 return error(GL_INVALID_VALUE);
1935 }
1936
1937 context->setVertexAttribDivisor(index, divisor);
1938 }
1939}
1940
John Bauman66b8ab22014-05-06 15:57:45 -04001941void GL_APIENTRY glEnable(GLenum cap)
1942{
Nicolas Capensf160b172014-11-26 11:58:23 -05001943 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04001944
Nicolas Capensf160b172014-11-26 11:58:23 -05001945 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001946
Nicolas Capensf160b172014-11-26 11:58:23 -05001947 if(context)
1948 {
1949 switch(cap)
1950 {
1951 case GL_CULL_FACE: context->setCullFace(true); break;
1952 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1953 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1954 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1955 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1956 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1957 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1958 case GL_BLEND: context->setBlend(true); break;
1959 case GL_DITHER: context->setDither(true); break;
Alexis Hetufceb1832015-03-10 16:42:04 -04001960 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndex(true); break;
1961 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscard(true); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05001962 default:
1963 return error(GL_INVALID_ENUM);
1964 }
1965 }
John Bauman66b8ab22014-05-06 15:57:45 -04001966}
1967
1968void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
1969{
Nicolas Capensf160b172014-11-26 11:58:23 -05001970 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04001971
Nicolas Capensf160b172014-11-26 11:58:23 -05001972 if(index >= es2::MAX_VERTEX_ATTRIBS)
1973 {
1974 return error(GL_INVALID_VALUE);
1975 }
John Bauman66b8ab22014-05-06 15:57:45 -04001976
Nicolas Capensf160b172014-11-26 11:58:23 -05001977 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001978
Nicolas Capensf160b172014-11-26 11:58:23 -05001979 if(context)
1980 {
1981 context->setEnableVertexAttribArray(index, true);
1982 }
John Bauman66b8ab22014-05-06 15:57:45 -04001983}
1984
1985void GL_APIENTRY glEndQueryEXT(GLenum target)
1986{
Nicolas Capensf160b172014-11-26 11:58:23 -05001987 TRACE("GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04001988
Nicolas Capensf160b172014-11-26 11:58:23 -05001989 switch(target)
1990 {
1991 case GL_ANY_SAMPLES_PASSED_EXT:
1992 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1993 break;
1994 default:
1995 return error(GL_INVALID_ENUM);
1996 }
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 context->endQuery(target);
2003 }
John Bauman66b8ab22014-05-06 15:57:45 -04002004}
2005
2006void GL_APIENTRY glFinishFenceNV(GLuint fence)
2007{
Nicolas Capensf160b172014-11-26 11:58:23 -05002008 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002009
Nicolas Capensf160b172014-11-26 11:58:23 -05002010 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002011
Nicolas Capensf160b172014-11-26 11:58:23 -05002012 if(context)
2013 {
2014 es2::Fence* fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002015
Nicolas Capensf160b172014-11-26 11:58:23 -05002016 if(fenceObject == NULL)
2017 {
2018 return error(GL_INVALID_OPERATION);
2019 }
John Bauman66b8ab22014-05-06 15:57:45 -04002020
Nicolas Capensf160b172014-11-26 11:58:23 -05002021 fenceObject->finishFence();
2022 }
John Bauman66b8ab22014-05-06 15:57:45 -04002023}
2024
2025void GL_APIENTRY glFinish(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->finish();
2034 }
John Bauman66b8ab22014-05-06 15:57:45 -04002035}
2036
2037void GL_APIENTRY glFlush(void)
2038{
Nicolas Capensf160b172014-11-26 11:58:23 -05002039 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002040
Nicolas Capensf160b172014-11-26 11:58:23 -05002041 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002042
Nicolas Capensf160b172014-11-26 11:58:23 -05002043 if(context)
2044 {
2045 context->flush();
2046 }
John Bauman66b8ab22014-05-06 15:57:45 -04002047}
2048
2049void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2050{
Nicolas Capensf160b172014-11-26 11:58:23 -05002051 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
2052 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04002053
Nicolas Capensf160b172014-11-26 11:58:23 -05002054 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
2055 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
2056 {
2057 return error(GL_INVALID_ENUM);
2058 }
John Bauman66b8ab22014-05-06 15:57:45 -04002059
Nicolas Capensf160b172014-11-26 11:58:23 -05002060 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002061
Nicolas Capensf160b172014-11-26 11:58:23 -05002062 if(context)
2063 {
2064 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002065 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002066 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2067 {
2068 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002069 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002070 }
2071 else
2072 {
2073 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002074 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002075 }
John Bauman66b8ab22014-05-06 15:57:45 -04002076
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002077 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capensf160b172014-11-26 11:58:23 -05002078 {
2079 return error(GL_INVALID_OPERATION);
2080 }
John Bauman66b8ab22014-05-06 15:57:45 -04002081
Nicolas Capensf160b172014-11-26 11:58:23 -05002082 switch(attachment)
2083 {
2084 case GL_COLOR_ATTACHMENT0:
2085 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2086 break;
2087 case GL_DEPTH_ATTACHMENT:
2088 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2089 break;
2090 case GL_STENCIL_ATTACHMENT:
2091 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2092 break;
2093 default:
2094 return error(GL_INVALID_ENUM);
2095 }
2096 }
John Bauman66b8ab22014-05-06 15:57:45 -04002097}
2098
2099void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2100{
Nicolas Capensf160b172014-11-26 11:58:23 -05002101 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
2102 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
John Bauman66b8ab22014-05-06 15:57:45 -04002103
Nicolas Capensf160b172014-11-26 11:58:23 -05002104 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2105 {
2106 return error(GL_INVALID_ENUM);
2107 }
John Bauman66b8ab22014-05-06 15:57:45 -04002108
Nicolas Capensf160b172014-11-26 11:58:23 -05002109 switch(attachment)
2110 {
2111 case GL_COLOR_ATTACHMENT0:
2112 case GL_DEPTH_ATTACHMENT:
2113 case GL_STENCIL_ATTACHMENT:
2114 break;
2115 default:
2116 return error(GL_INVALID_ENUM);
2117 }
John Bauman66b8ab22014-05-06 15:57:45 -04002118
Nicolas Capensf160b172014-11-26 11:58:23 -05002119 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002120
Nicolas Capensf160b172014-11-26 11:58:23 -05002121 if(context)
2122 {
2123 if(texture == 0)
2124 {
2125 textarget = GL_NONE;
2126 }
2127 else
2128 {
2129 es2::Texture *tex = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04002130
Nicolas Capensf160b172014-11-26 11:58:23 -05002131 if(tex == NULL)
2132 {
2133 return error(GL_INVALID_OPERATION);
2134 }
John Bauman66b8ab22014-05-06 15:57:45 -04002135
Nicolas Capensf160b172014-11-26 11:58:23 -05002136 if(tex->isCompressed(textarget, level))
2137 {
2138 return error(GL_INVALID_OPERATION);
2139 }
John Bauman66b8ab22014-05-06 15:57:45 -04002140
Nicolas Capensf160b172014-11-26 11:58:23 -05002141 switch(textarget)
2142 {
2143 case GL_TEXTURE_2D:
2144 if(tex->getTarget() != GL_TEXTURE_2D)
2145 {
2146 return error(GL_INVALID_OPERATION);
2147 }
2148 break;
2149 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2150 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2151 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2152 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2153 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2154 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2155 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2156 {
2157 return error(GL_INVALID_OPERATION);
2158 }
2159 break;
2160 default:
2161 return error(GL_INVALID_ENUM);
2162 }
John Bauman66b8ab22014-05-06 15:57:45 -04002163
Nicolas Capensf160b172014-11-26 11:58:23 -05002164 if(level != 0)
2165 {
2166 return error(GL_INVALID_VALUE);
2167 }
2168 }
John Bauman66b8ab22014-05-06 15:57:45 -04002169
Nicolas Capensf160b172014-11-26 11:58:23 -05002170 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002171 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002172 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2173 {
2174 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002175 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002176 }
2177 else
2178 {
2179 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002180 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002181 }
John Bauman66b8ab22014-05-06 15:57:45 -04002182
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002183 if(framebufferName == 0 || !framebuffer)
Nicolas Capensf160b172014-11-26 11:58:23 -05002184 {
2185 return error(GL_INVALID_OPERATION);
2186 }
John Bauman66b8ab22014-05-06 15:57:45 -04002187
Nicolas Capensf160b172014-11-26 11:58:23 -05002188 switch(attachment)
2189 {
2190 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2191 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2192 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2193 }
2194 }
John Bauman66b8ab22014-05-06 15:57:45 -04002195}
2196
2197void GL_APIENTRY glFrontFace(GLenum mode)
2198{
Nicolas Capensf160b172014-11-26 11:58:23 -05002199 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04002200
Nicolas Capensf160b172014-11-26 11:58:23 -05002201 switch(mode)
2202 {
2203 case GL_CW:
2204 case GL_CCW:
2205 {
2206 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002207
Nicolas Capensf160b172014-11-26 11:58:23 -05002208 if(context)
2209 {
2210 context->setFrontFace(mode);
2211 }
2212 }
2213 break;
2214 default:
2215 return error(GL_INVALID_ENUM);
2216 }
John Bauman66b8ab22014-05-06 15:57:45 -04002217}
2218
2219void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
2220{
Nicolas Capensf160b172014-11-26 11:58:23 -05002221 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002222
Nicolas Capensf160b172014-11-26 11:58:23 -05002223 if(n < 0)
2224 {
2225 return error(GL_INVALID_VALUE);
2226 }
John Bauman66b8ab22014-05-06 15:57:45 -04002227
Nicolas Capensf160b172014-11-26 11:58:23 -05002228 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002229
Nicolas Capensf160b172014-11-26 11:58:23 -05002230 if(context)
2231 {
2232 for(int i = 0; i < n; i++)
2233 {
2234 buffers[i] = context->createBuffer();
2235 }
2236 }
John Bauman66b8ab22014-05-06 15:57:45 -04002237}
2238
2239void GL_APIENTRY glGenerateMipmap(GLenum target)
2240{
Nicolas Capensf160b172014-11-26 11:58:23 -05002241 TRACE("(GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04002242
Nicolas Capensf160b172014-11-26 11:58:23 -05002243 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002244
Nicolas Capensf160b172014-11-26 11:58:23 -05002245 if(context)
2246 {
Alexis Hetued306182015-04-02 12:02:28 -04002247 es2::Texture *texture = nullptr;
2248
2249 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04002250
Nicolas Capensf160b172014-11-26 11:58:23 -05002251 switch(target)
2252 {
2253 case GL_TEXTURE_2D:
2254 texture = context->getTexture2D();
2255 break;
2256 case GL_TEXTURE_CUBE_MAP:
2257 texture = context->getTextureCubeMap();
2258 break;
Alexis Hetued306182015-04-02 12:02:28 -04002259 case GL_TEXTURE_2D_ARRAY:
2260 if(clientVersion < 3)
2261 {
2262 return error(GL_INVALID_ENUM);
2263 }
2264 else
2265 {
2266 UNIMPLEMENTED();
2267 texture = context->getTexture3D();
2268 break;
2269 }
2270 case GL_TEXTURE_3D_OES:
2271 texture = context->getTexture3D();
2272 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05002273 default:
2274 return error(GL_INVALID_ENUM);
2275 }
John Bauman66b8ab22014-05-06 15:57:45 -04002276
Nicolas Capensf160b172014-11-26 11:58:23 -05002277 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2278 {
2279 return error(GL_INVALID_OPERATION);
2280 }
John Bauman66b8ab22014-05-06 15:57:45 -04002281
Nicolas Capensf160b172014-11-26 11:58:23 -05002282 texture->generateMipmaps();
2283 }
John Bauman66b8ab22014-05-06 15:57:45 -04002284}
2285
2286void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
2287{
Nicolas Capensf160b172014-11-26 11:58:23 -05002288 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04002289
Nicolas Capensf160b172014-11-26 11:58:23 -05002290 if(n < 0)
2291 {
2292 return error(GL_INVALID_VALUE);
2293 }
John Bauman66b8ab22014-05-06 15:57:45 -04002294
Nicolas Capensf160b172014-11-26 11:58:23 -05002295 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002296
Nicolas Capensf160b172014-11-26 11:58:23 -05002297 if(context)
2298 {
2299 for(int i = 0; i < n; i++)
2300 {
2301 fences[i] = context->createFence();
2302 }
2303 }
John Bauman66b8ab22014-05-06 15:57:45 -04002304}
2305
2306void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2307{
Nicolas Capensf160b172014-11-26 11:58:23 -05002308 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002309
Nicolas Capensf160b172014-11-26 11:58:23 -05002310 if(n < 0)
2311 {
2312 return error(GL_INVALID_VALUE);
2313 }
John Bauman66b8ab22014-05-06 15:57:45 -04002314
Nicolas Capensf160b172014-11-26 11:58:23 -05002315 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002316
Nicolas Capensf160b172014-11-26 11:58:23 -05002317 if(context)
2318 {
2319 for(int i = 0; i < n; i++)
2320 {
2321 framebuffers[i] = context->createFramebuffer();
2322 }
2323 }
John Bauman66b8ab22014-05-06 15:57:45 -04002324}
2325
2326void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
2327{
Nicolas Capensf160b172014-11-26 11:58:23 -05002328 TRACE("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04002329
Nicolas Capensf160b172014-11-26 11:58:23 -05002330 if(n < 0)
2331 {
2332 return error(GL_INVALID_VALUE);
2333 }
John Bauman66b8ab22014-05-06 15:57:45 -04002334
Nicolas Capensf160b172014-11-26 11:58:23 -05002335 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002336
Nicolas Capensf160b172014-11-26 11:58:23 -05002337 if(context)
2338 {
2339 for(int i = 0; i < n; i++)
2340 {
2341 ids[i] = context->createQuery();
2342 }
2343 }
John Bauman66b8ab22014-05-06 15:57:45 -04002344}
2345
2346void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2347{
Nicolas Capensf160b172014-11-26 11:58:23 -05002348 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002349
Nicolas Capensf160b172014-11-26 11:58:23 -05002350 if(n < 0)
2351 {
2352 return error(GL_INVALID_VALUE);
2353 }
John Bauman66b8ab22014-05-06 15:57:45 -04002354
Nicolas Capensf160b172014-11-26 11:58:23 -05002355 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002356
Nicolas Capensf160b172014-11-26 11:58:23 -05002357 if(context)
2358 {
2359 for(int i = 0; i < n; i++)
2360 {
2361 renderbuffers[i] = context->createRenderbuffer();
2362 }
2363 }
John Bauman66b8ab22014-05-06 15:57:45 -04002364}
2365
2366void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
2367{
Nicolas Capensf160b172014-11-26 11:58:23 -05002368 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04002369
Nicolas Capensf160b172014-11-26 11:58:23 -05002370 if(n < 0)
2371 {
2372 return error(GL_INVALID_VALUE);
2373 }
John Bauman66b8ab22014-05-06 15:57:45 -04002374
Nicolas Capensf160b172014-11-26 11:58:23 -05002375 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002376
Nicolas Capensf160b172014-11-26 11:58:23 -05002377 if(context)
2378 {
2379 for(int i = 0; i < n; i++)
2380 {
2381 textures[i] = context->createTexture();
2382 }
2383 }
John Bauman66b8ab22014-05-06 15:57:45 -04002384}
2385
2386void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
2387{
Nicolas Capensf160b172014-11-26 11:58:23 -05002388 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2389 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
2390 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002391
Nicolas Capensf160b172014-11-26 11:58:23 -05002392 if(bufsize < 0)
2393 {
2394 return error(GL_INVALID_VALUE);
2395 }
John Bauman66b8ab22014-05-06 15:57:45 -04002396
Nicolas Capensf160b172014-11-26 11:58:23 -05002397 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002398
Nicolas Capensf160b172014-11-26 11:58:23 -05002399 if(context)
2400 {
2401 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002402
Nicolas Capensf160b172014-11-26 11:58:23 -05002403 if(!programObject)
2404 {
2405 if(context->getShader(program))
2406 {
2407 return error(GL_INVALID_OPERATION);
2408 }
2409 else
2410 {
2411 return error(GL_INVALID_VALUE);
2412 }
2413 }
John Bauman66b8ab22014-05-06 15:57:45 -04002414
Nicolas Capensf160b172014-11-26 11:58:23 -05002415 if(index >= (GLuint)programObject->getActiveAttributeCount())
2416 {
2417 return error(GL_INVALID_VALUE);
2418 }
John Bauman66b8ab22014-05-06 15:57:45 -04002419
Nicolas Capensf160b172014-11-26 11:58:23 -05002420 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2421 }
John Bauman66b8ab22014-05-06 15:57:45 -04002422}
2423
2424void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
2425{
Nicolas Capensf160b172014-11-26 11:58:23 -05002426 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2427 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = %s)",
2428 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002429
Nicolas Capensf160b172014-11-26 11:58:23 -05002430 if(bufsize < 0)
2431 {
2432 return error(GL_INVALID_VALUE);
2433 }
John Bauman66b8ab22014-05-06 15:57:45 -04002434
Nicolas Capensf160b172014-11-26 11:58:23 -05002435 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002436
Nicolas Capensf160b172014-11-26 11:58:23 -05002437 if(context)
2438 {
2439 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002440
Nicolas Capensf160b172014-11-26 11:58:23 -05002441 if(!programObject)
2442 {
2443 if(context->getShader(program))
2444 {
2445 return error(GL_INVALID_OPERATION);
2446 }
2447 else
2448 {
2449 return error(GL_INVALID_VALUE);
2450 }
2451 }
John Bauman66b8ab22014-05-06 15:57:45 -04002452
Nicolas Capensf160b172014-11-26 11:58:23 -05002453 if(index >= (GLuint)programObject->getActiveUniformCount())
2454 {
2455 return error(GL_INVALID_VALUE);
2456 }
John Bauman66b8ab22014-05-06 15:57:45 -04002457
Nicolas Capensf160b172014-11-26 11:58:23 -05002458 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2459 }
John Bauman66b8ab22014-05-06 15:57:45 -04002460}
2461
2462void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2463{
Nicolas Capensf160b172014-11-26 11:58:23 -05002464 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2465 program, maxcount, count, shaders);
John Bauman66b8ab22014-05-06 15:57:45 -04002466
Nicolas Capensf160b172014-11-26 11:58:23 -05002467 if(maxcount < 0)
2468 {
2469 return error(GL_INVALID_VALUE);
2470 }
John Bauman66b8ab22014-05-06 15:57:45 -04002471
Nicolas Capensf160b172014-11-26 11:58:23 -05002472 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002473
Nicolas Capensf160b172014-11-26 11:58:23 -05002474 if(context)
2475 {
2476 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002477
Nicolas Capensf160b172014-11-26 11:58:23 -05002478 if(!programObject)
2479 {
2480 if(context->getShader(program))
2481 {
2482 return error(GL_INVALID_OPERATION);
2483 }
2484 else
2485 {
2486 return error(GL_INVALID_VALUE);
2487 }
2488 }
John Bauman66b8ab22014-05-06 15:57:45 -04002489
Nicolas Capensf160b172014-11-26 11:58:23 -05002490 return programObject->getAttachedShaders(maxcount, count, shaders);
2491 }
John Bauman66b8ab22014-05-06 15:57:45 -04002492}
2493
2494int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
2495{
Nicolas Capensf160b172014-11-26 11:58:23 -05002496 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002497
Nicolas Capensf160b172014-11-26 11:58:23 -05002498 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002499
Nicolas Capensf160b172014-11-26 11:58:23 -05002500 if(context)
2501 {
John Bauman66b8ab22014-05-06 15:57:45 -04002502
Nicolas Capensf160b172014-11-26 11:58:23 -05002503 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002504
Nicolas Capensf160b172014-11-26 11:58:23 -05002505 if(!programObject)
2506 {
2507 if(context->getShader(program))
2508 {
2509 return error(GL_INVALID_OPERATION, -1);
2510 }
2511 else
2512 {
2513 return error(GL_INVALID_VALUE, -1);
2514 }
2515 }
John Bauman66b8ab22014-05-06 15:57:45 -04002516
Nicolas Capensf160b172014-11-26 11:58:23 -05002517 if(!programObject->isLinked())
2518 {
2519 return error(GL_INVALID_OPERATION, -1);
2520 }
John Bauman66b8ab22014-05-06 15:57:45 -04002521
Nicolas Capensf160b172014-11-26 11:58:23 -05002522 return programObject->getAttributeLocation(name);
2523 }
John Bauman66b8ab22014-05-06 15:57:45 -04002524
Nicolas Capensf160b172014-11-26 11:58:23 -05002525 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04002526}
2527
2528void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
2529{
Nicolas Capensf160b172014-11-26 11:58:23 -05002530 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002531
Nicolas Capensf160b172014-11-26 11:58:23 -05002532 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002533
Nicolas Capensf160b172014-11-26 11:58:23 -05002534 if(context)
2535 {
2536 if(!(context->getBooleanv(pname, params)))
2537 {
2538 GLenum nativeType;
2539 unsigned int numParams = 0;
2540 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2541 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002542
Nicolas Capensf160b172014-11-26 11:58:23 -05002543 if(numParams == 0)
2544 return; // it is known that the pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04002545
Nicolas Capensf160b172014-11-26 11:58:23 -05002546 if(nativeType == GL_FLOAT)
2547 {
2548 GLfloat *floatParams = NULL;
2549 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002550
Nicolas Capensf160b172014-11-26 11:58:23 -05002551 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002552
Nicolas Capensf160b172014-11-26 11:58:23 -05002553 for(unsigned int i = 0; i < numParams; ++i)
2554 {
2555 if(floatParams[i] == 0.0f)
2556 params[i] = GL_FALSE;
2557 else
2558 params[i] = GL_TRUE;
2559 }
John Bauman66b8ab22014-05-06 15:57:45 -04002560
Nicolas Capensf160b172014-11-26 11:58:23 -05002561 delete [] floatParams;
2562 }
2563 else if(nativeType == GL_INT)
2564 {
2565 GLint *intParams = NULL;
2566 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002567
Nicolas Capensf160b172014-11-26 11:58:23 -05002568 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002569
Nicolas Capensf160b172014-11-26 11:58:23 -05002570 for(unsigned int i = 0; i < numParams; ++i)
2571 {
2572 if(intParams[i] == 0)
2573 params[i] = GL_FALSE;
2574 else
2575 params[i] = GL_TRUE;
2576 }
John Bauman66b8ab22014-05-06 15:57:45 -04002577
Nicolas Capensf160b172014-11-26 11:58:23 -05002578 delete [] intParams;
2579 }
2580 }
2581 }
John Bauman66b8ab22014-05-06 15:57:45 -04002582}
2583
2584void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2585{
Nicolas Capensf160b172014-11-26 11:58:23 -05002586 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002587
Nicolas Capensf160b172014-11-26 11:58:23 -05002588 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002589
Nicolas Capensf160b172014-11-26 11:58:23 -05002590 if(context)
2591 {
2592 es2::Buffer *buffer;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -04002593 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -05002594 {
Nicolas Capensf160b172014-11-26 11:58:23 -05002595 return error(GL_INVALID_ENUM);
2596 }
John Bauman66b8ab22014-05-06 15:57:45 -04002597
Nicolas Capensf160b172014-11-26 11:58:23 -05002598 if(!buffer)
2599 {
2600 // A null buffer means that "0" is bound to the requested buffer target
2601 return error(GL_INVALID_OPERATION);
2602 }
John Bauman66b8ab22014-05-06 15:57:45 -04002603
Alexis Hetued306182015-04-02 12:02:28 -04002604 egl::GLint clientVersion = context->getClientVersion();
2605
Nicolas Capensf160b172014-11-26 11:58:23 -05002606 switch(pname)
2607 {
2608 case GL_BUFFER_USAGE:
2609 *params = buffer->usage();
2610 break;
2611 case GL_BUFFER_SIZE:
2612 *params = buffer->size();
2613 break;
Alexis Hetued306182015-04-02 12:02:28 -04002614 case GL_BUFFER_ACCESS_FLAGS:
2615 if(clientVersion >= 3)
2616 {
2617 *params = buffer->access();
2618 break;
2619 }
2620 else return error(GL_INVALID_ENUM);
2621 case GL_BUFFER_MAPPED:
2622 if(clientVersion >= 3)
2623 {
2624 *params = buffer->isMapped();
2625 break;
2626 }
2627 else return error(GL_INVALID_ENUM);
2628 case GL_BUFFER_MAP_LENGTH:
2629 if(clientVersion >= 3)
2630 {
2631 *params = buffer->length();
2632 break;
2633 }
2634 else return error(GL_INVALID_ENUM);
2635 case GL_BUFFER_MAP_OFFSET:
2636 if(clientVersion >= 3)
2637 {
2638 *params = buffer->offset();
2639 break;
2640 }
2641 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05002642 default:
2643 return error(GL_INVALID_ENUM);
2644 }
2645 }
John Bauman66b8ab22014-05-06 15:57:45 -04002646}
2647
2648GLenum GL_APIENTRY glGetError(void)
2649{
Nicolas Capensf160b172014-11-26 11:58:23 -05002650 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002651
Nicolas Capensf160b172014-11-26 11:58:23 -05002652 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002653
Nicolas Capensf160b172014-11-26 11:58:23 -05002654 if(context)
2655 {
2656 return context->getError();
2657 }
John Bauman66b8ab22014-05-06 15:57:45 -04002658
Nicolas Capensf160b172014-11-26 11:58:23 -05002659 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002660}
2661
2662void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2663{
Nicolas Capensf160b172014-11-26 11:58:23 -05002664 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002665
Nicolas Capensf160b172014-11-26 11:58:23 -05002666 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002667
Nicolas Capensf160b172014-11-26 11:58:23 -05002668 if(context)
2669 {
2670 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002671
Nicolas Capensf160b172014-11-26 11:58:23 -05002672 if(fenceObject == NULL)
2673 {
2674 return error(GL_INVALID_OPERATION);
2675 }
John Bauman66b8ab22014-05-06 15:57:45 -04002676
Nicolas Capensf160b172014-11-26 11:58:23 -05002677 fenceObject->getFenceiv(pname, params);
2678 }
John Bauman66b8ab22014-05-06 15:57:45 -04002679}
2680
2681void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
2682{
Nicolas Capensf160b172014-11-26 11:58:23 -05002683 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002684
Nicolas Capensf160b172014-11-26 11:58:23 -05002685 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002686
Nicolas Capensf160b172014-11-26 11:58:23 -05002687 if(context)
2688 {
2689 if(!(context->getFloatv(pname, params)))
2690 {
2691 GLenum nativeType;
2692 unsigned int numParams = 0;
2693 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2694 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002695
Nicolas Capensf160b172014-11-26 11:58:23 -05002696 if(numParams == 0)
2697 return; // it is known that the pname is valid, but that there are no parameters to return.
John Bauman66b8ab22014-05-06 15:57:45 -04002698
Nicolas Capensf160b172014-11-26 11:58:23 -05002699 if(nativeType == GL_BOOL)
2700 {
2701 GLboolean *boolParams = NULL;
2702 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002703
Nicolas Capensf160b172014-11-26 11:58:23 -05002704 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002705
Nicolas Capensf160b172014-11-26 11:58:23 -05002706 for(unsigned int i = 0; i < numParams; ++i)
2707 {
2708 if(boolParams[i] == GL_FALSE)
2709 params[i] = 0.0f;
2710 else
2711 params[i] = 1.0f;
2712 }
John Bauman66b8ab22014-05-06 15:57:45 -04002713
Nicolas Capensf160b172014-11-26 11:58:23 -05002714 delete [] boolParams;
2715 }
2716 else if(nativeType == GL_INT)
2717 {
2718 GLint *intParams = NULL;
2719 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002720
Nicolas Capensf160b172014-11-26 11:58:23 -05002721 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002722
Nicolas Capensf160b172014-11-26 11:58:23 -05002723 for(unsigned int i = 0; i < numParams; ++i)
2724 {
2725 params[i] = (GLfloat)intParams[i];
2726 }
John Bauman66b8ab22014-05-06 15:57:45 -04002727
Nicolas Capensf160b172014-11-26 11:58:23 -05002728 delete [] intParams;
2729 }
2730 }
2731 }
John Bauman66b8ab22014-05-06 15:57:45 -04002732}
2733
2734void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2735{
Nicolas Capensf160b172014-11-26 11:58:23 -05002736 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2737 target, attachment, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002738
Nicolas Capensf160b172014-11-26 11:58:23 -05002739 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002740
Nicolas Capensf160b172014-11-26 11:58:23 -05002741 if(context)
2742 {
2743 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2744 {
2745 return error(GL_INVALID_ENUM);
2746 }
John Bauman66b8ab22014-05-06 15:57:45 -04002747
Nicolas Capensf160b172014-11-26 11:58:23 -05002748 es2::Framebuffer *framebuffer = NULL;
2749 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2750 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002751 if(context->getReadFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002752 {
2753 return error(GL_INVALID_OPERATION);
2754 }
John Bauman66b8ab22014-05-06 15:57:45 -04002755
Nicolas Capensf160b172014-11-26 11:58:23 -05002756 framebuffer = context->getReadFramebuffer();
2757 }
2758 else
2759 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002760 if(context->getDrawFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002761 {
2762 return error(GL_INVALID_OPERATION);
2763 }
John Bauman66b8ab22014-05-06 15:57:45 -04002764
Nicolas Capensf160b172014-11-26 11:58:23 -05002765 framebuffer = context->getDrawFramebuffer();
2766 }
John Bauman66b8ab22014-05-06 15:57:45 -04002767
Nicolas Capensf160b172014-11-26 11:58:23 -05002768 GLenum attachmentType;
2769 GLuint attachmentHandle;
2770 switch(attachment)
2771 {
2772 case GL_COLOR_ATTACHMENT0:
2773 attachmentType = framebuffer->getColorbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002774 attachmentHandle = framebuffer->getColorbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002775 break;
2776 case GL_DEPTH_ATTACHMENT:
2777 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002778 attachmentHandle = framebuffer->getDepthbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002779 break;
2780 case GL_STENCIL_ATTACHMENT:
2781 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002782 attachmentHandle = framebuffer->getStencilbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002783 break;
2784 default:
2785 return error(GL_INVALID_ENUM);
2786 }
John Bauman66b8ab22014-05-06 15:57:45 -04002787
Nicolas Capensf160b172014-11-26 11:58:23 -05002788 GLenum attachmentObjectType; // Type category
2789 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2790 {
2791 attachmentObjectType = attachmentType;
2792 }
2793 else if(es2::IsTextureTarget(attachmentType))
2794 {
2795 attachmentObjectType = GL_TEXTURE;
2796 }
2797 else UNREACHABLE();
John Bauman66b8ab22014-05-06 15:57:45 -04002798
Nicolas Capensf160b172014-11-26 11:58:23 -05002799 switch(pname)
2800 {
2801 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2802 *params = attachmentObjectType;
2803 break;
2804 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2805 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2806 {
2807 *params = attachmentHandle;
2808 }
2809 else
2810 {
2811 return error(GL_INVALID_ENUM);
2812 }
2813 break;
2814 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2815 if(attachmentObjectType == GL_TEXTURE)
2816 {
2817 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2818 }
2819 else
2820 {
2821 return error(GL_INVALID_ENUM);
2822 }
2823 break;
2824 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2825 if(attachmentObjectType == GL_TEXTURE)
2826 {
2827 if(es2::IsCubemapTextureTarget(attachmentType))
2828 {
2829 *params = attachmentType;
2830 }
2831 else
2832 {
2833 *params = 0;
2834 }
2835 }
2836 else
2837 {
2838 return error(GL_INVALID_ENUM);
2839 }
2840 break;
2841 default:
2842 return error(GL_INVALID_ENUM);
2843 }
2844 }
John Bauman66b8ab22014-05-06 15:57:45 -04002845}
2846
2847GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
2848{
Nicolas Capensf160b172014-11-26 11:58:23 -05002849 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002850
Nicolas Capensf160b172014-11-26 11:58:23 -05002851 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002852}
2853
2854void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
2855{
Nicolas Capensf160b172014-11-26 11:58:23 -05002856 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002857
Nicolas Capensf160b172014-11-26 11:58:23 -05002858 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002859
Nicolas Capens7ae353d2015-03-13 17:59:58 -04002860 if(!context)
2861 {
Greg Hartman6074f122015-04-08 09:57:16 -07002862 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
2863 #ifdef __ANDROID__
2864 ALOGI("expected_badness glGetIntegerv() called without current context.");
2865 #else
2866 ERR("glGetIntegerv() called without current context.");
2867 #endif
Nicolas Capens7ae353d2015-03-13 17:59:58 -04002868
2869 // This is not spec compliant! When there is no current GL context, functions should
2870 // have no side effects. Google Maps queries these values before creating a context,
2871 // so we need this as a bug-compatible workaround.
2872 switch(pname)
2873 {
2874 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return;
2875 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return;
2876 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
2877 case GL_STENCIL_BITS: *params = 8; return;
2878 case GL_ALIASED_LINE_WIDTH_RANGE:
2879 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
2880 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
2881 return;
2882 }
2883 }
2884
Nicolas Capensf160b172014-11-26 11:58:23 -05002885 if(context)
2886 {
2887 if(!(context->getIntegerv(pname, params)))
2888 {
2889 GLenum nativeType;
2890 unsigned int numParams = 0;
2891 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2892 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002893
Nicolas Capensf160b172014-11-26 11:58:23 -05002894 if(numParams == 0)
2895 return; // it is known that pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04002896
Nicolas Capensf160b172014-11-26 11:58:23 -05002897 if(nativeType == GL_BOOL)
2898 {
2899 GLboolean *boolParams = NULL;
2900 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002901
Nicolas Capensf160b172014-11-26 11:58:23 -05002902 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002903
Nicolas Capensf160b172014-11-26 11:58:23 -05002904 for(unsigned int i = 0; i < numParams; ++i)
2905 {
Alexis Hetued306182015-04-02 12:02:28 -04002906 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
Nicolas Capensf160b172014-11-26 11:58:23 -05002907 }
John Bauman66b8ab22014-05-06 15:57:45 -04002908
Nicolas Capensf160b172014-11-26 11:58:23 -05002909 delete [] boolParams;
2910 }
2911 else if(nativeType == GL_FLOAT)
2912 {
2913 GLfloat *floatParams = NULL;
2914 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002915
Nicolas Capensf160b172014-11-26 11:58:23 -05002916 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002917
Nicolas Capensf160b172014-11-26 11:58:23 -05002918 for(unsigned int i = 0; i < numParams; ++i)
2919 {
2920 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
2921 {
Alexis Hetued306182015-04-02 12:02:28 -04002922 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) * 0.5f);
Nicolas Capensf160b172014-11-26 11:58:23 -05002923 }
2924 else
2925 {
2926 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2927 }
2928 }
John Bauman66b8ab22014-05-06 15:57:45 -04002929
Nicolas Capensf160b172014-11-26 11:58:23 -05002930 delete [] floatParams;
2931 }
2932 }
2933 }
John Bauman66b8ab22014-05-06 15:57:45 -04002934}
2935
2936void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2937{
Nicolas Capensf160b172014-11-26 11:58:23 -05002938 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", program, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002939
Nicolas Capensf160b172014-11-26 11:58:23 -05002940 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002941
Nicolas Capensf160b172014-11-26 11:58:23 -05002942 if(context)
2943 {
2944 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002945
Nicolas Capensf160b172014-11-26 11:58:23 -05002946 if(!programObject)
2947 {
2948 return error(GL_INVALID_VALUE);
2949 }
John Bauman66b8ab22014-05-06 15:57:45 -04002950
Nicolas Capensf160b172014-11-26 11:58:23 -05002951 switch(pname)
2952 {
2953 case GL_DELETE_STATUS:
2954 *params = programObject->isFlaggedForDeletion();
2955 return;
2956 case GL_LINK_STATUS:
2957 *params = programObject->isLinked();
2958 return;
2959 case GL_VALIDATE_STATUS:
2960 *params = programObject->isValidated();
2961 return;
2962 case GL_INFO_LOG_LENGTH:
2963 *params = programObject->getInfoLogLength();
2964 return;
2965 case GL_ATTACHED_SHADERS:
2966 *params = programObject->getAttachedShadersCount();
2967 return;
2968 case GL_ACTIVE_ATTRIBUTES:
2969 *params = programObject->getActiveAttributeCount();
2970 return;
2971 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2972 *params = programObject->getActiveAttributeMaxLength();
2973 return;
2974 case GL_ACTIVE_UNIFORMS:
2975 *params = programObject->getActiveUniformCount();
2976 return;
2977 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2978 *params = programObject->getActiveUniformMaxLength();
2979 return;
2980 default:
2981 return error(GL_INVALID_ENUM);
2982 }
2983 }
John Bauman66b8ab22014-05-06 15:57:45 -04002984}
2985
2986void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
2987{
Nicolas Capensf160b172014-11-26 11:58:23 -05002988 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
2989 program, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04002990
Nicolas Capensf160b172014-11-26 11:58:23 -05002991 if(bufsize < 0)
2992 {
2993 return error(GL_INVALID_VALUE);
2994 }
John Bauman66b8ab22014-05-06 15:57:45 -04002995
Nicolas Capensf160b172014-11-26 11:58:23 -05002996 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002997
Nicolas Capensf160b172014-11-26 11:58:23 -05002998 if(context)
2999 {
3000 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003001
Nicolas Capensf160b172014-11-26 11:58:23 -05003002 if(!programObject)
3003 {
3004 return error(GL_INVALID_VALUE);
3005 }
John Bauman66b8ab22014-05-06 15:57:45 -04003006
Nicolas Capensf160b172014-11-26 11:58:23 -05003007 programObject->getInfoLog(bufsize, length, infolog);
3008 }
John Bauman66b8ab22014-05-06 15:57:45 -04003009}
3010
3011void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3012{
Nicolas Capensf160b172014-11-26 11:58:23 -05003013 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003014
Nicolas Capensf160b172014-11-26 11:58:23 -05003015 switch(pname)
3016 {
3017 case GL_CURRENT_QUERY_EXT:
3018 break;
3019 default:
3020 return error(GL_INVALID_ENUM);
3021 }
John Bauman66b8ab22014-05-06 15:57:45 -04003022
Nicolas Capensf160b172014-11-26 11:58:23 -05003023 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003024
Nicolas Capensf160b172014-11-26 11:58:23 -05003025 if(context)
3026 {
3027 params[0] = context->getActiveQuery(target);
3028 }
John Bauman66b8ab22014-05-06 15:57:45 -04003029}
3030
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003031void GL_APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04003032{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003033 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", name, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003034
Nicolas Capensf160b172014-11-26 11:58:23 -05003035 switch(pname)
3036 {
3037 case GL_QUERY_RESULT_EXT:
3038 case GL_QUERY_RESULT_AVAILABLE_EXT:
3039 break;
3040 default:
3041 return error(GL_INVALID_ENUM);
3042 }
John Bauman66b8ab22014-05-06 15:57:45 -04003043
Nicolas Capensf160b172014-11-26 11:58:23 -05003044 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003045
Nicolas Capensf160b172014-11-26 11:58:23 -05003046 if(context)
3047 {
Alexis Hetu8e32f7b2015-04-28 09:59:09 -04003048 es2::Query *queryObject = context->getQuery(name);
John Bauman66b8ab22014-05-06 15:57:45 -04003049
Nicolas Capensf160b172014-11-26 11:58:23 -05003050 if(!queryObject)
3051 {
3052 return error(GL_INVALID_OPERATION);
3053 }
John Bauman66b8ab22014-05-06 15:57:45 -04003054
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003055 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capensf160b172014-11-26 11:58:23 -05003056 {
3057 return error(GL_INVALID_OPERATION);
3058 }
John Bauman66b8ab22014-05-06 15:57:45 -04003059
Nicolas Capensf160b172014-11-26 11:58:23 -05003060 switch(pname)
3061 {
3062 case GL_QUERY_RESULT_EXT:
3063 params[0] = queryObject->getResult();
3064 break;
3065 case GL_QUERY_RESULT_AVAILABLE_EXT:
3066 params[0] = queryObject->isResultAvailable();
3067 break;
3068 default:
3069 ASSERT(false);
3070 }
3071 }
John Bauman66b8ab22014-05-06 15:57:45 -04003072}
3073
3074void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3075{
Nicolas Capensf160b172014-11-26 11:58:23 -05003076 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003077
Nicolas Capensf160b172014-11-26 11:58:23 -05003078 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003079
Nicolas Capensf160b172014-11-26 11:58:23 -05003080 if(context)
3081 {
3082 if(target != GL_RENDERBUFFER)
3083 {
3084 return error(GL_INVALID_ENUM);
3085 }
John Bauman66b8ab22014-05-06 15:57:45 -04003086
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003087 if(context->getRenderbufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05003088 {
3089 return error(GL_INVALID_OPERATION);
3090 }
John Bauman66b8ab22014-05-06 15:57:45 -04003091
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003092 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
John Bauman66b8ab22014-05-06 15:57:45 -04003093
Nicolas Capensf160b172014-11-26 11:58:23 -05003094 switch(pname)
3095 {
3096 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3097 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3098 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
3099 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3100 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3101 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3102 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3103 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3104 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
3105 case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break;
3106 default:
3107 return error(GL_INVALID_ENUM);
3108 }
3109 }
John Bauman66b8ab22014-05-06 15:57:45 -04003110}
3111
3112void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3113{
Nicolas Capensf160b172014-11-26 11:58:23 -05003114 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003115
Nicolas Capensf160b172014-11-26 11:58:23 -05003116 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003117
Nicolas Capensf160b172014-11-26 11:58:23 -05003118 if(context)
3119 {
3120 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003121
Nicolas Capensf160b172014-11-26 11:58:23 -05003122 if(!shaderObject)
3123 {
3124 return error(GL_INVALID_VALUE);
3125 }
John Bauman66b8ab22014-05-06 15:57:45 -04003126
Nicolas Capensf160b172014-11-26 11:58:23 -05003127 switch(pname)
3128 {
3129 case GL_SHADER_TYPE:
3130 *params = shaderObject->getType();
3131 return;
3132 case GL_DELETE_STATUS:
3133 *params = shaderObject->isFlaggedForDeletion();
3134 return;
3135 case GL_COMPILE_STATUS:
3136 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3137 return;
3138 case GL_INFO_LOG_LENGTH:
3139 *params = shaderObject->getInfoLogLength();
3140 return;
3141 case GL_SHADER_SOURCE_LENGTH:
3142 *params = shaderObject->getSourceLength();
3143 return;
3144 default:
3145 return error(GL_INVALID_ENUM);
3146 }
3147 }
John Bauman66b8ab22014-05-06 15:57:45 -04003148}
3149
3150void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3151{
Nicolas Capensf160b172014-11-26 11:58:23 -05003152 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
3153 shader, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04003154
Nicolas Capensf160b172014-11-26 11:58:23 -05003155 if(bufsize < 0)
3156 {
3157 return error(GL_INVALID_VALUE);
3158 }
John Bauman66b8ab22014-05-06 15:57:45 -04003159
Nicolas Capensf160b172014-11-26 11:58:23 -05003160 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003161
Nicolas Capensf160b172014-11-26 11:58:23 -05003162 if(context)
3163 {
3164 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003165
Nicolas Capensf160b172014-11-26 11:58:23 -05003166 if(!shaderObject)
3167 {
3168 return error(GL_INVALID_VALUE);
3169 }
John Bauman66b8ab22014-05-06 15:57:45 -04003170
Nicolas Capensf160b172014-11-26 11:58:23 -05003171 shaderObject->getInfoLog(bufsize, length, infolog);
3172 }
John Bauman66b8ab22014-05-06 15:57:45 -04003173}
3174
3175void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3176{
Nicolas Capensf160b172014-11-26 11:58:23 -05003177 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3178 shadertype, precisiontype, range, precision);
John Bauman66b8ab22014-05-06 15:57:45 -04003179
Nicolas Capensf160b172014-11-26 11:58:23 -05003180 switch(shadertype)
3181 {
3182 case GL_VERTEX_SHADER:
3183 case GL_FRAGMENT_SHADER:
3184 break;
3185 default:
3186 return error(GL_INVALID_ENUM);
3187 }
John Bauman66b8ab22014-05-06 15:57:45 -04003188
Nicolas Capensf160b172014-11-26 11:58:23 -05003189 switch(precisiontype)
3190 {
3191 case GL_LOW_FLOAT:
3192 case GL_MEDIUM_FLOAT:
3193 case GL_HIGH_FLOAT:
3194 // IEEE 754 single-precision
3195 range[0] = 127;
3196 range[1] = 127;
3197 *precision = 23;
3198 break;
3199 case GL_LOW_INT:
3200 case GL_MEDIUM_INT:
3201 case GL_HIGH_INT:
3202 // Single-precision floating-point numbers can accurately represent integers up to +/-16777216
3203 range[0] = 24;
3204 range[1] = 24;
3205 *precision = 0;
3206 break;
3207 default:
3208 return error(GL_INVALID_ENUM);
3209 }
John Bauman66b8ab22014-05-06 15:57:45 -04003210}
3211
3212void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3213{
Nicolas Capensf160b172014-11-26 11:58:23 -05003214 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3215 shader, bufsize, length, source);
John Bauman66b8ab22014-05-06 15:57:45 -04003216
Nicolas Capensf160b172014-11-26 11:58:23 -05003217 if(bufsize < 0)
3218 {
3219 return error(GL_INVALID_VALUE);
3220 }
John Bauman66b8ab22014-05-06 15:57:45 -04003221
Nicolas Capensf160b172014-11-26 11:58:23 -05003222 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003223
Nicolas Capensf160b172014-11-26 11:58:23 -05003224 if(context)
3225 {
3226 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003227
Nicolas Capensf160b172014-11-26 11:58:23 -05003228 if(!shaderObject)
3229 {
3230 return error(GL_INVALID_OPERATION);
3231 }
John Bauman66b8ab22014-05-06 15:57:45 -04003232
Nicolas Capensf160b172014-11-26 11:58:23 -05003233 shaderObject->getSource(bufsize, length, source);
3234 }
John Bauman66b8ab22014-05-06 15:57:45 -04003235}
3236
3237const GLubyte* GL_APIENTRY glGetString(GLenum name)
3238{
Nicolas Capensf160b172014-11-26 11:58:23 -05003239 TRACE("(GLenum name = 0x%X)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04003240
Nicolas Capensf160b172014-11-26 11:58:23 -05003241 switch(name)
3242 {
3243 case GL_VENDOR:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003244 return (GLubyte*)"Google Inc.";
Nicolas Capensf160b172014-11-26 11:58:23 -05003245 case GL_RENDERER:
3246 return (GLubyte*)"SwiftShader";
3247 case GL_VERSION:
3248 return (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3249 case GL_SHADING_LANGUAGE_VERSION:
3250 return (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3251 case GL_EXTENSIONS:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003252 {
3253 es2::Context *context = es2::getContext();
3254 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)NULL;
3255 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003256 default:
3257 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3258 }
John Bauman66b8ab22014-05-06 15:57:45 -04003259}
3260
3261void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3262{
Nicolas Capensf160b172014-11-26 11:58:23 -05003263 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003264
Nicolas Capensf160b172014-11-26 11:58:23 -05003265 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003266
Nicolas Capensf160b172014-11-26 11:58:23 -05003267 if(context)
3268 {
3269 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003270
Alexis Hetued306182015-04-02 12:02:28 -04003271 egl::GLint clientVersion = context->getClientVersion();
3272
Nicolas Capensf160b172014-11-26 11:58:23 -05003273 switch(target)
3274 {
3275 case GL_TEXTURE_2D:
3276 texture = context->getTexture2D();
3277 break;
3278 case GL_TEXTURE_CUBE_MAP:
3279 texture = context->getTextureCubeMap();
3280 break;
3281 case GL_TEXTURE_EXTERNAL_OES:
3282 texture = context->getTextureExternal();
3283 break;
Alexis Hetued306182015-04-02 12:02:28 -04003284 case GL_TEXTURE_2D_ARRAY:
3285 if(clientVersion < 3)
3286 {
3287 return error(GL_INVALID_ENUM);
3288 }
3289 else
3290 {
3291 UNIMPLEMENTED();
3292 texture = context->getTexture3D();
3293 break;
3294 }
3295 case GL_TEXTURE_3D_OES:
3296 texture = context->getTexture3D();
3297 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003298 default:
3299 return error(GL_INVALID_ENUM);
3300 }
John Bauman66b8ab22014-05-06 15:57:45 -04003301
Nicolas Capensf160b172014-11-26 11:58:23 -05003302 switch(pname)
3303 {
3304 case GL_TEXTURE_MAG_FILTER:
3305 *params = (GLfloat)texture->getMagFilter();
3306 break;
3307 case GL_TEXTURE_MIN_FILTER:
3308 *params = (GLfloat)texture->getMinFilter();
3309 break;
3310 case GL_TEXTURE_WRAP_S:
3311 *params = (GLfloat)texture->getWrapS();
3312 break;
3313 case GL_TEXTURE_WRAP_T:
3314 *params = (GLfloat)texture->getWrapT();
3315 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003316 case GL_TEXTURE_WRAP_R_OES:
3317 *params = (GLfloat)texture->getWrapR();
3318 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003319 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3320 *params = texture->getMaxAnisotropy();
3321 break;
3322 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3323 *params = (GLfloat)1;
3324 break;
Alexis Hetued306182015-04-02 12:02:28 -04003325 case GL_TEXTURE_BASE_LEVEL:
3326 if(clientVersion >= 3)
3327 {
3328 *params = (GLfloat)texture->getBaseLevel();
3329 break;
3330 }
3331 else return error(GL_INVALID_ENUM);
3332 case GL_TEXTURE_COMPARE_FUNC:
3333 if(clientVersion >= 3)
3334 {
3335 *params = (GLfloat)texture->getCompareFunc();
3336 break;
3337 }
3338 else return error(GL_INVALID_ENUM);
3339 case GL_TEXTURE_COMPARE_MODE:
3340 if(clientVersion >= 3)
3341 {
3342 *params = (GLfloat)texture->getCompareMode();
3343 break;
3344 }
3345 else return error(GL_INVALID_ENUM);
3346 case GL_TEXTURE_IMMUTABLE_FORMAT:
3347 if(clientVersion >= 3)
3348 {
3349 *params = (GLfloat)texture->getImmutableFormat();
3350 break;
3351 }
3352 else return error(GL_INVALID_ENUM);
3353 case GL_TEXTURE_MAX_LEVEL:
3354 if(clientVersion >= 3)
3355 {
3356 *params = (GLfloat)texture->getMaxLevel();
3357 break;
3358 }
3359 else return error(GL_INVALID_ENUM);
3360 case GL_TEXTURE_MAX_LOD:
3361 if(clientVersion >= 3)
3362 {
3363 *params = texture->getMaxLOD();
3364 break;
3365 }
3366 else return error(GL_INVALID_ENUM);
3367 case GL_TEXTURE_MIN_LOD:
3368 if(clientVersion >= 3)
3369 {
3370 *params = texture->getMinLOD();
3371 break;
3372 }
3373 else return error(GL_INVALID_ENUM);
3374 case GL_TEXTURE_SWIZZLE_R:
3375 if(clientVersion >= 3)
3376 {
3377 *params = (GLfloat)texture->getSwizzleR();
3378 break;
3379 }
3380 else return error(GL_INVALID_ENUM);
3381 case GL_TEXTURE_SWIZZLE_G:
3382 if(clientVersion >= 3)
3383 {
3384 *params = (GLfloat)texture->getSwizzleG();
3385 break;
3386 }
3387 else return error(GL_INVALID_ENUM);
3388 case GL_TEXTURE_SWIZZLE_B:
3389 if(clientVersion >= 3)
3390 {
3391 *params = (GLfloat)texture->getSwizzleB();
3392 break;
3393 }
3394 else return error(GL_INVALID_ENUM);
3395 case GL_TEXTURE_SWIZZLE_A:
3396 if(clientVersion >= 3)
3397 {
3398 *params = (GLfloat)texture->getSwizzleA();
3399 break;
3400 }
3401 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003402 default:
3403 return error(GL_INVALID_ENUM);
3404 }
3405 }
John Bauman66b8ab22014-05-06 15:57:45 -04003406}
3407
3408void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3409{
Nicolas Capensf160b172014-11-26 11:58:23 -05003410 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003411
Nicolas Capensf160b172014-11-26 11:58:23 -05003412 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003413
Nicolas Capensf160b172014-11-26 11:58:23 -05003414 if(context)
3415 {
3416 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003417
Alexis Hetued306182015-04-02 12:02:28 -04003418 egl::GLint clientVersion = context->getClientVersion();
3419
Nicolas Capensf160b172014-11-26 11:58:23 -05003420 switch(target)
3421 {
3422 case GL_TEXTURE_2D:
3423 texture = context->getTexture2D();
3424 break;
3425 case GL_TEXTURE_CUBE_MAP:
3426 texture = context->getTextureCubeMap();
3427 break;
3428 case GL_TEXTURE_EXTERNAL_OES:
3429 texture = context->getTextureExternal();
3430 break;
Alexis Hetued306182015-04-02 12:02:28 -04003431 case GL_TEXTURE_2D_ARRAY:
3432 if(clientVersion < 3)
3433 {
3434 return error(GL_INVALID_ENUM);
3435 }
3436 else
3437 {
3438 UNIMPLEMENTED();
3439 texture = context->getTexture3D();
3440 break;
3441 }
3442 case GL_TEXTURE_3D_OES:
3443 texture = context->getTexture3D();
3444 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003445 default:
3446 return error(GL_INVALID_ENUM);
3447 }
John Bauman66b8ab22014-05-06 15:57:45 -04003448
Nicolas Capensf160b172014-11-26 11:58:23 -05003449 switch(pname)
3450 {
3451 case GL_TEXTURE_MAG_FILTER:
3452 *params = texture->getMagFilter();
3453 break;
3454 case GL_TEXTURE_MIN_FILTER:
3455 *params = texture->getMinFilter();
3456 break;
3457 case GL_TEXTURE_WRAP_S:
3458 *params = texture->getWrapS();
3459 break;
3460 case GL_TEXTURE_WRAP_T:
3461 *params = texture->getWrapT();
3462 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003463 case GL_TEXTURE_WRAP_R_OES:
3464 *params = texture->getWrapR();
3465 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003466 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3467 *params = (GLint)texture->getMaxAnisotropy();
3468 break;
3469 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3470 *params = 1;
3471 break;
Alexis Hetued306182015-04-02 12:02:28 -04003472 case GL_TEXTURE_BASE_LEVEL:
3473 if(clientVersion >= 3)
3474 {
3475 *params = texture->getBaseLevel();
3476 break;
3477 }
3478 else return error(GL_INVALID_ENUM);
3479 case GL_TEXTURE_COMPARE_FUNC:
3480 if(clientVersion >= 3)
3481 {
3482 *params = (GLint)texture->getCompareFunc();
3483 break;
3484 }
3485 else return error(GL_INVALID_ENUM);
3486 case GL_TEXTURE_COMPARE_MODE:
3487 if(clientVersion >= 3)
3488 {
3489 *params = (GLint)texture->getCompareMode();
3490 break;
3491 }
3492 else return error(GL_INVALID_ENUM);
3493 case GL_TEXTURE_IMMUTABLE_FORMAT:
3494 if(clientVersion >= 3)
3495 {
3496 *params = (GLint)texture->getImmutableFormat();
3497 break;
3498 }
3499 else return error(GL_INVALID_ENUM);
3500 case GL_TEXTURE_MAX_LEVEL:
3501 if(clientVersion >= 3)
3502 {
3503 *params = texture->getMaxLevel();
3504 break;
3505 }
3506 else return error(GL_INVALID_ENUM);
3507 case GL_TEXTURE_MAX_LOD:
3508 if(clientVersion >= 3)
3509 {
3510 *params = (GLint)texture->getMaxLOD();
3511 break;
3512 }
3513 else return error(GL_INVALID_ENUM);
3514 case GL_TEXTURE_MIN_LOD:
3515 if(clientVersion >= 3)
3516 {
3517 *params = (GLint)texture->getMinLOD();
3518 break;
3519 }
3520 else return error(GL_INVALID_ENUM);
3521 case GL_TEXTURE_SWIZZLE_R:
3522 if(clientVersion >= 3)
3523 {
3524 *params = (GLint)texture->getSwizzleR();
3525 break;
3526 }
3527 else return error(GL_INVALID_ENUM);
3528 case GL_TEXTURE_SWIZZLE_G:
3529 if(clientVersion >= 3)
3530 {
3531 *params = (GLint)texture->getSwizzleG();
3532 break;
3533 }
3534 else return error(GL_INVALID_ENUM);
3535 case GL_TEXTURE_SWIZZLE_B:
3536 if(clientVersion >= 3)
3537 {
3538 *params = (GLint)texture->getSwizzleB();
3539 break;
3540 }
3541 else return error(GL_INVALID_ENUM);
3542 case GL_TEXTURE_SWIZZLE_A:
3543 if(clientVersion >= 3)
3544 {
3545 *params = (GLint)texture->getSwizzleA();
3546 break;
3547 }
3548 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003549 default:
3550 return error(GL_INVALID_ENUM);
3551 }
3552 }
John Bauman66b8ab22014-05-06 15:57:45 -04003553}
3554
3555void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3556{
Nicolas Capensf160b172014-11-26 11:58:23 -05003557 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3558 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003559
Nicolas Capensf160b172014-11-26 11:58:23 -05003560 if(bufSize < 0)
3561 {
3562 return error(GL_INVALID_VALUE);
3563 }
John Bauman66b8ab22014-05-06 15:57:45 -04003564
Nicolas Capensf160b172014-11-26 11:58:23 -05003565 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003566
Nicolas Capensf160b172014-11-26 11:58:23 -05003567 if(context)
3568 {
3569 if(program == 0)
3570 {
3571 return error(GL_INVALID_VALUE);
3572 }
John Bauman66b8ab22014-05-06 15:57:45 -04003573
Nicolas Capensf160b172014-11-26 11:58:23 -05003574 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003575
Nicolas Capensf160b172014-11-26 11:58:23 -05003576 if(!programObject || !programObject->isLinked())
3577 {
3578 return error(GL_INVALID_OPERATION);
3579 }
John Bauman66b8ab22014-05-06 15:57:45 -04003580
Nicolas Capensf160b172014-11-26 11:58:23 -05003581 if(!programObject->getUniformfv(location, &bufSize, params))
3582 {
3583 return error(GL_INVALID_OPERATION);
3584 }
3585 }
John Bauman66b8ab22014-05-06 15:57:45 -04003586}
3587
3588void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3589{
Nicolas Capensf160b172014-11-26 11:58:23 -05003590 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003591
Nicolas Capensf160b172014-11-26 11:58:23 -05003592 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003593
Nicolas Capensf160b172014-11-26 11:58:23 -05003594 if(context)
3595 {
3596 if(program == 0)
3597 {
3598 return error(GL_INVALID_VALUE);
3599 }
John Bauman66b8ab22014-05-06 15:57:45 -04003600
Nicolas Capensf160b172014-11-26 11:58:23 -05003601 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003602
Nicolas Capensf160b172014-11-26 11:58:23 -05003603 if(!programObject || !programObject->isLinked())
3604 {
3605 return error(GL_INVALID_OPERATION);
3606 }
John Bauman66b8ab22014-05-06 15:57:45 -04003607
Nicolas Capensf160b172014-11-26 11:58:23 -05003608 if(!programObject->getUniformfv(location, NULL, params))
3609 {
3610 return error(GL_INVALID_OPERATION);
3611 }
3612 }
John Bauman66b8ab22014-05-06 15:57:45 -04003613}
3614
3615void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3616{
Nicolas Capensf160b172014-11-26 11:58:23 -05003617 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3618 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003619
Nicolas Capensf160b172014-11-26 11:58:23 -05003620 if(bufSize < 0)
3621 {
3622 return error(GL_INVALID_VALUE);
3623 }
John Bauman66b8ab22014-05-06 15:57:45 -04003624
Nicolas Capensf160b172014-11-26 11:58:23 -05003625 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003626
Nicolas Capensf160b172014-11-26 11:58:23 -05003627 if(context)
3628 {
3629 if(program == 0)
3630 {
3631 return error(GL_INVALID_VALUE);
3632 }
John Bauman66b8ab22014-05-06 15:57:45 -04003633
Nicolas Capensf160b172014-11-26 11:58:23 -05003634 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003635
Nicolas Capensf160b172014-11-26 11:58:23 -05003636 if(!programObject || !programObject->isLinked())
3637 {
3638 return error(GL_INVALID_OPERATION);
3639 }
John Bauman66b8ab22014-05-06 15:57:45 -04003640
Nicolas Capensf160b172014-11-26 11:58:23 -05003641 if(!programObject)
3642 {
3643 return error(GL_INVALID_OPERATION);
3644 }
John Bauman66b8ab22014-05-06 15:57:45 -04003645
Nicolas Capensf160b172014-11-26 11:58:23 -05003646 if(!programObject->getUniformiv(location, &bufSize, params))
3647 {
3648 return error(GL_INVALID_OPERATION);
3649 }
3650 }
John Bauman66b8ab22014-05-06 15:57:45 -04003651}
3652
3653void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
3654{
Nicolas Capensf160b172014-11-26 11:58:23 -05003655 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003656
Nicolas Capensf160b172014-11-26 11:58:23 -05003657 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003658
Nicolas Capensf160b172014-11-26 11:58:23 -05003659 if(context)
3660 {
3661 if(program == 0)
3662 {
3663 return error(GL_INVALID_VALUE);
3664 }
John Bauman66b8ab22014-05-06 15:57:45 -04003665
Nicolas Capensf160b172014-11-26 11:58:23 -05003666 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003667
Nicolas Capensf160b172014-11-26 11:58:23 -05003668 if(!programObject || !programObject->isLinked())
3669 {
3670 return error(GL_INVALID_OPERATION);
3671 }
John Bauman66b8ab22014-05-06 15:57:45 -04003672
Nicolas Capensf160b172014-11-26 11:58:23 -05003673 if(!programObject)
3674 {
3675 return error(GL_INVALID_OPERATION);
3676 }
John Bauman66b8ab22014-05-06 15:57:45 -04003677
Nicolas Capensf160b172014-11-26 11:58:23 -05003678 if(!programObject->getUniformiv(location, NULL, params))
3679 {
3680 return error(GL_INVALID_OPERATION);
3681 }
3682 }
John Bauman66b8ab22014-05-06 15:57:45 -04003683}
3684
3685int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
3686{
Nicolas Capensf160b172014-11-26 11:58:23 -05003687 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04003688
Nicolas Capensf160b172014-11-26 11:58:23 -05003689 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003690
Nicolas Capensf160b172014-11-26 11:58:23 -05003691 if(strstr(name, "gl_") == name)
3692 {
3693 return -1;
3694 }
John Bauman66b8ab22014-05-06 15:57:45 -04003695
Nicolas Capensf160b172014-11-26 11:58:23 -05003696 if(context)
3697 {
3698 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003699
Nicolas Capensf160b172014-11-26 11:58:23 -05003700 if(!programObject)
3701 {
3702 if(context->getShader(program))
3703 {
3704 return error(GL_INVALID_OPERATION, -1);
3705 }
3706 else
3707 {
3708 return error(GL_INVALID_VALUE, -1);
3709 }
3710 }
John Bauman66b8ab22014-05-06 15:57:45 -04003711
Nicolas Capensf160b172014-11-26 11:58:23 -05003712 if(!programObject->isLinked())
3713 {
3714 return error(GL_INVALID_OPERATION, -1);
3715 }
John Bauman66b8ab22014-05-06 15:57:45 -04003716
Nicolas Capensf160b172014-11-26 11:58:23 -05003717 return programObject->getUniformLocation(name);
3718 }
John Bauman66b8ab22014-05-06 15:57:45 -04003719
Nicolas Capensf160b172014-11-26 11:58:23 -05003720 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04003721}
3722
3723void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3724{
Nicolas Capensf160b172014-11-26 11:58:23 -05003725 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003726
Nicolas Capensf160b172014-11-26 11:58:23 -05003727 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003728
Nicolas Capensf160b172014-11-26 11:58:23 -05003729 if(context)
3730 {
3731 if(index >= es2::MAX_VERTEX_ATTRIBS)
3732 {
3733 return error(GL_INVALID_VALUE);
3734 }
John Bauman66b8ab22014-05-06 15:57:45 -04003735
Nicolas Capensf160b172014-11-26 11:58:23 -05003736 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
Alexis Hetued306182015-04-02 12:02:28 -04003737
3738 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04003739
Nicolas Capensf160b172014-11-26 11:58:23 -05003740 switch(pname)
3741 {
3742 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3743 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3744 break;
3745 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3746 *params = (GLfloat)attribState.mSize;
3747 break;
3748 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3749 *params = (GLfloat)attribState.mStride;
3750 break;
3751 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3752 *params = (GLfloat)attribState.mType;
3753 break;
3754 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3755 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3756 break;
3757 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003758 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003759 break;
3760 case GL_CURRENT_VERTEX_ATTRIB:
3761 for(int i = 0; i < 4; ++i)
3762 {
Alexis Hetu93ae1032015-04-10 14:31:01 -04003763 params[i] = attribState.getCurrentValue(i);
Nicolas Capensf160b172014-11-26 11:58:23 -05003764 }
3765 break;
Alexis Hetued306182015-04-02 12:02:28 -04003766 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3767 if(clientVersion >= 3)
3768 {
3769 switch(attribState.mType)
3770 {
3771 case GL_BYTE:
3772 case GL_UNSIGNED_BYTE:
3773 case GL_SHORT:
3774 case GL_UNSIGNED_SHORT:
3775 case GL_INT:
3776 case GL_INT_2_10_10_10_REV:
3777 case GL_UNSIGNED_INT:
3778 case GL_FIXED:
3779 *params = (GLfloat)GL_TRUE;
3780 break;
3781 default:
3782 *params = (GLfloat)GL_FALSE;
3783 break;
3784 }
3785 break;
3786 }
3787 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003788 default: return error(GL_INVALID_ENUM);
3789 }
3790 }
John Bauman66b8ab22014-05-06 15:57:45 -04003791}
3792
3793void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3794{
Nicolas Capensf160b172014-11-26 11:58:23 -05003795 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003796
Nicolas Capensf160b172014-11-26 11:58:23 -05003797 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003798
Nicolas Capensf160b172014-11-26 11:58:23 -05003799 if(context)
3800 {
3801 if(index >= es2::MAX_VERTEX_ATTRIBS)
3802 {
3803 return error(GL_INVALID_VALUE);
3804 }
John Bauman66b8ab22014-05-06 15:57:45 -04003805
Nicolas Capensf160b172014-11-26 11:58:23 -05003806 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
John Bauman66b8ab22014-05-06 15:57:45 -04003807
Alexis Hetued306182015-04-02 12:02:28 -04003808 egl::GLint clientVersion = context->getClientVersion();
3809
Nicolas Capensf160b172014-11-26 11:58:23 -05003810 switch(pname)
3811 {
3812 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3813 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3814 break;
3815 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3816 *params = attribState.mSize;
3817 break;
3818 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3819 *params = attribState.mStride;
3820 break;
3821 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3822 *params = attribState.mType;
3823 break;
3824 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3825 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3826 break;
3827 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003828 *params = attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003829 break;
3830 case GL_CURRENT_VERTEX_ATTRIB:
3831 for(int i = 0; i < 4; ++i)
3832 {
Alexis Hetu93ae1032015-04-10 14:31:01 -04003833 float currentValue = attribState.getCurrentValue(i);
Nicolas Capensf160b172014-11-26 11:58:23 -05003834 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3835 }
3836 break;
Alexis Hetued306182015-04-02 12:02:28 -04003837 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3838 if(clientVersion >= 3)
3839 {
3840 switch(attribState.mType)
3841 {
3842 case GL_BYTE:
3843 case GL_UNSIGNED_BYTE:
3844 case GL_SHORT:
3845 case GL_UNSIGNED_SHORT:
3846 case GL_INT:
3847 case GL_INT_2_10_10_10_REV:
3848 case GL_UNSIGNED_INT:
3849 case GL_FIXED:
3850 *params = GL_TRUE;
3851 break;
3852 default:
3853 *params = GL_FALSE;
3854 break;
3855 }
3856 break;
3857 }
3858 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003859 default: return error(GL_INVALID_ENUM);
3860 }
3861 }
John Bauman66b8ab22014-05-06 15:57:45 -04003862}
3863
3864void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
3865{
Nicolas Capensf160b172014-11-26 11:58:23 -05003866 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
John Bauman66b8ab22014-05-06 15:57:45 -04003867
Nicolas Capensf160b172014-11-26 11:58:23 -05003868 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003869
Nicolas Capensf160b172014-11-26 11:58:23 -05003870 if(context)
3871 {
3872 if(index >= es2::MAX_VERTEX_ATTRIBS)
3873 {
3874 return error(GL_INVALID_VALUE);
3875 }
John Bauman66b8ab22014-05-06 15:57:45 -04003876
Nicolas Capensf160b172014-11-26 11:58:23 -05003877 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3878 {
3879 return error(GL_INVALID_ENUM);
3880 }
John Bauman66b8ab22014-05-06 15:57:45 -04003881
Nicolas Capensf160b172014-11-26 11:58:23 -05003882 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3883 }
John Bauman66b8ab22014-05-06 15:57:45 -04003884}
3885
3886void GL_APIENTRY glHint(GLenum target, GLenum mode)
3887{
Nicolas Capensf160b172014-11-26 11:58:23 -05003888 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
John Bauman66b8ab22014-05-06 15:57:45 -04003889
Nicolas Capensf160b172014-11-26 11:58:23 -05003890 switch(mode)
3891 {
3892 case GL_FASTEST:
3893 case GL_NICEST:
3894 case GL_DONT_CARE:
3895 break;
3896 default:
3897 return error(GL_INVALID_ENUM);
3898 }
John Bauman66b8ab22014-05-06 15:57:45 -04003899
Nicolas Capensf160b172014-11-26 11:58:23 -05003900 es2::Context *context = es2::getContext();
3901 switch(target)
3902 {
3903 case GL_GENERATE_MIPMAP_HINT:
3904 if(context) context->setGenerateMipmapHint(mode);
3905 break;
3906 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3907 if(context) context->setFragmentShaderDerivativeHint(mode);
3908 break;
3909 default:
3910 return error(GL_INVALID_ENUM);
3911 }
John Bauman66b8ab22014-05-06 15:57:45 -04003912}
3913
3914GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
3915{
Nicolas Capensf160b172014-11-26 11:58:23 -05003916 TRACE("(GLuint buffer = %d)", buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003917
Nicolas Capensf160b172014-11-26 11:58:23 -05003918 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003919
Nicolas Capensf160b172014-11-26 11:58:23 -05003920 if(context && buffer)
3921 {
3922 es2::Buffer *bufferObject = context->getBuffer(buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003923
Nicolas Capensf160b172014-11-26 11:58:23 -05003924 if(bufferObject)
3925 {
3926 return GL_TRUE;
3927 }
3928 }
John Bauman66b8ab22014-05-06 15:57:45 -04003929
Nicolas Capensf160b172014-11-26 11:58:23 -05003930 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003931}
3932
3933GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
3934{
Nicolas Capensf160b172014-11-26 11:58:23 -05003935 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04003936
Nicolas Capensf160b172014-11-26 11:58:23 -05003937 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003938
Nicolas Capensf160b172014-11-26 11:58:23 -05003939 if(context)
3940 {
3941 switch(cap)
3942 {
3943 case GL_CULL_FACE: return context->isCullFaceEnabled();
3944 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3945 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3946 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3947 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3948 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3949 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3950 case GL_BLEND: return context->isBlendEnabled();
3951 case GL_DITHER: return context->isDitherEnabled();
3952 default:
3953 return error(GL_INVALID_ENUM, false);
3954 }
3955 }
John Bauman66b8ab22014-05-06 15:57:45 -04003956
Nicolas Capensf160b172014-11-26 11:58:23 -05003957 return false;
John Bauman66b8ab22014-05-06 15:57:45 -04003958}
3959
3960GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
3961{
Nicolas Capensf160b172014-11-26 11:58:23 -05003962 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04003963
Nicolas Capensf160b172014-11-26 11:58:23 -05003964 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003965
Nicolas Capensf160b172014-11-26 11:58:23 -05003966 if(context)
3967 {
3968 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04003969
Nicolas Capensf160b172014-11-26 11:58:23 -05003970 if(fenceObject == NULL)
3971 {
3972 return GL_FALSE;
3973 }
John Bauman66b8ab22014-05-06 15:57:45 -04003974
Nicolas Capensf160b172014-11-26 11:58:23 -05003975 return fenceObject->isFence();
3976 }
John Bauman66b8ab22014-05-06 15:57:45 -04003977
Nicolas Capensf160b172014-11-26 11:58:23 -05003978 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003979}
3980
3981GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
3982{
Nicolas Capensf160b172014-11-26 11:58:23 -05003983 TRACE("(GLuint framebuffer = %d)", framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003984
Nicolas Capensf160b172014-11-26 11:58:23 -05003985 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003986
Nicolas Capensf160b172014-11-26 11:58:23 -05003987 if(context && framebuffer)
3988 {
3989 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003990
Nicolas Capensf160b172014-11-26 11:58:23 -05003991 if(framebufferObject)
3992 {
3993 return GL_TRUE;
3994 }
3995 }
John Bauman66b8ab22014-05-06 15:57:45 -04003996
Nicolas Capensf160b172014-11-26 11:58:23 -05003997 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003998}
3999
4000GLboolean GL_APIENTRY glIsProgram(GLuint program)
4001{
Nicolas Capensf160b172014-11-26 11:58:23 -05004002 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004003
Nicolas Capensf160b172014-11-26 11:58:23 -05004004 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004005
Nicolas Capensf160b172014-11-26 11:58:23 -05004006 if(context && program)
4007 {
4008 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004009
Nicolas Capensf160b172014-11-26 11:58:23 -05004010 if(programObject)
4011 {
4012 return GL_TRUE;
4013 }
4014 }
John Bauman66b8ab22014-05-06 15:57:45 -04004015
Nicolas Capensf160b172014-11-26 11:58:23 -05004016 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004017}
4018
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004019GLboolean GL_APIENTRY glIsQueryEXT(GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -04004020{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004021 TRACE("(GLuint name = %d)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04004022
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004023 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05004024 {
4025 return GL_FALSE;
4026 }
John Bauman66b8ab22014-05-06 15:57:45 -04004027
Nicolas Capensf160b172014-11-26 11:58:23 -05004028 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004029
Nicolas Capensf160b172014-11-26 11:58:23 -05004030 if(context)
4031 {
Alexis Hetu8e32f7b2015-04-28 09:59:09 -04004032 es2::Query *queryObject = context->getQuery(name);
John Bauman66b8ab22014-05-06 15:57:45 -04004033
Nicolas Capensf160b172014-11-26 11:58:23 -05004034 if(queryObject)
4035 {
4036 return GL_TRUE;
4037 }
4038 }
John Bauman66b8ab22014-05-06 15:57:45 -04004039
Nicolas Capensf160b172014-11-26 11:58:23 -05004040 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004041}
4042
4043GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
4044{
Nicolas Capensf160b172014-11-26 11:58:23 -05004045 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004046
Nicolas Capensf160b172014-11-26 11:58:23 -05004047 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004048
Nicolas Capensf160b172014-11-26 11:58:23 -05004049 if(context && renderbuffer)
4050 {
4051 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004052
Nicolas Capensf160b172014-11-26 11:58:23 -05004053 if(renderbufferObject)
4054 {
4055 return GL_TRUE;
4056 }
4057 }
John Bauman66b8ab22014-05-06 15:57:45 -04004058
Nicolas Capensf160b172014-11-26 11:58:23 -05004059 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004060}
4061
4062GLboolean GL_APIENTRY glIsShader(GLuint shader)
4063{
Nicolas Capensf160b172014-11-26 11:58:23 -05004064 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004065
Nicolas Capensf160b172014-11-26 11:58:23 -05004066 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004067
Nicolas Capensf160b172014-11-26 11:58:23 -05004068 if(context && shader)
4069 {
4070 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004071
Nicolas Capensf160b172014-11-26 11:58:23 -05004072 if(shaderObject)
4073 {
4074 return GL_TRUE;
4075 }
4076 }
John Bauman66b8ab22014-05-06 15:57:45 -04004077
Nicolas Capensf160b172014-11-26 11:58:23 -05004078 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004079}
4080
4081GLboolean GL_APIENTRY glIsTexture(GLuint texture)
4082{
Nicolas Capensf160b172014-11-26 11:58:23 -05004083 TRACE("(GLuint texture = %d)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004084
Nicolas Capensf160b172014-11-26 11:58:23 -05004085 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004086
Nicolas Capensf160b172014-11-26 11:58:23 -05004087 if(context && texture)
4088 {
4089 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004090
Nicolas Capensf160b172014-11-26 11:58:23 -05004091 if(textureObject)
4092 {
4093 return GL_TRUE;
4094 }
4095 }
John Bauman66b8ab22014-05-06 15:57:45 -04004096
Nicolas Capensf160b172014-11-26 11:58:23 -05004097 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004098}
4099
4100void GL_APIENTRY glLineWidth(GLfloat width)
4101{
Nicolas Capensf160b172014-11-26 11:58:23 -05004102 TRACE("(GLfloat width = %f)", width);
John Bauman66b8ab22014-05-06 15:57:45 -04004103
Nicolas Capensf160b172014-11-26 11:58:23 -05004104 if(width <= 0.0f)
4105 {
4106 return error(GL_INVALID_VALUE);
4107 }
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 context->setLineWidth(width);
4114 }
John Bauman66b8ab22014-05-06 15:57:45 -04004115}
4116
4117void GL_APIENTRY glLinkProgram(GLuint program)
4118{
Nicolas Capensf160b172014-11-26 11:58:23 -05004119 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004120
Nicolas Capensf160b172014-11-26 11:58:23 -05004121 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004122
Nicolas Capensf160b172014-11-26 11:58:23 -05004123 if(context)
4124 {
4125 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004126
Nicolas Capensf160b172014-11-26 11:58:23 -05004127 if(!programObject)
4128 {
4129 if(context->getShader(program))
4130 {
4131 return error(GL_INVALID_OPERATION);
4132 }
4133 else
4134 {
4135 return error(GL_INVALID_VALUE);
4136 }
4137 }
John Bauman66b8ab22014-05-06 15:57:45 -04004138
Nicolas Capensf160b172014-11-26 11:58:23 -05004139 programObject->link();
4140 }
John Bauman66b8ab22014-05-06 15:57:45 -04004141}
4142
4143void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
4144{
Nicolas Capensf160b172014-11-26 11:58:23 -05004145 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04004146
Nicolas Capensf160b172014-11-26 11:58:23 -05004147 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004148
Nicolas Capensf160b172014-11-26 11:58:23 -05004149 if(context)
4150 {
Alexis Hetued306182015-04-02 12:02:28 -04004151 egl::GLint clientVersion = context->getClientVersion();
4152
Nicolas Capensf160b172014-11-26 11:58:23 -05004153 switch(pname)
4154 {
4155 case GL_UNPACK_ALIGNMENT:
4156 if(param != 1 && param != 2 && param != 4 && param != 8)
4157 {
4158 return error(GL_INVALID_VALUE);
4159 }
4160 context->setUnpackAlignment(param);
4161 break;
4162 case GL_PACK_ALIGNMENT:
4163 if(param != 1 && param != 2 && param != 4 && param != 8)
4164 {
4165 return error(GL_INVALID_VALUE);
4166 }
4167 context->setPackAlignment(param);
4168 break;
Alexis Hetued306182015-04-02 12:02:28 -04004169 case GL_PACK_ROW_LENGTH:
4170 case GL_PACK_SKIP_PIXELS:
4171 case GL_PACK_SKIP_ROWS:
4172 case GL_UNPACK_ROW_LENGTH:
4173 case GL_UNPACK_IMAGE_HEIGHT:
4174 case GL_UNPACK_SKIP_PIXELS:
4175 case GL_UNPACK_SKIP_ROWS:
4176 case GL_UNPACK_SKIP_IMAGES:
4177 if(clientVersion >= 3)
4178 {
4179 UNIMPLEMENTED();
4180 break;
4181 }
4182 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05004183 default:
4184 return error(GL_INVALID_ENUM);
4185 }
4186 }
John Bauman66b8ab22014-05-06 15:57:45 -04004187}
4188
4189void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
4190{
Nicolas Capensf160b172014-11-26 11:58:23 -05004191 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
John Bauman66b8ab22014-05-06 15:57:45 -04004192
Nicolas Capensf160b172014-11-26 11:58:23 -05004193 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004194
Nicolas Capensf160b172014-11-26 11:58:23 -05004195 if(context)
4196 {
4197 context->setPolygonOffsetParams(factor, units);
4198 }
John Bauman66b8ab22014-05-06 15:57:45 -04004199}
4200
4201void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05004202 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
John Bauman66b8ab22014-05-06 15:57:45 -04004203{
Nicolas Capensf160b172014-11-26 11:58:23 -05004204 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4205 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4206 x, y, width, height, format, type, bufSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04004207
Nicolas Capensf160b172014-11-26 11:58:23 -05004208 if(width < 0 || height < 0 || bufSize < 0)
4209 {
4210 return error(GL_INVALID_VALUE);
4211 }
John Bauman66b8ab22014-05-06 15:57:45 -04004212
Nicolas Capensf160b172014-11-26 11:58:23 -05004213 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004214
Nicolas Capensf160b172014-11-26 11:58:23 -05004215 if(context)
4216 {
4217 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4218 }
John Bauman66b8ab22014-05-06 15:57:45 -04004219}
4220
4221void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
4222{
Nicolas Capensf160b172014-11-26 11:58:23 -05004223 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4224 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
4225 x, y, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004226
Nicolas Capensf160b172014-11-26 11:58:23 -05004227 if(width < 0 || height < 0)
4228 {
4229 return error(GL_INVALID_VALUE);
4230 }
John Bauman66b8ab22014-05-06 15:57:45 -04004231
Nicolas Capensf160b172014-11-26 11:58:23 -05004232 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004233
Nicolas Capensf160b172014-11-26 11:58:23 -05004234 if(context)
4235 {
4236 context->readPixels(x, y, width, height, format, type, NULL, pixels);
4237 }
John Bauman66b8ab22014-05-06 15:57:45 -04004238}
4239
4240void GL_APIENTRY glReleaseShaderCompiler(void)
4241{
Nicolas Capensf160b172014-11-26 11:58:23 -05004242 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04004243
Nicolas Capensf160b172014-11-26 11:58:23 -05004244 es2::Shader::releaseCompiler();
John Bauman66b8ab22014-05-06 15:57:45 -04004245}
4246
4247void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4248{
Nicolas Capensf160b172014-11-26 11:58:23 -05004249 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4250 target, samples, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004251
Nicolas Capensf160b172014-11-26 11:58:23 -05004252 switch(target)
4253 {
4254 case GL_RENDERBUFFER:
4255 break;
4256 default:
4257 return error(GL_INVALID_ENUM);
4258 }
John Bauman66b8ab22014-05-06 15:57:45 -04004259
Nicolas Capensf160b172014-11-26 11:58:23 -05004260 if(!es2::IsColorRenderable(internalformat) && !es2::IsDepthRenderable(internalformat) && !es2::IsStencilRenderable(internalformat))
4261 {
4262 return error(GL_INVALID_ENUM);
4263 }
John Bauman66b8ab22014-05-06 15:57:45 -04004264
Nicolas Capensf160b172014-11-26 11:58:23 -05004265 if(width < 0 || height < 0 || samples < 0)
4266 {
4267 return error(GL_INVALID_VALUE);
4268 }
John Bauman66b8ab22014-05-06 15:57:45 -04004269
Nicolas Capensf160b172014-11-26 11:58:23 -05004270 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004271
Nicolas Capensf160b172014-11-26 11:58:23 -05004272 if(context)
4273 {
4274 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4275 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4276 samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4277 {
4278 return error(GL_INVALID_VALUE);
4279 }
John Bauman66b8ab22014-05-06 15:57:45 -04004280
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004281 GLuint handle = context->getRenderbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05004282 if(handle == 0)
4283 {
4284 return error(GL_INVALID_OPERATION);
4285 }
John Bauman66b8ab22014-05-06 15:57:45 -04004286
Nicolas Capensf160b172014-11-26 11:58:23 -05004287 switch(internalformat)
4288 {
4289 case GL_DEPTH_COMPONENT16:
4290 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, samples));
4291 break;
4292 case GL_RGBA4:
4293 case GL_RGB5_A1:
4294 case GL_RGB565:
4295 case GL_RGB8_OES:
4296 case GL_RGBA8_OES:
4297 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4298 break;
4299 case GL_STENCIL_INDEX8:
4300 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4301 break;
4302 case GL_DEPTH24_STENCIL8_OES:
4303 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, samples));
4304 break;
4305 default:
4306 return error(GL_INVALID_ENUM);
4307 }
4308 }
John Bauman66b8ab22014-05-06 15:57:45 -04004309}
4310
4311void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4312{
Nicolas Capensf160b172014-11-26 11:58:23 -05004313 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004314}
4315
4316void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
4317{
Nicolas Capensf160b172014-11-26 11:58:23 -05004318 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
John Bauman66b8ab22014-05-06 15:57:45 -04004319
Nicolas Capensf160b172014-11-26 11:58:23 -05004320 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004321
Nicolas Capensf160b172014-11-26 11:58:23 -05004322 if(context)
4323 {
4324 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4325 }
John Bauman66b8ab22014-05-06 15:57:45 -04004326}
4327
4328void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
4329{
Nicolas Capensf160b172014-11-26 11:58:23 -05004330 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
John Bauman66b8ab22014-05-06 15:57:45 -04004331
Nicolas Capensf160b172014-11-26 11:58:23 -05004332 if(condition != GL_ALL_COMPLETED_NV)
4333 {
4334 return error(GL_INVALID_ENUM);
4335 }
John Bauman66b8ab22014-05-06 15:57:45 -04004336
Nicolas Capensf160b172014-11-26 11:58:23 -05004337 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004338
Nicolas Capensf160b172014-11-26 11:58:23 -05004339 if(context)
4340 {
4341 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004342
Nicolas Capensf160b172014-11-26 11:58:23 -05004343 if(fenceObject == NULL)
4344 {
4345 return error(GL_INVALID_OPERATION);
4346 }
John Bauman66b8ab22014-05-06 15:57:45 -04004347
Nicolas Capensf160b172014-11-26 11:58:23 -05004348 fenceObject->setFence(condition);
4349 }
John Bauman66b8ab22014-05-06 15:57:45 -04004350}
4351
4352void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4353{
Nicolas Capensf160b172014-11-26 11:58:23 -05004354 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004355
Nicolas Capensf160b172014-11-26 11:58:23 -05004356 if(width < 0 || height < 0)
4357 {
4358 return error(GL_INVALID_VALUE);
4359 }
John Bauman66b8ab22014-05-06 15:57:45 -04004360
Nicolas Capensf160b172014-11-26 11:58:23 -05004361 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004362
Nicolas Capensf160b172014-11-26 11:58:23 -05004363 if(context)
4364 {
4365 context->setScissorParams(x, y, width, height);
4366 }
John Bauman66b8ab22014-05-06 15:57:45 -04004367}
4368
4369void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4370{
Nicolas Capensf160b172014-11-26 11:58:23 -05004371 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
4372 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
4373 n, shaders, binaryformat, binary, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004374
Nicolas Capensf160b172014-11-26 11:58:23 -05004375 // No binary shader formats are supported.
4376 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04004377}
4378
Nicolas Capensb0e93552014-10-28 11:54:43 -04004379void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
John Bauman66b8ab22014-05-06 15:57:45 -04004380{
Nicolas Capensf160b172014-11-26 11:58:23 -05004381 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
4382 shader, count, string, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004383
Nicolas Capensf160b172014-11-26 11:58:23 -05004384 if(count < 0)
4385 {
4386 return error(GL_INVALID_VALUE);
4387 }
John Bauman66b8ab22014-05-06 15:57:45 -04004388
Nicolas Capensf160b172014-11-26 11:58:23 -05004389 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004390
Nicolas Capensf160b172014-11-26 11:58:23 -05004391 if(context)
4392 {
4393 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004394
Nicolas Capensf160b172014-11-26 11:58:23 -05004395 if(!shaderObject)
4396 {
4397 if(context->getProgram(shader))
4398 {
4399 return error(GL_INVALID_OPERATION);
4400 }
4401 else
4402 {
4403 return error(GL_INVALID_VALUE);
4404 }
4405 }
John Bauman66b8ab22014-05-06 15:57:45 -04004406
Nicolas Capensf160b172014-11-26 11:58:23 -05004407 shaderObject->setSource(count, string, length);
4408 }
John Bauman66b8ab22014-05-06 15:57:45 -04004409}
4410
4411void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
4412{
Nicolas Capensf160b172014-11-26 11:58:23 -05004413 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004414}
4415
4416void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4417{
Nicolas Capensf160b172014-11-26 11:58:23 -05004418 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 -04004419
Nicolas Capensf160b172014-11-26 11:58:23 -05004420 switch(face)
4421 {
4422 case GL_FRONT:
4423 case GL_BACK:
4424 case GL_FRONT_AND_BACK:
4425 break;
4426 default:
4427 return error(GL_INVALID_ENUM);
4428 }
John Bauman66b8ab22014-05-06 15:57:45 -04004429
Nicolas Capensf160b172014-11-26 11:58:23 -05004430 switch(func)
4431 {
4432 case GL_NEVER:
4433 case GL_ALWAYS:
4434 case GL_LESS:
4435 case GL_LEQUAL:
4436 case GL_EQUAL:
4437 case GL_GEQUAL:
4438 case GL_GREATER:
4439 case GL_NOTEQUAL:
4440 break;
4441 default:
4442 return error(GL_INVALID_ENUM);
4443 }
John Bauman66b8ab22014-05-06 15:57:45 -04004444
Nicolas Capensf160b172014-11-26 11:58:23 -05004445 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004446
Nicolas Capensf160b172014-11-26 11:58:23 -05004447 if(context)
4448 {
4449 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4450 {
4451 context->setStencilParams(func, ref, mask);
4452 }
John Bauman66b8ab22014-05-06 15:57:45 -04004453
Nicolas Capensf160b172014-11-26 11:58:23 -05004454 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4455 {
4456 context->setStencilBackParams(func, ref, mask);
4457 }
4458 }
John Bauman66b8ab22014-05-06 15:57:45 -04004459}
4460
4461void GL_APIENTRY glStencilMask(GLuint mask)
4462{
Nicolas Capensf160b172014-11-26 11:58:23 -05004463 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004464}
4465
4466void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
4467{
Nicolas Capensf160b172014-11-26 11:58:23 -05004468 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004469
Nicolas Capensf160b172014-11-26 11:58:23 -05004470 switch(face)
4471 {
4472 case GL_FRONT:
4473 case GL_BACK:
4474 case GL_FRONT_AND_BACK:
4475 break;
4476 default:
4477 return error(GL_INVALID_ENUM);
4478 }
John Bauman66b8ab22014-05-06 15:57:45 -04004479
Nicolas Capensf160b172014-11-26 11:58:23 -05004480 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004481
Nicolas Capensf160b172014-11-26 11:58:23 -05004482 if(context)
4483 {
4484 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4485 {
4486 context->setStencilWritemask(mask);
4487 }
John Bauman66b8ab22014-05-06 15:57:45 -04004488
Nicolas Capensf160b172014-11-26 11:58:23 -05004489 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4490 {
4491 context->setStencilBackWritemask(mask);
4492 }
4493 }
John Bauman66b8ab22014-05-06 15:57:45 -04004494}
4495
4496void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4497{
Nicolas Capensf160b172014-11-26 11:58:23 -05004498 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004499}
4500
4501void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4502{
Nicolas Capensf160b172014-11-26 11:58:23 -05004503 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4504 face, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004505
Nicolas Capensf160b172014-11-26 11:58:23 -05004506 switch(face)
4507 {
4508 case GL_FRONT:
4509 case GL_BACK:
4510 case GL_FRONT_AND_BACK:
4511 break;
4512 default:
4513 return error(GL_INVALID_ENUM);
4514 }
John Bauman66b8ab22014-05-06 15:57:45 -04004515
Nicolas Capensf160b172014-11-26 11:58:23 -05004516 switch(fail)
4517 {
4518 case GL_ZERO:
4519 case GL_KEEP:
4520 case GL_REPLACE:
4521 case GL_INCR:
4522 case GL_DECR:
4523 case GL_INVERT:
4524 case GL_INCR_WRAP:
4525 case GL_DECR_WRAP:
4526 break;
4527 default:
4528 return error(GL_INVALID_ENUM);
4529 }
John Bauman66b8ab22014-05-06 15:57:45 -04004530
Nicolas Capensf160b172014-11-26 11:58:23 -05004531 switch(zfail)
4532 {
4533 case GL_ZERO:
4534 case GL_KEEP:
4535 case GL_REPLACE:
4536 case GL_INCR:
4537 case GL_DECR:
4538 case GL_INVERT:
4539 case GL_INCR_WRAP:
4540 case GL_DECR_WRAP:
4541 break;
4542 default:
4543 return error(GL_INVALID_ENUM);
4544 }
John Bauman66b8ab22014-05-06 15:57:45 -04004545
Nicolas Capensf160b172014-11-26 11:58:23 -05004546 switch(zpass)
4547 {
4548 case GL_ZERO:
4549 case GL_KEEP:
4550 case GL_REPLACE:
4551 case GL_INCR:
4552 case GL_DECR:
4553 case GL_INVERT:
4554 case GL_INCR_WRAP:
4555 case GL_DECR_WRAP:
4556 break;
4557 default:
4558 return error(GL_INVALID_ENUM);
4559 }
John Bauman66b8ab22014-05-06 15:57:45 -04004560
Nicolas Capensf160b172014-11-26 11:58:23 -05004561 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004562
Nicolas Capensf160b172014-11-26 11:58:23 -05004563 if(context)
4564 {
4565 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4566 {
4567 context->setStencilOperations(fail, zfail, zpass);
4568 }
John Bauman66b8ab22014-05-06 15:57:45 -04004569
Nicolas Capensf160b172014-11-26 11:58:23 -05004570 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4571 {
4572 context->setStencilBackOperations(fail, zfail, zpass);
4573 }
4574 }
John Bauman66b8ab22014-05-06 15:57:45 -04004575}
4576
4577GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
4578{
Nicolas Capensf160b172014-11-26 11:58:23 -05004579 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004580
Nicolas Capensf160b172014-11-26 11:58:23 -05004581 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004582
Nicolas Capensf160b172014-11-26 11:58:23 -05004583 if(context)
4584 {
4585 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004586
Nicolas Capensf160b172014-11-26 11:58:23 -05004587 if(fenceObject == NULL)
4588 {
4589 return error(GL_INVALID_OPERATION, GL_TRUE);
4590 }
John Bauman66b8ab22014-05-06 15:57:45 -04004591
Nicolas Capensf160b172014-11-26 11:58:23 -05004592 return fenceObject->testFence();
4593 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05004594
Nicolas Capensf160b172014-11-26 11:58:23 -05004595 return GL_TRUE;
John Bauman66b8ab22014-05-06 15:57:45 -04004596}
4597
4598void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4599 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4600{
Nicolas Capensf160b172014-11-26 11:58:23 -05004601 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4602 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
4603 target, level, internalformat, width, height, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004604
Nicolas Capensf160b172014-11-26 11:58:23 -05004605 if(!validImageSize(level, width, height))
4606 {
4607 return error(GL_INVALID_VALUE);
4608 }
John Bauman66b8ab22014-05-06 15:57:45 -04004609
Nicolas Capensf160b172014-11-26 11:58:23 -05004610 es2::Context *context = es2::getContext();
4611
4612 if(context)
4613 {
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004614 if(context->getClientVersion() < 3)
4615 {
4616 if(internalformat != format)
4617 {
4618 return error(GL_INVALID_OPERATION);
4619 }
4620 }
4621
4622 switch(format)
4623 {
4624 case GL_ALPHA:
4625 case GL_LUMINANCE:
4626 case GL_LUMINANCE_ALPHA:
4627 switch(type)
4628 {
4629 case GL_UNSIGNED_BYTE:
4630 case GL_FLOAT:
4631 case GL_HALF_FLOAT_OES:
4632 break;
4633 default:
4634 return error(GL_INVALID_ENUM);
4635 }
4636 break;
Alexis Hetued306182015-04-02 12:02:28 -04004637 case GL_RED:
4638 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004639 {
Alexis Hetued306182015-04-02 12:02:28 -04004640 case GL_R8:
4641 switch(type)
4642 {
4643 case GL_UNSIGNED_BYTE:
4644 break;
4645 default:
4646 return error(GL_INVALID_ENUM);
4647 }
4648 break;
4649 case GL_R8_SNORM:
4650 switch(type)
4651 {
4652 case GL_BYTE:
4653 break;
4654 default:
4655 return error(GL_INVALID_ENUM);
4656 }
4657 break;
4658 case GL_R16F:
4659 switch(type)
4660 {
4661 case GL_FLOAT:
4662 case GL_HALF_FLOAT:
4663 break;
4664 default:
4665 return error(GL_INVALID_ENUM);
4666 }
4667 break;
4668 case GL_R32F:
4669 switch(type)
4670 {
4671 case GL_FLOAT:
4672 break;
4673 default:
4674 return error(GL_INVALID_ENUM);
4675 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004676 break;
4677 default:
Alexis Hetued306182015-04-02 12:02:28 -04004678 return error(GL_INVALID_VALUE);
4679 }
4680 break;
4681 case GL_RED_INTEGER:
4682 switch(internalformat)
4683 {
4684 case GL_R8UI:
4685 switch(type)
4686 {
4687 case GL_UNSIGNED_BYTE:
4688 break;
4689 default:
4690 return error(GL_INVALID_ENUM);
4691 }
4692 break;
4693 case GL_R8I:
4694 switch(type)
4695 {
4696 case GL_BYTE:
4697 break;
4698 default:
4699 return error(GL_INVALID_ENUM);
4700 }
4701 break;
4702 case GL_R16UI:
4703 switch(type)
4704 {
4705 case GL_UNSIGNED_SHORT:
4706 break;
4707 default:
4708 return error(GL_INVALID_ENUM);
4709 }
4710 break;
4711 case GL_R16I:
4712 switch(type)
4713 {
4714 case GL_SHORT:
4715 break;
4716 default:
4717 return error(GL_INVALID_ENUM);
4718 }
4719 break;
4720 case GL_R32UI:
4721 switch(type)
4722 {
4723 case GL_UNSIGNED_INT:
4724 break;
4725 default:
4726 return error(GL_INVALID_ENUM);
4727 }
4728 break;
4729 case GL_R32I:
4730 switch(type)
4731 {
4732 case GL_INT:
4733 break;
4734 default:
4735 return error(GL_INVALID_ENUM);
4736 }
4737 break;
4738 default:
4739 return error(GL_INVALID_VALUE);
4740 }
4741 break;
4742 case GL_RG_INTEGER:
4743 switch(internalformat)
4744 {
4745 case GL_RG8UI:
4746 switch(type)
4747 {
4748 case GL_UNSIGNED_BYTE:
4749 break;
4750 default:
4751 return error(GL_INVALID_ENUM);
4752 }
4753 break;
4754 case GL_RG8I:
4755 switch(type)
4756 {
4757 case GL_BYTE:
4758 break;
4759 default:
4760 return error(GL_INVALID_ENUM);
4761 }
4762 break;
4763 case GL_RG16UI:
4764 switch(type)
4765 {
4766 case GL_UNSIGNED_SHORT:
4767 break;
4768 default:
4769 return error(GL_INVALID_ENUM);
4770 }
4771 break;
4772 case GL_RG16I:
4773 switch(type)
4774 {
4775 case GL_SHORT:
4776 break;
4777 default:
4778 return error(GL_INVALID_ENUM);
4779 }
4780 break;
4781 case GL_RG32UI:
4782 switch(type)
4783 {
4784 case GL_UNSIGNED_INT:
4785 break;
4786 default:
4787 return error(GL_INVALID_ENUM);
4788 }
4789 break;
4790 case GL_RG32I:
4791 switch(type)
4792 {
4793 case GL_INT:
4794 break;
4795 default:
4796 return error(GL_INVALID_ENUM);
4797 }
4798 break;
4799 default:
4800 return error(GL_INVALID_VALUE);
4801 }
4802 break;
4803 case GL_RGB_INTEGER:
4804 switch(internalformat)
4805 {
4806 case GL_RGB8UI:
4807 switch(type)
4808 {
4809 case GL_UNSIGNED_BYTE:
4810 break;
4811 default:
4812 return error(GL_INVALID_ENUM);
4813 }
4814 break;
4815 case GL_RGB8I:
4816 switch(type)
4817 {
4818 case GL_BYTE:
4819 break;
4820 default:
4821 return error(GL_INVALID_ENUM);
4822 }
4823 break;
4824 case GL_RGB16UI:
4825 switch(type)
4826 {
4827 case GL_UNSIGNED_SHORT:
4828 break;
4829 default:
4830 return error(GL_INVALID_ENUM);
4831 }
4832 break;
4833 case GL_RGB16I:
4834 switch(type)
4835 {
4836 case GL_SHORT:
4837 break;
4838 default:
4839 return error(GL_INVALID_ENUM);
4840 }
4841 break;
4842 case GL_RGB32UI:
4843 switch(type)
4844 {
4845 case GL_UNSIGNED_INT:
4846 break;
4847 default:
4848 return error(GL_INVALID_ENUM);
4849 }
4850 break;
4851 case GL_RGB32I:
4852 switch(type)
4853 {
4854 case GL_INT:
4855 break;
4856 default:
4857 return error(GL_INVALID_ENUM);
4858 }
4859 break;
4860 default:
4861 return error(GL_INVALID_VALUE);
4862 }
4863 break;
4864 case GL_RGBA_INTEGER:
4865 switch(internalformat)
4866 {
4867 case GL_RGBA8UI:
4868 switch(type)
4869 {
4870 case GL_UNSIGNED_BYTE:
4871 break;
4872 default:
4873 return error(GL_INVALID_ENUM);
4874 }
4875 break;
4876 case GL_RGBA8I:
4877 switch(type)
4878 {
4879 case GL_BYTE:
4880 break;
4881 default:
4882 return error(GL_INVALID_ENUM);
4883 }
4884 break;
4885 case GL_RGB10_A2UI:
4886 switch(type)
4887 {
4888 case GL_UNSIGNED_INT_2_10_10_10_REV:
4889 break;
4890 default:
4891 return error(GL_INVALID_ENUM);
4892 }
4893 break;
4894 case GL_RGBA16UI:
4895 switch(type)
4896 {
4897 case GL_UNSIGNED_SHORT:
4898 break;
4899 default:
4900 return error(GL_INVALID_ENUM);
4901 }
4902 break;
4903 case GL_RGBA16I:
4904 switch(type)
4905 {
4906 case GL_SHORT:
4907 break;
4908 default:
4909 return error(GL_INVALID_ENUM);
4910 }
4911 break;
4912 case GL_RGBA32UI:
4913 switch(type)
4914 {
4915 case GL_INT:
4916 break;
4917 default:
4918 return error(GL_INVALID_ENUM);
4919 }
4920 break;
4921 case GL_RGBA32I:
4922 switch(type)
4923 {
4924 case GL_UNSIGNED_INT:
4925 break;
4926 default:
4927 return error(GL_INVALID_ENUM);
4928 }
4929 break;
4930 default:
4931 return error(GL_INVALID_VALUE);
4932 }
4933 break;
4934 case GL_RG:
4935 switch(internalformat)
4936 {
4937 case GL_RG8:
4938 switch(type)
4939 {
4940 case GL_UNSIGNED_BYTE:
4941 break;
4942 default:
4943 return error(GL_INVALID_ENUM);
4944 }
4945 break;
4946 case GL_RG8_SNORM:
4947 switch(type)
4948 {
4949 case GL_BYTE:
4950 break;
4951 default:
4952 return error(GL_INVALID_ENUM);
4953 }
4954 break;
4955 case GL_RG16F:
4956 switch(type)
4957 {
4958 case GL_FLOAT:
4959 case GL_HALF_FLOAT:
4960 break;
4961 default:
4962 return error(GL_INVALID_ENUM);
4963 }
4964 break;
4965 case GL_RG32F:
4966 switch(type)
4967 {
4968 case GL_FLOAT:
4969 break;
4970 default:
4971 return error(GL_INVALID_ENUM);
4972 }
4973 break;
4974 default:
4975 return error(GL_INVALID_VALUE);
4976 }
4977 break;
4978 case GL_RGB:
4979 switch(internalformat)
4980 {
4981 case GL_RGB:
4982 switch(type)
4983 {
4984 case GL_UNSIGNED_BYTE:
4985 case GL_UNSIGNED_SHORT_5_6_5:
4986 case GL_FLOAT:
4987 case GL_HALF_FLOAT_OES:
4988 break;
4989 default:
4990 return error(GL_INVALID_ENUM);
4991 }
4992 break;
4993 case GL_RGB8:
4994 switch(type)
4995 {
4996 case GL_UNSIGNED_BYTE:
4997 break;
4998 default:
4999 return error(GL_INVALID_ENUM);
5000 }
5001 break;
5002 case GL_SRGB8:
5003 switch(type)
5004 {
5005 case GL_UNSIGNED_BYTE:
5006 break;
5007 default:
5008 return error(GL_INVALID_ENUM);
5009 }
5010 break;
5011 case GL_RGB565:
5012 switch(type)
5013 {
5014 case GL_UNSIGNED_BYTE:
5015 case GL_UNSIGNED_SHORT_5_6_5:
5016 break;
5017 default:
5018 return error(GL_INVALID_ENUM);
5019 }
5020 break;
5021 case GL_RGB8_SNORM:
5022 switch(type)
5023 {
5024 case GL_BYTE:
5025 break;
5026 default:
5027 return error(GL_INVALID_ENUM);
5028 }
5029 break;
5030 case GL_R11F_G11F_B10F:
5031 switch(type)
5032 {
5033 case GL_UNSIGNED_INT_10F_11F_11F_REV:
5034 case GL_FLOAT:
5035 case GL_HALF_FLOAT:
5036 break;
5037 default:
5038 return error(GL_INVALID_ENUM);
5039 }
5040 break;
5041 case GL_RGB9_E5:
5042 switch(type)
5043 {
5044 case GL_UNSIGNED_INT_5_9_9_9_REV:
5045 case GL_FLOAT:
5046 case GL_HALF_FLOAT:
5047 break;
5048 default:
5049 return error(GL_INVALID_ENUM);
5050 }
5051 break;
5052 case GL_RGB16F:
5053 switch(type)
5054 {
5055 case GL_FLOAT:
5056 case GL_HALF_FLOAT:
5057 break;
5058 default:
5059 return error(GL_INVALID_ENUM);
5060 }
5061 break;
5062 case GL_RGB32F:
5063 switch(type)
5064 {
5065 case GL_FLOAT:
5066 break;
5067 default:
5068 return error(GL_INVALID_ENUM);
5069 }
5070 break;
5071 default:
5072 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005073 }
5074 break;
5075 case GL_RGBA:
Alexis Hetued306182015-04-02 12:02:28 -04005076 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005077 {
Alexis Hetued306182015-04-02 12:02:28 -04005078 case GL_RGBA:
5079 switch(type)
5080 {
5081 case GL_UNSIGNED_BYTE:
5082 case GL_UNSIGNED_SHORT_4_4_4_4:
5083 case GL_UNSIGNED_SHORT_5_5_5_1:
5084 case GL_FLOAT:
5085 case GL_HALF_FLOAT_OES:
5086 break;
5087 default:
5088 return error(GL_INVALID_ENUM);
5089 }
5090 break;
5091 case GL_RGBA8:
5092 switch(type)
5093 {
5094 case GL_UNSIGNED_BYTE:
5095 break;
5096 default:
5097 return error(GL_INVALID_ENUM);
5098 }
5099 break;
5100 case GL_SRGB8_ALPHA8:
5101 switch(type)
5102 {
5103 case GL_UNSIGNED_BYTE:
5104 break;
5105 default:
5106 return error(GL_INVALID_ENUM);
5107 }
5108 break;
5109 case GL_RGB5_A1:
5110 switch(type)
5111 {
5112 case GL_UNSIGNED_BYTE:
5113 case GL_UNSIGNED_SHORT_5_5_5_1:
5114 case GL_UNSIGNED_INT_2_10_10_10_REV:
5115 break;
5116 default:
5117 return error(GL_INVALID_ENUM);
5118 }
5119 break;
5120 case GL_RGBA8_SNORM:
5121 switch(type)
5122 {
5123 case GL_BYTE:
5124 break;
5125 default:
5126 return error(GL_INVALID_ENUM);
5127 }
5128 break;
5129 case GL_RGBA4:
5130 switch(type)
5131 {
5132 case GL_UNSIGNED_BYTE:
5133 case GL_UNSIGNED_SHORT_4_4_4_4:
5134 break;
5135 default:
5136 return error(GL_INVALID_ENUM);
5137 }
5138 break;
5139 case GL_RGB10_A2:
5140 switch(type)
5141 {
5142 case GL_UNSIGNED_INT_2_10_10_10_REV:
5143 break;
5144 default:
5145 return error(GL_INVALID_ENUM);
5146 }
5147 break;
5148 case GL_RGBA16F:
5149 switch(type)
5150 {
5151 case GL_FLOAT:
5152 case GL_HALF_FLOAT:
5153 break;
5154 default:
5155 return error(GL_INVALID_ENUM);
5156 }
5157 break;
5158 case GL_RGBA32F:
5159 switch(type)
5160 {
5161 case GL_FLOAT:
5162 break;
5163 default:
5164 return error(GL_INVALID_ENUM);
5165 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005166 break;
5167 default:
Alexis Hetued306182015-04-02 12:02:28 -04005168 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005169 }
5170 break;
5171 case GL_BGRA_EXT:
5172 switch(type)
5173 {
5174 case GL_UNSIGNED_BYTE:
5175 break;
5176 default:
5177 return error(GL_INVALID_ENUM);
5178 }
5179 break;
5180 case GL_ETC1_RGB8_OES:
5181 return error(GL_INVALID_OPERATION);
5182 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5183 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5184 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5185 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5186 if(S3TC_SUPPORT)
5187 {
5188 return error(GL_INVALID_OPERATION);
5189 }
5190 else
5191 {
5192 return error(GL_INVALID_ENUM);
5193 }
5194 case GL_DEPTH_COMPONENT:
Alexis Hetued306182015-04-02 12:02:28 -04005195 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005196 {
Alexis Hetued306182015-04-02 12:02:28 -04005197 case GL_DEPTH_COMPONENT:
5198 case GL_DEPTH_COMPONENT16:
5199 switch(type)
5200 {
5201 case GL_UNSIGNED_SHORT:
5202 case GL_UNSIGNED_INT:
5203 break;
5204 default:
5205 return error(GL_INVALID_ENUM);
5206 }
5207 break;
5208 case GL_DEPTH_COMPONENT24:
5209 switch(type)
5210 {
5211 case GL_UNSIGNED_INT:
5212 break;
5213 default:
5214 return error(GL_INVALID_ENUM);
5215 }
5216 break;
5217 case GL_DEPTH_COMPONENT32F:
5218 switch(type)
5219 {
5220 case GL_UNSIGNED_INT:
5221 break;
5222 default:
5223 return error(GL_INVALID_ENUM);
5224 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005225 break;
5226 default:
Alexis Hetued306182015-04-02 12:02:28 -04005227 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005228 }
5229 break;
5230 case GL_DEPTH_STENCIL_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005231 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005232 {
Alexis Hetued306182015-04-02 12:02:28 -04005233 case GL_DEPTH_STENCIL_OES:
5234 case GL_DEPTH24_STENCIL8:
5235 switch(type)
5236 {
5237 case GL_UNSIGNED_INT_24_8_OES:
5238 break;
5239 default:
5240 return error(GL_INVALID_ENUM);
5241 }
5242 break;
5243 case GL_DEPTH32F_STENCIL8:
5244 switch(type)
5245 {
5246 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
5247 break;
5248 default:
5249 return error(GL_INVALID_ENUM);
5250 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005251 break;
5252 default:
Alexis Hetued306182015-04-02 12:02:28 -04005253 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005254 }
5255 break;
5256 default:
5257 return error(GL_INVALID_VALUE);
5258 }
5259
5260 if(border != 0)
5261 {
5262 return error(GL_INVALID_VALUE);
5263 }
5264
Nicolas Capensf160b172014-11-26 11:58:23 -05005265 switch(target)
5266 {
Nicolas Capens22658242014-11-29 00:31:41 -05005267 case GL_TEXTURE_2D:
Nicolas Capensf160b172014-11-26 11:58:23 -05005268 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5269 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
John Bauman66b8ab22014-05-06 15:57:45 -04005270 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005271 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005272 }
5273 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005274 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5275 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5276 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5277 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5278 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5279 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
Nicolas Capensf160b172014-11-26 11:58:23 -05005280 if(width != height)
John Bauman66b8ab22014-05-06 15:57:45 -04005281 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005282 return error(GL_INVALID_VALUE);
5283 }
5284
5285 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5286 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5287 {
5288 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005289 }
5290 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005291 default:
Nicolas Capensf160b172014-11-26 11:58:23 -05005292 return error(GL_INVALID_ENUM);
5293 }
John Bauman66b8ab22014-05-06 15:57:45 -04005294
Nicolas Capensf160b172014-11-26 11:58:23 -05005295 if(target == GL_TEXTURE_2D)
5296 {
5297 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005298
Nicolas Capensf160b172014-11-26 11:58:23 -05005299 if(!texture)
5300 {
5301 return error(GL_INVALID_OPERATION);
5302 }
John Bauman66b8ab22014-05-06 15:57:45 -04005303
Nicolas Capensf160b172014-11-26 11:58:23 -05005304 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
5305 }
5306 else
5307 {
5308 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04005309
Nicolas Capensf160b172014-11-26 11:58:23 -05005310 if(!texture)
5311 {
5312 return error(GL_INVALID_OPERATION);
5313 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005314
Nicolas Capensf160b172014-11-26 11:58:23 -05005315 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
5316 }
5317 }
John Bauman66b8ab22014-05-06 15:57:45 -04005318}
5319
5320void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5321{
Nicolas Capensf160b172014-11-26 11:58:23 -05005322 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005323
Nicolas Capensf160b172014-11-26 11:58:23 -05005324 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005325
Nicolas Capensf160b172014-11-26 11:58:23 -05005326 if(context)
5327 {
5328 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005329
Alexis Hetued306182015-04-02 12:02:28 -04005330 egl::GLint clientVersion = context->getClientVersion();
5331
Nicolas Capensf160b172014-11-26 11:58:23 -05005332 switch(target)
5333 {
5334 case GL_TEXTURE_2D:
5335 texture = context->getTexture2D();
5336 break;
Alexis Hetued306182015-04-02 12:02:28 -04005337 case GL_TEXTURE_2D_ARRAY:
5338 if(clientVersion < 3)
5339 {
5340 return error(GL_INVALID_ENUM);
5341 }
5342 else
5343 {
5344 UNIMPLEMENTED();
5345 texture = context->getTexture3D();
5346 break;
5347 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005348 case GL_TEXTURE_3D_OES:
5349 texture = context->getTexture3D();
5350 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005351 case GL_TEXTURE_CUBE_MAP:
5352 texture = context->getTextureCubeMap();
5353 break;
5354 case GL_TEXTURE_EXTERNAL_OES:
5355 texture = context->getTextureExternal();
5356 break;
5357 default:
5358 return error(GL_INVALID_ENUM);
5359 }
John Bauman66b8ab22014-05-06 15:57:45 -04005360
Nicolas Capensf160b172014-11-26 11:58:23 -05005361 switch(pname)
5362 {
5363 case GL_TEXTURE_WRAP_S:
5364 if(!texture->setWrapS((GLenum)param))
5365 {
5366 return error(GL_INVALID_ENUM);
5367 }
5368 break;
5369 case GL_TEXTURE_WRAP_T:
5370 if(!texture->setWrapT((GLenum)param))
5371 {
5372 return error(GL_INVALID_ENUM);
5373 }
5374 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005375 case GL_TEXTURE_WRAP_R_OES:
5376 if(!texture->setWrapR((GLenum)param))
5377 {
5378 return error(GL_INVALID_ENUM);
5379 }
5380 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005381 case GL_TEXTURE_MIN_FILTER:
5382 if(!texture->setMinFilter((GLenum)param))
5383 {
5384 return error(GL_INVALID_ENUM);
5385 }
5386 break;
5387 case GL_TEXTURE_MAG_FILTER:
5388 if(!texture->setMagFilter((GLenum)param))
5389 {
5390 return error(GL_INVALID_ENUM);
5391 }
5392 break;
5393 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5394 if(!texture->setMaxAnisotropy(param))
5395 {
5396 return error(GL_INVALID_VALUE);
5397 }
5398 break;
Alexis Hetued306182015-04-02 12:02:28 -04005399 case GL_TEXTURE_BASE_LEVEL:
5400 if(clientVersion < 3 || !texture->setBaseLevel((GLint)param))
5401 {
5402 return error(GL_INVALID_VALUE);
5403 }
5404 break;
5405 case GL_TEXTURE_COMPARE_FUNC:
5406 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5407 {
5408 return error(GL_INVALID_VALUE);
5409 }
5410 break;
5411 case GL_TEXTURE_COMPARE_MODE:
5412 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5413 {
5414 return error(GL_INVALID_VALUE);
5415 }
5416 break;
5417 case GL_TEXTURE_IMMUTABLE_FORMAT:
5418 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5419 {
5420 return error(GL_INVALID_VALUE);
5421 }
5422 break;
5423 case GL_TEXTURE_MAX_LEVEL:
5424 if(clientVersion < 3 || !texture->setMaxLevel((GLint)param))
5425 {
5426 return error(GL_INVALID_VALUE);
5427 }
5428 break;
5429 case GL_TEXTURE_MAX_LOD:
5430 if(clientVersion < 3 || !texture->setMaxLOD(param))
5431 {
5432 return error(GL_INVALID_VALUE);
5433 }
5434 break;
5435 case GL_TEXTURE_MIN_LOD:
5436 if(clientVersion < 3 || !texture->setMinLOD(param))
5437 {
5438 return error(GL_INVALID_VALUE);
5439 }
5440 break;
5441 case GL_TEXTURE_SWIZZLE_R:
5442 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5443 {
5444 return error(GL_INVALID_VALUE);
5445 }
5446 break;
5447 case GL_TEXTURE_SWIZZLE_G:
5448 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5449 {
5450 return error(GL_INVALID_VALUE);
5451 }
5452 break;
5453 case GL_TEXTURE_SWIZZLE_B:
5454 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5455 {
5456 return error(GL_INVALID_VALUE);
5457 }
5458 break;
5459 case GL_TEXTURE_SWIZZLE_A:
5460 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5461 {
5462 return error(GL_INVALID_VALUE);
5463 }
5464 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005465 default:
5466 return error(GL_INVALID_ENUM);
5467 }
5468 }
John Bauman66b8ab22014-05-06 15:57:45 -04005469}
5470
5471void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5472{
Nicolas Capensf160b172014-11-26 11:58:23 -05005473 glTexParameterf(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005474}
5475
5476void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
5477{
Nicolas Capensf160b172014-11-26 11:58:23 -05005478 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005479
Nicolas Capensf160b172014-11-26 11:58:23 -05005480 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005481
Nicolas Capensf160b172014-11-26 11:58:23 -05005482 if(context)
5483 {
5484 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005485
Alexis Hetued306182015-04-02 12:02:28 -04005486 egl::GLint clientVersion = context->getClientVersion();
5487
Nicolas Capensf160b172014-11-26 11:58:23 -05005488 switch(target)
5489 {
5490 case GL_TEXTURE_2D:
5491 texture = context->getTexture2D();
5492 break;
Alexis Hetued306182015-04-02 12:02:28 -04005493 case GL_TEXTURE_2D_ARRAY:
5494 if(clientVersion < 3)
5495 {
5496 return error(GL_INVALID_ENUM);
5497 }
5498 else
5499 {
5500 UNIMPLEMENTED();
5501 texture = context->getTexture3D();
5502 break;
5503 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005504 case GL_TEXTURE_3D_OES:
5505 texture = context->getTexture3D();
5506 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005507 case GL_TEXTURE_CUBE_MAP:
5508 texture = context->getTextureCubeMap();
5509 break;
5510 case GL_TEXTURE_EXTERNAL_OES:
Alexis Hetuf7be67f2015-02-11 16:11:07 -05005511 texture = context->getTextureExternal();
5512 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005513 default:
5514 return error(GL_INVALID_ENUM);
5515 }
John Bauman66b8ab22014-05-06 15:57:45 -04005516
Nicolas Capensf160b172014-11-26 11:58:23 -05005517 switch(pname)
5518 {
5519 case GL_TEXTURE_WRAP_S:
5520 if(!texture->setWrapS((GLenum)param))
5521 {
5522 return error(GL_INVALID_ENUM);
5523 }
5524 break;
5525 case GL_TEXTURE_WRAP_T:
5526 if(!texture->setWrapT((GLenum)param))
5527 {
5528 return error(GL_INVALID_ENUM);
5529 }
5530 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005531 case GL_TEXTURE_WRAP_R_OES:
5532 if(!texture->setWrapR((GLenum)param))
5533 {
5534 return error(GL_INVALID_ENUM);
5535 }
5536 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005537 case GL_TEXTURE_MIN_FILTER:
5538 if(!texture->setMinFilter((GLenum)param))
5539 {
5540 return error(GL_INVALID_ENUM);
5541 }
5542 break;
5543 case GL_TEXTURE_MAG_FILTER:
5544 if(!texture->setMagFilter((GLenum)param))
5545 {
5546 return error(GL_INVALID_ENUM);
5547 }
5548 break;
5549 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5550 if(!texture->setMaxAnisotropy((GLfloat)param))
5551 {
5552 return error(GL_INVALID_VALUE);
5553 }
5554 break;
Alexis Hetued306182015-04-02 12:02:28 -04005555 case GL_TEXTURE_BASE_LEVEL:
5556 if(clientVersion < 3 || !texture->setBaseLevel(param))
5557 {
5558 return error(GL_INVALID_VALUE);
5559 }
5560 break;
5561 case GL_TEXTURE_COMPARE_FUNC:
5562 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5563 {
5564 return error(GL_INVALID_VALUE);
5565 }
5566 break;
5567 case GL_TEXTURE_COMPARE_MODE:
5568 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5569 {
5570 return error(GL_INVALID_VALUE);
5571 }
5572 case GL_TEXTURE_IMMUTABLE_FORMAT:
5573 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5574 {
5575 return error(GL_INVALID_VALUE);
5576 }
5577 break;
5578 case GL_TEXTURE_MAX_LEVEL:
5579 if(clientVersion < 3 || !texture->setMaxLevel(param))
5580 {
5581 return error(GL_INVALID_VALUE);
5582 }
5583 break;
5584 case GL_TEXTURE_MAX_LOD:
5585 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5586 {
5587 return error(GL_INVALID_VALUE);
5588 }
5589 break;
5590 case GL_TEXTURE_MIN_LOD:
5591 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5592 {
5593 return error(GL_INVALID_VALUE);
5594 }
5595 break;
5596 case GL_TEXTURE_SWIZZLE_R:
5597 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5598 {
5599 return error(GL_INVALID_VALUE);
5600 }
5601 break;
5602 case GL_TEXTURE_SWIZZLE_G:
5603 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5604 {
5605 return error(GL_INVALID_VALUE);
5606 }
5607 break;
5608 case GL_TEXTURE_SWIZZLE_B:
5609 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5610 {
5611 return error(GL_INVALID_VALUE);
5612 }
5613 break;
5614 case GL_TEXTURE_SWIZZLE_A:
5615 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5616 {
5617 return error(GL_INVALID_VALUE);
5618 }
5619 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005620 default:
5621 return error(GL_INVALID_ENUM);
5622 }
5623 }
John Bauman66b8ab22014-05-06 15:57:45 -04005624}
5625
5626void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5627{
Nicolas Capensf160b172014-11-26 11:58:23 -05005628 glTexParameteri(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005629}
5630
5631void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05005632 GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04005633{
Nicolas Capensf160b172014-11-26 11:58:23 -05005634 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5635 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
5636 "const GLvoid* pixels = 0x%0.8p)",
5637 target, level, xoffset, yoffset, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04005638
Nicolas Capensf160b172014-11-26 11:58:23 -05005639 if(!es2::IsTextureTarget(target))
5640 {
5641 return error(GL_INVALID_ENUM);
5642 }
John Bauman66b8ab22014-05-06 15:57:45 -04005643
Nicolas Capensf160b172014-11-26 11:58:23 -05005644 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5645 {
5646 return error(GL_INVALID_VALUE);
5647 }
John Bauman66b8ab22014-05-06 15:57:45 -04005648
Nicolas Capensf160b172014-11-26 11:58:23 -05005649 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5650 {
5651 return error(GL_INVALID_VALUE);
5652 }
John Bauman66b8ab22014-05-06 15:57:45 -04005653
Nicolas Capensf160b172014-11-26 11:58:23 -05005654 if(!es2::CheckTextureFormatType(format, type))
5655 {
5656 return error(GL_INVALID_ENUM);
5657 }
John Bauman66b8ab22014-05-06 15:57:45 -04005658
Nicolas Capensf160b172014-11-26 11:58:23 -05005659 if(width == 0 || height == 0 || pixels == NULL)
5660 {
5661 return;
5662 }
John Bauman66b8ab22014-05-06 15:57:45 -04005663
Nicolas Capensf160b172014-11-26 11:58:23 -05005664 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005665
Nicolas Capensf160b172014-11-26 11:58:23 -05005666 if(context)
5667 {
Alexis Hetub027aa92015-01-19 15:56:12 -05005668 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05005669 {
5670 return error(GL_INVALID_VALUE);
5671 }
John Bauman66b8ab22014-05-06 15:57:45 -04005672
Nicolas Capensf160b172014-11-26 11:58:23 -05005673 if(target == GL_TEXTURE_2D)
5674 {
5675 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005676
Nicolas Capensf160b172014-11-26 11:58:23 -05005677 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5678 {
5679 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5680 }
5681 }
5682 else if(es2::IsCubemapTextureTarget(target))
5683 {
5684 es2::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens08e90f02014-11-21 12:49:12 -05005685
Nicolas Capensf160b172014-11-26 11:58:23 -05005686 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5687 {
5688 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5689 }
5690 }
5691 else
5692 {
5693 UNREACHABLE();
5694 }
5695 }
John Bauman66b8ab22014-05-06 15:57:45 -04005696}
5697
5698void GL_APIENTRY glUniform1f(GLint location, GLfloat x)
5699{
Nicolas Capensf160b172014-11-26 11:58:23 -05005700 glUniform1fv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005701}
5702
5703void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5704{
Nicolas Capensf160b172014-11-26 11:58:23 -05005705 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005706
Nicolas Capensf160b172014-11-26 11:58:23 -05005707 if(count < 0)
5708 {
5709 return error(GL_INVALID_VALUE);
5710 }
John Bauman66b8ab22014-05-06 15:57:45 -04005711
Nicolas Capensf160b172014-11-26 11:58:23 -05005712 if(location == -1)
5713 {
5714 return;
5715 }
John Bauman66b8ab22014-05-06 15:57:45 -04005716
Nicolas Capensf160b172014-11-26 11:58:23 -05005717 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005718
Nicolas Capensf160b172014-11-26 11:58:23 -05005719 if(context)
5720 {
5721 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005722
Nicolas Capensf160b172014-11-26 11:58:23 -05005723 if(!program)
5724 {
5725 return error(GL_INVALID_OPERATION);
5726 }
John Bauman66b8ab22014-05-06 15:57:45 -04005727
Nicolas Capensf160b172014-11-26 11:58:23 -05005728 if(!program->setUniform1fv(location, count, v))
5729 {
5730 return error(GL_INVALID_OPERATION);
5731 }
5732 }
John Bauman66b8ab22014-05-06 15:57:45 -04005733}
5734
5735void GL_APIENTRY glUniform1i(GLint location, GLint x)
5736{
Nicolas Capensf160b172014-11-26 11:58:23 -05005737 glUniform1iv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005738}
5739
5740void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
5741{
Nicolas Capensf160b172014-11-26 11:58:23 -05005742 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005743
Nicolas Capensf160b172014-11-26 11:58:23 -05005744 if(count < 0)
5745 {
5746 return error(GL_INVALID_VALUE);
5747 }
John Bauman66b8ab22014-05-06 15:57:45 -04005748
Nicolas Capensf160b172014-11-26 11:58:23 -05005749 if(location == -1)
5750 {
5751 return;
5752 }
John Bauman66b8ab22014-05-06 15:57:45 -04005753
Nicolas Capensf160b172014-11-26 11:58:23 -05005754 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005755
Nicolas Capensf160b172014-11-26 11:58:23 -05005756 if(context)
5757 {
5758 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005759
Nicolas Capensf160b172014-11-26 11:58:23 -05005760 if(!program)
5761 {
5762 return error(GL_INVALID_OPERATION);
5763 }
John Bauman66b8ab22014-05-06 15:57:45 -04005764
Nicolas Capensf160b172014-11-26 11:58:23 -05005765 if(!program->setUniform1iv(location, count, v))
5766 {
5767 return error(GL_INVALID_OPERATION);
5768 }
5769 }
John Bauman66b8ab22014-05-06 15:57:45 -04005770}
5771
5772void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
5773{
Nicolas Capensf160b172014-11-26 11:58:23 -05005774 GLfloat xy[2] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005775
Nicolas Capensf160b172014-11-26 11:58:23 -05005776 glUniform2fv(location, 1, (GLfloat*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005777}
5778
5779void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5780{
Nicolas Capensf160b172014-11-26 11:58:23 -05005781 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005782
Nicolas Capensf160b172014-11-26 11:58:23 -05005783 if(count < 0)
5784 {
5785 return error(GL_INVALID_VALUE);
5786 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005787
Nicolas Capensf160b172014-11-26 11:58:23 -05005788 if(location == -1)
5789 {
5790 return;
5791 }
John Bauman66b8ab22014-05-06 15:57:45 -04005792
Nicolas Capensf160b172014-11-26 11:58:23 -05005793 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005794
Nicolas Capensf160b172014-11-26 11:58:23 -05005795 if(context)
5796 {
5797 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005798
Nicolas Capensf160b172014-11-26 11:58:23 -05005799 if(!program)
5800 {
5801 return error(GL_INVALID_OPERATION);
5802 }
John Bauman66b8ab22014-05-06 15:57:45 -04005803
Nicolas Capensf160b172014-11-26 11:58:23 -05005804 if(!program->setUniform2fv(location, count, v))
5805 {
5806 return error(GL_INVALID_OPERATION);
5807 }
5808 }
John Bauman66b8ab22014-05-06 15:57:45 -04005809}
5810
5811void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)
5812{
Nicolas Capensf160b172014-11-26 11:58:23 -05005813 GLint xy[4] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005814
Nicolas Capensf160b172014-11-26 11:58:23 -05005815 glUniform2iv(location, 1, (GLint*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005816}
5817
5818void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
5819{
Nicolas Capensf160b172014-11-26 11:58:23 -05005820 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005821
Nicolas Capensf160b172014-11-26 11:58:23 -05005822 if(count < 0)
5823 {
5824 return error(GL_INVALID_VALUE);
5825 }
John Bauman66b8ab22014-05-06 15:57:45 -04005826
Nicolas Capensf160b172014-11-26 11:58:23 -05005827 if(location == -1)
5828 {
5829 return;
5830 }
John Bauman66b8ab22014-05-06 15:57:45 -04005831
Nicolas Capensf160b172014-11-26 11:58:23 -05005832 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005833
Nicolas Capensf160b172014-11-26 11:58:23 -05005834 if(context)
5835 {
5836 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005837
Nicolas Capensf160b172014-11-26 11:58:23 -05005838 if(!program)
5839 {
5840 return error(GL_INVALID_OPERATION);
5841 }
John Bauman66b8ab22014-05-06 15:57:45 -04005842
Nicolas Capensf160b172014-11-26 11:58:23 -05005843 if(!program->setUniform2iv(location, count, v))
5844 {
5845 return error(GL_INVALID_OPERATION);
5846 }
5847 }
John Bauman66b8ab22014-05-06 15:57:45 -04005848}
5849
5850void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5851{
Nicolas Capensf160b172014-11-26 11:58:23 -05005852 GLfloat xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04005853
Nicolas Capensf160b172014-11-26 11:58:23 -05005854 glUniform3fv(location, 1, (GLfloat*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04005855}
5856
5857void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5858{
Nicolas Capensf160b172014-11-26 11:58:23 -05005859 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005860
Nicolas Capensf160b172014-11-26 11:58:23 -05005861 if(count < 0)
5862 {
5863 return error(GL_INVALID_VALUE);
5864 }
John Bauman66b8ab22014-05-06 15:57:45 -04005865
Nicolas Capensf160b172014-11-26 11:58:23 -05005866 if(location == -1)
5867 {
5868 return;
5869 }
John Bauman66b8ab22014-05-06 15:57:45 -04005870
Nicolas Capensf160b172014-11-26 11:58:23 -05005871 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005872
Nicolas Capensf160b172014-11-26 11:58:23 -05005873 if(context)
5874 {
5875 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005876
Nicolas Capensf160b172014-11-26 11:58:23 -05005877 if(!program)
5878 {
5879 return error(GL_INVALID_OPERATION);
5880 }
John Bauman66b8ab22014-05-06 15:57:45 -04005881
Nicolas Capensf160b172014-11-26 11:58:23 -05005882 if(!program->setUniform3fv(location, count, v))
5883 {
5884 return error(GL_INVALID_OPERATION);
5885 }
5886 }
John Bauman66b8ab22014-05-06 15:57:45 -04005887}
5888
5889void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
5890{
Nicolas Capensf160b172014-11-26 11:58:23 -05005891 GLint xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04005892
Nicolas Capensf160b172014-11-26 11:58:23 -05005893 glUniform3iv(location, 1, (GLint*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04005894}
5895
5896void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
5897{
Nicolas Capensf160b172014-11-26 11:58:23 -05005898 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005899
Nicolas Capensf160b172014-11-26 11:58:23 -05005900 if(count < 0)
5901 {
5902 return error(GL_INVALID_VALUE);
5903 }
John Bauman66b8ab22014-05-06 15:57:45 -04005904
Nicolas Capensf160b172014-11-26 11:58:23 -05005905 if(location == -1)
5906 {
5907 return;
5908 }
John Bauman66b8ab22014-05-06 15:57:45 -04005909
Nicolas Capensf160b172014-11-26 11:58:23 -05005910 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005911
Nicolas Capensf160b172014-11-26 11:58:23 -05005912 if(context)
5913 {
5914 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005915
Nicolas Capensf160b172014-11-26 11:58:23 -05005916 if(!program)
5917 {
5918 return error(GL_INVALID_OPERATION);
5919 }
John Bauman66b8ab22014-05-06 15:57:45 -04005920
Nicolas Capensf160b172014-11-26 11:58:23 -05005921 if(!program->setUniform3iv(location, count, v))
5922 {
5923 return error(GL_INVALID_OPERATION);
5924 }
5925 }
John Bauman66b8ab22014-05-06 15:57:45 -04005926}
5927
5928void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5929{
Nicolas Capensf160b172014-11-26 11:58:23 -05005930 GLfloat xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04005931
Nicolas Capensf160b172014-11-26 11:58:23 -05005932 glUniform4fv(location, 1, (GLfloat*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04005933}
5934
5935void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5936{
Nicolas Capensf160b172014-11-26 11:58:23 -05005937 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005938
Nicolas Capensf160b172014-11-26 11:58:23 -05005939 if(count < 0)
5940 {
5941 return error(GL_INVALID_VALUE);
5942 }
John Bauman66b8ab22014-05-06 15:57:45 -04005943
Nicolas Capensf160b172014-11-26 11:58:23 -05005944 if(location == -1)
5945 {
5946 return;
5947 }
John Bauman66b8ab22014-05-06 15:57:45 -04005948
Nicolas Capensf160b172014-11-26 11:58:23 -05005949 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005950
Nicolas Capensf160b172014-11-26 11:58:23 -05005951 if(context)
5952 {
5953 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005954
Nicolas Capensf160b172014-11-26 11:58:23 -05005955 if(!program)
5956 {
5957 return error(GL_INVALID_OPERATION);
5958 }
John Bauman66b8ab22014-05-06 15:57:45 -04005959
Nicolas Capensf160b172014-11-26 11:58:23 -05005960 if(!program->setUniform4fv(location, count, v))
5961 {
5962 return error(GL_INVALID_OPERATION);
5963 }
5964 }
John Bauman66b8ab22014-05-06 15:57:45 -04005965}
5966
5967void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5968{
Nicolas Capensf160b172014-11-26 11:58:23 -05005969 GLint xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04005970
Nicolas Capensf160b172014-11-26 11:58:23 -05005971 glUniform4iv(location, 1, (GLint*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04005972}
5973
5974void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
5975{
Nicolas Capensf160b172014-11-26 11:58:23 -05005976 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005977
Nicolas Capensf160b172014-11-26 11:58:23 -05005978 if(count < 0)
5979 {
5980 return error(GL_INVALID_VALUE);
5981 }
John Bauman66b8ab22014-05-06 15:57:45 -04005982
Nicolas Capensf160b172014-11-26 11:58:23 -05005983 if(location == -1)
5984 {
5985 return;
5986 }
John Bauman66b8ab22014-05-06 15:57:45 -04005987
Nicolas Capensf160b172014-11-26 11:58:23 -05005988 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005989
Nicolas Capensf160b172014-11-26 11:58:23 -05005990 if(context)
5991 {
5992 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005993
Nicolas Capensf160b172014-11-26 11:58:23 -05005994 if(!program)
5995 {
5996 return error(GL_INVALID_OPERATION);
5997 }
John Bauman66b8ab22014-05-06 15:57:45 -04005998
Nicolas Capensf160b172014-11-26 11:58:23 -05005999 if(!program->setUniform4iv(location, count, v))
6000 {
6001 return error(GL_INVALID_OPERATION);
6002 }
6003 }
John Bauman66b8ab22014-05-06 15:57:45 -04006004}
6005
6006void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6007{
Nicolas Capensf160b172014-11-26 11:58:23 -05006008 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
6009 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006010
Nicolas Capensf160b172014-11-26 11:58:23 -05006011 if(count < 0 || transpose != GL_FALSE)
6012 {
6013 return error(GL_INVALID_VALUE);
6014 }
John Bauman66b8ab22014-05-06 15:57:45 -04006015
Nicolas Capensf160b172014-11-26 11:58:23 -05006016 if(location == -1)
6017 {
6018 return;
6019 }
John Bauman66b8ab22014-05-06 15:57:45 -04006020
Nicolas Capensf160b172014-11-26 11:58:23 -05006021 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006022
Nicolas Capensf160b172014-11-26 11:58:23 -05006023 if(context)
6024 {
6025 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006026
Nicolas Capensf160b172014-11-26 11:58:23 -05006027 if(!program)
6028 {
6029 return error(GL_INVALID_OPERATION);
6030 }
John Bauman66b8ab22014-05-06 15:57:45 -04006031
Nicolas Capensf160b172014-11-26 11:58:23 -05006032 if(!program->setUniformMatrix2fv(location, count, value))
6033 {
6034 return error(GL_INVALID_OPERATION);
6035 }
6036 }
John Bauman66b8ab22014-05-06 15:57:45 -04006037}
6038
6039void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6040{
Nicolas Capensf160b172014-11-26 11:58:23 -05006041 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
6042 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006043
Nicolas Capensf160b172014-11-26 11:58:23 -05006044 if(count < 0 || transpose != GL_FALSE)
6045 {
6046 return error(GL_INVALID_VALUE);
6047 }
John Bauman66b8ab22014-05-06 15:57:45 -04006048
Nicolas Capensf160b172014-11-26 11:58:23 -05006049 if(location == -1)
6050 {
6051 return;
6052 }
John Bauman66b8ab22014-05-06 15:57:45 -04006053
Nicolas Capensf160b172014-11-26 11:58:23 -05006054 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006055
Nicolas Capensf160b172014-11-26 11:58:23 -05006056 if(context)
6057 {
6058 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006059
Nicolas Capensf160b172014-11-26 11:58:23 -05006060 if(!program)
6061 {
6062 return error(GL_INVALID_OPERATION);
6063 }
John Bauman66b8ab22014-05-06 15:57:45 -04006064
Nicolas Capensf160b172014-11-26 11:58:23 -05006065 if(!program->setUniformMatrix3fv(location, count, value))
6066 {
6067 return error(GL_INVALID_OPERATION);
6068 }
6069 }
John Bauman66b8ab22014-05-06 15:57:45 -04006070}
6071
6072void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6073{
Nicolas Capensf160b172014-11-26 11:58:23 -05006074 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
6075 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006076
Nicolas Capensf160b172014-11-26 11:58:23 -05006077 if(count < 0 || transpose != GL_FALSE)
6078 {
6079 return error(GL_INVALID_VALUE);
6080 }
John Bauman66b8ab22014-05-06 15:57:45 -04006081
Nicolas Capensf160b172014-11-26 11:58:23 -05006082 if(location == -1)
6083 {
6084 return;
6085 }
John Bauman66b8ab22014-05-06 15:57:45 -04006086
Nicolas Capensf160b172014-11-26 11:58:23 -05006087 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006088
Nicolas Capensf160b172014-11-26 11:58:23 -05006089 if(context)
6090 {
6091 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006092
Nicolas Capensf160b172014-11-26 11:58:23 -05006093 if(!program)
6094 {
6095 return error(GL_INVALID_OPERATION);
6096 }
John Bauman66b8ab22014-05-06 15:57:45 -04006097
Nicolas Capensf160b172014-11-26 11:58:23 -05006098 if(!program->setUniformMatrix4fv(location, count, value))
6099 {
6100 return error(GL_INVALID_OPERATION);
6101 }
6102 }
John Bauman66b8ab22014-05-06 15:57:45 -04006103}
6104
6105void GL_APIENTRY glUseProgram(GLuint program)
6106{
Nicolas Capensf160b172014-11-26 11:58:23 -05006107 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006108
Nicolas Capensf160b172014-11-26 11:58:23 -05006109 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006110
Nicolas Capensf160b172014-11-26 11:58:23 -05006111 if(context)
6112 {
6113 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006114
Nicolas Capensf160b172014-11-26 11:58:23 -05006115 if(!programObject && program != 0)
6116 {
6117 if(context->getShader(program))
6118 {
6119 return error(GL_INVALID_OPERATION);
6120 }
6121 else
6122 {
6123 return error(GL_INVALID_VALUE);
6124 }
6125 }
John Bauman66b8ab22014-05-06 15:57:45 -04006126
Nicolas Capensf160b172014-11-26 11:58:23 -05006127 if(program != 0 && !programObject->isLinked())
6128 {
6129 return error(GL_INVALID_OPERATION);
6130 }
John Bauman66b8ab22014-05-06 15:57:45 -04006131
Nicolas Capensf160b172014-11-26 11:58:23 -05006132 context->useProgram(program);
6133 }
John Bauman66b8ab22014-05-06 15:57:45 -04006134}
6135
6136void GL_APIENTRY glValidateProgram(GLuint program)
6137{
Nicolas Capensf160b172014-11-26 11:58:23 -05006138 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006139
Nicolas Capensf160b172014-11-26 11:58:23 -05006140 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006141
Nicolas Capensf160b172014-11-26 11:58:23 -05006142 if(context)
6143 {
6144 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006145
Nicolas Capensf160b172014-11-26 11:58:23 -05006146 if(!programObject)
6147 {
6148 if(context->getShader(program))
6149 {
6150 return error(GL_INVALID_OPERATION);
6151 }
6152 else
6153 {
6154 return error(GL_INVALID_VALUE);
6155 }
6156 }
John Bauman66b8ab22014-05-06 15:57:45 -04006157
Nicolas Capensf160b172014-11-26 11:58:23 -05006158 programObject->validate();
6159 }
John Bauman66b8ab22014-05-06 15:57:45 -04006160}
6161
6162void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
6163{
Nicolas Capensf160b172014-11-26 11:58:23 -05006164 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
John Bauman66b8ab22014-05-06 15:57:45 -04006165
Nicolas Capensf160b172014-11-26 11:58:23 -05006166 if(index >= es2::MAX_VERTEX_ATTRIBS)
6167 {
6168 return error(GL_INVALID_VALUE);
6169 }
John Bauman66b8ab22014-05-06 15:57:45 -04006170
Nicolas Capensf160b172014-11-26 11:58:23 -05006171 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006172
Nicolas Capensf160b172014-11-26 11:58:23 -05006173 if(context)
6174 {
6175 GLfloat vals[4] = { x, 0, 0, 1 };
6176 context->setVertexAttrib(index, vals);
6177 }
John Bauman66b8ab22014-05-06 15:57:45 -04006178}
6179
6180void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
6181{
Nicolas Capensf160b172014-11-26 11:58:23 -05006182 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006183
Nicolas Capensf160b172014-11-26 11:58:23 -05006184 if(index >= es2::MAX_VERTEX_ATTRIBS)
6185 {
6186 return error(GL_INVALID_VALUE);
6187 }
John Bauman66b8ab22014-05-06 15:57:45 -04006188
Nicolas Capensf160b172014-11-26 11:58:23 -05006189 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006190
Nicolas Capensf160b172014-11-26 11:58:23 -05006191 if(context)
6192 {
6193 GLfloat vals[4] = { values[0], 0, 0, 1 };
6194 context->setVertexAttrib(index, vals);
6195 }
John Bauman66b8ab22014-05-06 15:57:45 -04006196}
6197
6198void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6199{
Nicolas Capensf160b172014-11-26 11:58:23 -05006200 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
John Bauman66b8ab22014-05-06 15:57:45 -04006201
Nicolas Capensf160b172014-11-26 11:58:23 -05006202 if(index >= es2::MAX_VERTEX_ATTRIBS)
6203 {
6204 return error(GL_INVALID_VALUE);
6205 }
John Bauman66b8ab22014-05-06 15:57:45 -04006206
Nicolas Capensf160b172014-11-26 11:58:23 -05006207 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006208
Nicolas Capensf160b172014-11-26 11:58:23 -05006209 if(context)
6210 {
6211 GLfloat vals[4] = { x, y, 0, 1 };
6212 context->setVertexAttrib(index, vals);
6213 }
John Bauman66b8ab22014-05-06 15:57:45 -04006214}
6215
6216void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
6217{
Nicolas Capensf160b172014-11-26 11:58:23 -05006218 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006219
Nicolas Capensf160b172014-11-26 11:58:23 -05006220 if(index >= es2::MAX_VERTEX_ATTRIBS)
6221 {
6222 return error(GL_INVALID_VALUE);
6223 }
John Bauman66b8ab22014-05-06 15:57:45 -04006224
Nicolas Capensf160b172014-11-26 11:58:23 -05006225 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006226
Nicolas Capensf160b172014-11-26 11:58:23 -05006227 if(context)
6228 {
6229 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6230 context->setVertexAttrib(index, vals);
6231 }
John Bauman66b8ab22014-05-06 15:57:45 -04006232}
6233
6234void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6235{
Nicolas Capensf160b172014-11-26 11:58:23 -05006236 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
John Bauman66b8ab22014-05-06 15:57:45 -04006237
Nicolas Capensf160b172014-11-26 11:58:23 -05006238 if(index >= es2::MAX_VERTEX_ATTRIBS)
6239 {
6240 return error(GL_INVALID_VALUE);
6241 }
John Bauman66b8ab22014-05-06 15:57:45 -04006242
Nicolas Capensf160b172014-11-26 11:58:23 -05006243 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006244
Nicolas Capensf160b172014-11-26 11:58:23 -05006245 if(context)
6246 {
6247 GLfloat vals[4] = { x, y, z, 1 };
6248 context->setVertexAttrib(index, vals);
6249 }
John Bauman66b8ab22014-05-06 15:57:45 -04006250}
6251
6252void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
6253{
Nicolas Capensf160b172014-11-26 11:58:23 -05006254 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006255
Nicolas Capensf160b172014-11-26 11:58:23 -05006256 if(index >= es2::MAX_VERTEX_ATTRIBS)
6257 {
6258 return error(GL_INVALID_VALUE);
6259 }
John Bauman66b8ab22014-05-06 15:57:45 -04006260
Nicolas Capensf160b172014-11-26 11:58:23 -05006261 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006262
Nicolas Capensf160b172014-11-26 11:58:23 -05006263 if(context)
6264 {
6265 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6266 context->setVertexAttrib(index, vals);
6267 }
John Bauman66b8ab22014-05-06 15:57:45 -04006268}
6269
6270void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6271{
Nicolas Capensf160b172014-11-26 11:58:23 -05006272 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 -04006273
Nicolas Capensf160b172014-11-26 11:58:23 -05006274 if(index >= es2::MAX_VERTEX_ATTRIBS)
6275 {
6276 return error(GL_INVALID_VALUE);
6277 }
John Bauman66b8ab22014-05-06 15:57:45 -04006278
Nicolas Capensf160b172014-11-26 11:58:23 -05006279 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006280
Nicolas Capensf160b172014-11-26 11:58:23 -05006281 if(context)
6282 {
6283 GLfloat vals[4] = { x, y, z, w };
6284 context->setVertexAttrib(index, vals);
6285 }
John Bauman66b8ab22014-05-06 15:57:45 -04006286}
6287
6288void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
6289{
Nicolas Capensf160b172014-11-26 11:58:23 -05006290 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006291
Nicolas Capensf160b172014-11-26 11:58:23 -05006292 if(index >= es2::MAX_VERTEX_ATTRIBS)
6293 {
6294 return error(GL_INVALID_VALUE);
6295 }
John Bauman66b8ab22014-05-06 15:57:45 -04006296
Nicolas Capensf160b172014-11-26 11:58:23 -05006297 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006298
Nicolas Capensf160b172014-11-26 11:58:23 -05006299 if(context)
6300 {
6301 context->setVertexAttrib(index, values);
6302 }
John Bauman66b8ab22014-05-06 15:57:45 -04006303}
6304
6305void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
6306{
Nicolas Capensf160b172014-11-26 11:58:23 -05006307 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
6308 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
6309 index, size, type, normalized, stride, ptr);
John Bauman66b8ab22014-05-06 15:57:45 -04006310
Nicolas Capensf160b172014-11-26 11:58:23 -05006311 if(index >= es2::MAX_VERTEX_ATTRIBS)
6312 {
6313 return error(GL_INVALID_VALUE);
6314 }
John Bauman66b8ab22014-05-06 15:57:45 -04006315
Nicolas Capensf160b172014-11-26 11:58:23 -05006316 if(size < 1 || size > 4)
6317 {
6318 return error(GL_INVALID_VALUE);
6319 }
John Bauman66b8ab22014-05-06 15:57:45 -04006320
Alexis Hetued306182015-04-02 12:02:28 -04006321 egl::GLint clientVersion = egl::getClientVersion();
6322
Nicolas Capensf160b172014-11-26 11:58:23 -05006323 switch(type)
6324 {
6325 case GL_BYTE:
6326 case GL_UNSIGNED_BYTE:
6327 case GL_SHORT:
6328 case GL_UNSIGNED_SHORT:
6329 case GL_FIXED:
6330 case GL_FLOAT:
6331 break;
Alexis Hetued306182015-04-02 12:02:28 -04006332 case GL_INT_2_10_10_10_REV:
6333 case GL_UNSIGNED_INT_2_10_10_10_REV:
6334 if(clientVersion >= 3)
6335 {
6336 if(size != 4)
6337 {
6338 return error(GL_INVALID_OPERATION);
6339 }
6340 break;
6341 }
6342 else return error(GL_INVALID_ENUM);
6343 case GL_INT:
6344 case GL_UNSIGNED_INT:
6345 case GL_HALF_FLOAT:
6346 if(clientVersion >= 3)
6347 {
6348 break;
6349 }
6350 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05006351 default:
6352 return error(GL_INVALID_ENUM);
6353 }
John Bauman66b8ab22014-05-06 15:57:45 -04006354
Nicolas Capensf160b172014-11-26 11:58:23 -05006355 if(stride < 0)
6356 {
6357 return error(GL_INVALID_VALUE);
6358 }
John Bauman66b8ab22014-05-06 15:57:45 -04006359
Nicolas Capensf160b172014-11-26 11:58:23 -05006360 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006361
Nicolas Capensf160b172014-11-26 11:58:23 -05006362 if(context)
6363 {
6364 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6365 }
John Bauman66b8ab22014-05-06 15:57:45 -04006366}
6367
6368void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6369{
Nicolas Capensf160b172014-11-26 11:58:23 -05006370 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04006371
Nicolas Capensf160b172014-11-26 11:58:23 -05006372 if(width < 0 || height < 0)
6373 {
6374 return error(GL_INVALID_VALUE);
6375 }
John Bauman66b8ab22014-05-06 15:57:45 -04006376
Nicolas Capensf160b172014-11-26 11:58:23 -05006377 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006378
Nicolas Capensf160b172014-11-26 11:58:23 -05006379 if(context)
6380 {
6381 context->setViewportParams(x, y, width, height);
6382 }
John Bauman66b8ab22014-05-06 15:57:45 -04006383}
6384
Alexis Hetue9233fb2015-02-11 10:31:58 -05006385void 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 -04006386{
Nicolas Capensf160b172014-11-26 11:58:23 -05006387 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6388 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6389 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6390 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
John Bauman66b8ab22014-05-06 15:57:45 -04006391
Nicolas Capensf160b172014-11-26 11:58:23 -05006392 switch(filter)
6393 {
6394 case GL_NEAREST:
6395 break;
6396 default:
6397 return error(GL_INVALID_ENUM);
6398 }
John Bauman66b8ab22014-05-06 15:57:45 -04006399
Nicolas Capensf160b172014-11-26 11:58:23 -05006400 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6401 {
6402 return error(GL_INVALID_VALUE);
6403 }
John Bauman66b8ab22014-05-06 15:57:45 -04006404
Nicolas Capensf160b172014-11-26 11:58:23 -05006405 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006406
Nicolas Capensf160b172014-11-26 11:58:23 -05006407 if(context)
6408 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006409 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capensf160b172014-11-26 11:58:23 -05006410 {
6411 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6412 return error(GL_INVALID_OPERATION);
6413 }
John Bauman66b8ab22014-05-06 15:57:45 -04006414
Nicolas Capensf160b172014-11-26 11:58:23 -05006415 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6416 }
John Bauman66b8ab22014-05-06 15:57:45 -04006417}
6418
Alexis Hetue9233fb2015-02-11 10:31:58 -05006419void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6420 GLbitfield mask, GLenum filter)
6421{
6422 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6423 {
6424 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6425 return error(GL_INVALID_OPERATION);
6426 }
6427
6428 glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6429}
6430
John Bauman66b8ab22014-05-06 15:57:45 -04006431void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Nicolas Capensf160b172014-11-26 11:58:23 -05006432 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04006433{
Nicolas Capensf160b172014-11-26 11:58:23 -05006434 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6435 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
6436 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
6437 target, level, internalformat, width, height, depth, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04006438
Alexis Hetub027aa92015-01-19 15:56:12 -05006439 switch(target)
6440 {
6441 case GL_TEXTURE_3D_OES:
6442 switch(format)
6443 {
6444 case GL_DEPTH_COMPONENT:
6445 case GL_DEPTH_STENCIL_OES:
6446 return error(GL_INVALID_OPERATION);
6447 default:
6448 break;
6449 }
6450 break;
6451 default:
6452 return error(GL_INVALID_ENUM);
6453 }
6454
6455 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6456 {
6457 return error(GL_INVALID_ENUM);
6458 }
6459
6460 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6461 {
6462 return error(GL_INVALID_VALUE);
6463 }
6464
6465 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6466 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6467 {
6468 return error(GL_INVALID_VALUE);
6469 }
6470
6471 if(border != 0)
6472 {
6473 return error(GL_INVALID_VALUE);
6474 }
6475
6476 if(!ValidateInternalFormat3D(internalformat, format, type))
6477 {
6478 return error(GL_INVALID_OPERATION);
6479 }
6480
6481 es2::Context *context = es2::getContext();
6482
6483 if(context)
6484 {
6485 es2::Texture3D *texture = context->getTexture3D();
6486
6487 if(!texture)
6488 {
6489 return error(GL_INVALID_OPERATION);
6490 }
6491
6492 texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackAlignment(), pixels);
6493 }
John Bauman66b8ab22014-05-06 15:57:45 -04006494}
6495
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006496void 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)
6497{
Alexis Hetub027aa92015-01-19 15:56:12 -05006498 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6499 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6500 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006501 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
6502
Alexis Hetub027aa92015-01-19 15:56:12 -05006503 switch(target)
6504 {
6505 case GL_TEXTURE_3D_OES:
6506 break;
6507 default:
6508 return error(GL_INVALID_ENUM);
6509 }
6510
6511 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6512 {
6513 return error(GL_INVALID_ENUM);
6514 }
6515
6516 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6517 {
6518 return error(GL_INVALID_VALUE);
6519 }
6520
6521 if((width < 0) || (height < 0) || (depth < 0))
6522 {
6523 return error(GL_INVALID_VALUE);
6524 }
6525
6526 es2::Context *context = es2::getContext();
6527
6528 if(context)
6529 {
6530 es2::Texture3D *texture = context->getTexture3D();
6531
6532 if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))
6533 {
6534 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackAlignment(), pixels);
6535 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006536 }
6537}
6538
6539void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
6540{
Alexis Hetub027aa92015-01-19 15:56:12 -05006541 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6542 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006543 target, level, xoffset, yoffset, zoffset, x, y, width, height);
6544
Alexis Hetub027aa92015-01-19 15:56:12 -05006545 switch(target)
6546 {
6547 case GL_TEXTURE_3D_OES:
6548 break;
6549 default:
6550 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006551 }
6552
Alexis Hetub027aa92015-01-19 15:56:12 -05006553 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6554 {
6555 return error(GL_INVALID_VALUE);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006556 }
6557
Alexis Hetub027aa92015-01-19 15:56:12 -05006558 es2::Context *context = es2::getContext();
6559
6560 if(context)
6561 {
6562 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6563
6564 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
6565 {
6566 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6567 }
6568
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006569 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Alexis Hetub027aa92015-01-19 15:56:12 -05006570 {
6571 return error(GL_INVALID_OPERATION);
6572 }
6573
6574 es2::Renderbuffer *source = framebuffer->getColorbuffer();
6575 GLenum colorbufferFormat = source->getFormat();
6576 es2::Texture3D *texture = context->getTexture3D();
6577
6578 if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))
6579 {
6580 return;
6581 }
6582
6583 GLenum textureFormat = texture->getFormat(target, level);
6584
6585 if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
6586 {
6587 return;
6588 }
6589
6590 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006591 }
6592}
6593
6594void GL_APIENTRY glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
6595{
Alexis Hetub027aa92015-01-19 15:56:12 -05006596 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
6597 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
6598 target, level, internalformat, width, height, depth, border, imageSize, data);
6599
6600 switch(target)
6601 {
6602 case GL_TEXTURE_3D_OES:
6603 break;
6604 default:
6605 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006606 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006607
6608 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6609 {
6610 return error(GL_INVALID_VALUE);
6611 }
6612
6613 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6614 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6615 {
6616 return error(GL_INVALID_VALUE);
6617 }
6618
6619 switch(internalformat)
6620 {
6621 case GL_ETC1_RGB8_OES:
6622 break;
6623 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6624 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6625 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6626 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6627 if(!S3TC_SUPPORT)
6628 {
6629 return error(GL_INVALID_ENUM);
6630 }
6631 break;
6632 case GL_DEPTH_COMPONENT:
6633 case GL_DEPTH_COMPONENT16:
6634 case GL_DEPTH_COMPONENT32_OES:
6635 case GL_DEPTH_STENCIL_OES:
6636 case GL_DEPTH24_STENCIL8_OES:
6637 return error(GL_INVALID_OPERATION);
6638 default:
6639 return error(GL_INVALID_ENUM);
6640 }
6641
6642 if(imageSize != es2::ComputeCompressedSize(width, height, internalformat) * depth)
6643 {
6644 return error(GL_INVALID_VALUE);
6645 }
6646
6647 es2::Context *context = es2::getContext();
6648
6649 if(context)
6650 {
6651 es2::Texture3D *texture = context->getTexture3D();
6652
6653 if(!texture)
6654 {
6655 return error(GL_INVALID_OPERATION);
6656 }
6657
6658 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006659 }
6660}
6661
6662void 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)
6663{
Alexis Hetub027aa92015-01-19 15:56:12 -05006664 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6665 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6666 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = 0x%0.8p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006667 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6668
Alexis Hetub027aa92015-01-19 15:56:12 -05006669 switch(target)
6670 {
6671 case GL_TEXTURE_3D_OES:
6672 break;
6673 default:
6674 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006675 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006676
6677 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6678 {
6679 return error(GL_INVALID_VALUE);
6680 }
6681
6682 switch(format)
6683 {
6684 case GL_ETC1_RGB8_OES:
6685 break;
6686 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6687 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6688 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6689 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6690 if(!S3TC_SUPPORT)
6691 {
6692 return error(GL_INVALID_ENUM);
6693 }
6694 break;
6695 default:
6696 return error(GL_INVALID_ENUM);
6697 }
6698
6699 if(width == 0 || height == 0 || depth == 0 || data == NULL)
6700 {
6701 return;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006702 }
6703
Alexis Hetub027aa92015-01-19 15:56:12 -05006704 es2::Context *context = es2::getContext();
6705
6706 if(context)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006707 {
Alexis Hetub027aa92015-01-19 15:56:12 -05006708 es2::Texture3D *texture = context->getTexture3D();
6709
6710 if(!texture)
6711 {
6712 return error(GL_INVALID_OPERATION);
6713 }
6714
6715 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6716 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006717}
6718
6719void GL_APIENTRY glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
6720{
Alexis Hetub027aa92015-01-19 15:56:12 -05006721 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6722 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6723
6724 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
6725 {
6726 return error(GL_INVALID_ENUM);
6727 }
6728
6729 switch(attachment)
6730 {
6731 case GL_COLOR_ATTACHMENT0:
6732 case GL_DEPTH_ATTACHMENT:
6733 case GL_STENCIL_ATTACHMENT:
6734 break;
6735 default:
6736 return error(GL_INVALID_ENUM);
6737 }
6738
6739 es2::Context *context = es2::getContext();
6740
6741 if(context)
6742 {
6743 if(texture == 0)
6744 {
6745 textarget = GL_NONE;
6746 }
6747 else
6748 {
6749 es2::Texture *tex = context->getTexture(texture);
6750
6751 if(tex == NULL)
6752 {
6753 return error(GL_INVALID_OPERATION);
6754 }
6755
6756 if(tex->isCompressed(textarget, level))
6757 {
6758 return error(GL_INVALID_OPERATION);
6759 }
6760
6761 switch(textarget)
6762 {
6763 case GL_TEXTURE_3D_OES:
6764 if(tex->getTarget() != GL_TEXTURE_3D_OES)
6765 {
6766 return error(GL_INVALID_OPERATION);
6767 }
6768 break;
6769 default:
6770 return error(GL_INVALID_ENUM);
6771 }
6772
6773 if(level != 0)
6774 {
6775 return error(GL_INVALID_VALUE);
6776 }
6777 }
6778
6779 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006780 GLuint framebufferName = 0;
Alexis Hetub027aa92015-01-19 15:56:12 -05006781 if(target == GL_READ_FRAMEBUFFER_ANGLE)
6782 {
6783 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006784 framebufferName = context->getReadFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006785 }
6786 else
6787 {
6788 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006789 framebufferName = context->getDrawFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006790 }
6791
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006792 if(framebufferName == 0 || !framebuffer)
Alexis Hetub027aa92015-01-19 15:56:12 -05006793 {
6794 return error(GL_INVALID_OPERATION);
6795 }
6796
6797 switch(attachment)
6798 {
6799 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
6800 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
6801 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6802 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006803 }
6804}
Alexis Hetub027aa92015-01-19 15:56:12 -05006805
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006806void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
6807{
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006808 if(egl::getClientVersion() == 1)
6809 {
Nicolas Capensa2308052015-04-15 16:50:21 -04006810 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006811 }
6812
Nicolas Capensf160b172014-11-26 11:58:23 -05006813 TRACE("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006814
Nicolas Capensf160b172014-11-26 11:58:23 -05006815 switch(target)
6816 {
6817 case GL_TEXTURE_2D:
6818 case GL_TEXTURE_EXTERNAL_OES:
6819 break;
6820 default:
6821 return error(GL_INVALID_ENUM);
6822 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006823
Nicolas Capensf160b172014-11-26 11:58:23 -05006824 if(!image)
6825 {
6826 return error(GL_INVALID_OPERATION);
6827 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006828
Nicolas Capensf160b172014-11-26 11:58:23 -05006829 es2::Context *context = es2::getContext();
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006830
Nicolas Capensf160b172014-11-26 11:58:23 -05006831 if(context)
6832 {
6833 es2::Texture2D *texture = 0;
Nicolas Capens08e90f02014-11-21 12:49:12 -05006834
Nicolas Capensf160b172014-11-26 11:58:23 -05006835 switch(target)
6836 {
6837 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
6838 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
6839 default: UNREACHABLE();
6840 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006841
Nicolas Capensf160b172014-11-26 11:58:23 -05006842 if(!texture)
6843 {
6844 return error(GL_INVALID_OPERATION);
6845 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006846
Nicolas Capensf160b172014-11-26 11:58:23 -05006847 egl::Image *glImage = static_cast<egl::Image*>(image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006848
Nicolas Capensf160b172014-11-26 11:58:23 -05006849 texture->setImage(glImage);
6850 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006851}
6852
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006853void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
6854{
6855 TRACE("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
6856
6857 UNIMPLEMENTED();
6858}
6859
Nicolas Capensa2308052015-04-15 16:50:21 -04006860__eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
John Bauman66b8ab22014-05-06 15:57:45 -04006861{
Nicolas Capensf160b172014-11-26 11:58:23 -05006862 struct Extension
6863 {
6864 const char *name;
6865 __eglMustCastToProperFunctionPointerType address;
6866 };
John Bauman66b8ab22014-05-06 15:57:45 -04006867
Nicolas Capensf160b172014-11-26 11:58:23 -05006868 static const Extension glExtensions[] =
6869 {
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006870 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6871
Nicolas Capensf160b172014-11-26 11:58:23 -05006872 EXTENSION(glTexImage3DOES),
6873 EXTENSION(glBlitFramebufferANGLE),
Alexis Hetue9233fb2015-02-11 10:31:58 -05006874 EXTENSION(glBlitFramebufferNV),
Nicolas Capensf160b172014-11-26 11:58:23 -05006875 EXTENSION(glRenderbufferStorageMultisampleANGLE),
6876 EXTENSION(glDeleteFencesNV),
6877 EXTENSION(glGenFencesNV),
6878 EXTENSION(glIsFenceNV),
6879 EXTENSION(glTestFenceNV),
6880 EXTENSION(glGetFenceivNV),
6881 EXTENSION(glFinishFenceNV),
6882 EXTENSION(glSetFenceNV),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006883 EXTENSION(glGetGraphicsResetStatusEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05006884 EXTENSION(glReadnPixelsEXT),
6885 EXTENSION(glGetnUniformfvEXT),
6886 EXTENSION(glGetnUniformivEXT),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006887 EXTENSION(glGenQueriesEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05006888 EXTENSION(glDeleteQueriesEXT),
6889 EXTENSION(glIsQueryEXT),
6890 EXTENSION(glBeginQueryEXT),
6891 EXTENSION(glEndQueryEXT),
6892 EXTENSION(glGetQueryivEXT),
6893 EXTENSION(glGetQueryObjectuivEXT),
6894 EXTENSION(glEGLImageTargetTexture2DOES),
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006895 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
Alexis Hetue8af6d12015-04-17 16:58:45 -04006896 EXTENSION(glDrawElementsInstancedEXT),
6897 EXTENSION(glDrawArraysInstancedEXT),
6898 EXTENSION(glVertexAttribDivisorEXT),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006899
6900 #undef EXTENSION
Nicolas Capensf160b172014-11-26 11:58:23 -05006901 };
John Bauman66b8ab22014-05-06 15:57:45 -04006902
Nicolas Capensf160b172014-11-26 11:58:23 -05006903 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6904 {
6905 if(strcmp(procname, glExtensions[ext].name) == 0)
6906 {
6907 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6908 }
6909 }
John Bauman66b8ab22014-05-06 15:57:45 -04006910
Nicolas Capensf160b172014-11-26 11:58:23 -05006911 return NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04006912}
6913
John Baumand4ae8632014-05-06 16:18:33 -04006914void GL_APIENTRY Register(const char *licenseKey)
6915{
6916 RegisterLicenseKey(licenseKey);
6917}
6918
John Bauman66b8ab22014-05-06 15:57:45 -04006919}