blob: 9b356fdb434be1484894d187b6fa78d81a8f6d60 [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 Capens4be33702015-04-28 15:13:30 -0700742 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
Nicolas Capensf160b172014-11-26 11:58:23 -0500743 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 Capens4be33702015-04-28 15:13:30 -0700798 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -0500799 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, "
Nicolas Capens4be33702015-04-28 15:13:30 -0700962 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -0500963 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 Capensdeda34b2015-04-28 15:21:53 -07001054 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
Nicolas Capensf160b172014-11-26 11:58:23 -05001055 {
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, "
Nicolas Capens4be33702015-04-28 15:13:30 -07001100 "GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05001101 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 Capensdeda34b2015-04-28 15:21:53 -07001161 if(imageSize != egl::ComputeCompressedSize(width, height, format))
Nicolas Capensf160b172014-11-26 11:58:23 -05001162 {
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 Capens4be33702015-04-28 15:13:30 -07001430 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", 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 Capens4be33702015-04-28 15:13:30 -07001450 TRACE("(GLsizei n = %d, const GLuint* fences = %p)", 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 Capens4be33702015-04-28 15:13:30 -07001470 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", 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 Capens4be33702015-04-28 15:13:30 -07001522 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", 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 Capens4be33702015-04-28 15:13:30 -07001542 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", 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 Capens4be33702015-04-28 15:13:30 -07001591 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", 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 Capens4be33702015-04-28 15:13:30 -07001792 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05001793 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{
Nicolas Capens4be33702015-04-28 15:13:30 -07001878 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
Alexis Hetue8af6d12015-04-17 16:58:45 -04001879 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
Alexis Hetub4d557d2015-04-24 17:25:10 -04001941void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1942{
1943 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1944 mode, first, count, instanceCount);
1945
1946 switch(mode)
1947 {
1948 case GL_POINTS:
1949 case GL_LINES:
1950 case GL_LINE_LOOP:
1951 case GL_LINE_STRIP:
1952 case GL_TRIANGLES:
1953 case GL_TRIANGLE_FAN:
1954 case GL_TRIANGLE_STRIP:
1955 break;
1956 default:
1957 return error(GL_INVALID_ENUM);
1958 }
1959
1960 if(count < 0 || instanceCount < 0)
1961 {
1962 return error(GL_INVALID_VALUE);
1963 }
1964
1965 es2::Context *context = es2::getContext();
1966
1967 if(context)
1968 {
1969 if(!context->hasZeroDivisor())
1970 {
1971 return error(GL_INVALID_OPERATION);
1972 }
1973
1974 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1975 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1976 {
1977 return error(GL_INVALID_OPERATION);
1978 }
1979
1980 context->drawArrays(mode, first, count, instanceCount);
1981 }
1982}
1983
1984void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
1985{
Nicolas Capens4be33702015-04-28 15:13:30 -07001986 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
Alexis Hetub4d557d2015-04-24 17:25:10 -04001987 mode, count, type, indices, instanceCount);
1988
1989 switch(mode)
1990 {
1991 case GL_POINTS:
1992 case GL_LINES:
1993 case GL_LINE_LOOP:
1994 case GL_LINE_STRIP:
1995 case GL_TRIANGLES:
1996 case GL_TRIANGLE_FAN:
1997 case GL_TRIANGLE_STRIP:
1998 break;
1999 default:
2000 return error(GL_INVALID_ENUM);
2001 }
2002
2003 switch(type)
2004 {
2005 case GL_UNSIGNED_BYTE:
2006 case GL_UNSIGNED_SHORT:
2007 case GL_UNSIGNED_INT:
2008 break;
2009 default:
2010 return error(GL_INVALID_ENUM);
2011 }
2012
2013 if(count < 0 || instanceCount < 0)
2014 {
2015 return error(GL_INVALID_VALUE);
2016 }
2017
2018 es2::Context *context = es2::getContext();
2019
2020 if(context)
2021 {
2022 if(!context->hasZeroDivisor())
2023 {
2024 return error(GL_INVALID_OPERATION);
2025 }
2026
2027 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
2028 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
2029 {
2030 return error(GL_INVALID_OPERATION);
2031 }
2032
Nicolas Capens0416e5c2015-04-28 15:30:28 -07002033 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
Alexis Hetub4d557d2015-04-24 17:25:10 -04002034 }
2035}
2036
2037void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
2038{
2039 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
2040
2041 es2::Context *context = es2::getContext();
2042
2043 if(context)
2044 {
2045 if(index >= MAX_VERTEX_ATTRIBS)
2046 {
2047 return error(GL_INVALID_VALUE);
2048 }
2049
2050 context->setVertexAttribDivisor(index, divisor);
2051 }
2052}
2053
John Bauman66b8ab22014-05-06 15:57:45 -04002054void GL_APIENTRY glEnable(GLenum cap)
2055{
Nicolas Capensf160b172014-11-26 11:58:23 -05002056 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04002057
Nicolas Capensf160b172014-11-26 11:58:23 -05002058 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002059
Nicolas Capensf160b172014-11-26 11:58:23 -05002060 if(context)
2061 {
2062 switch(cap)
2063 {
2064 case GL_CULL_FACE: context->setCullFace(true); break;
2065 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
2066 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
2067 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
2068 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
2069 case GL_STENCIL_TEST: context->setStencilTest(true); break;
2070 case GL_DEPTH_TEST: context->setDepthTest(true); break;
2071 case GL_BLEND: context->setBlend(true); break;
2072 case GL_DITHER: context->setDither(true); break;
Alexis Hetufceb1832015-03-10 16:42:04 -04002073 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndex(true); break;
2074 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscard(true); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05002075 default:
2076 return error(GL_INVALID_ENUM);
2077 }
2078 }
John Bauman66b8ab22014-05-06 15:57:45 -04002079}
2080
2081void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
2082{
Nicolas Capensf160b172014-11-26 11:58:23 -05002083 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04002084
Nicolas Capensf160b172014-11-26 11:58:23 -05002085 if(index >= es2::MAX_VERTEX_ATTRIBS)
2086 {
2087 return error(GL_INVALID_VALUE);
2088 }
John Bauman66b8ab22014-05-06 15:57:45 -04002089
Nicolas Capensf160b172014-11-26 11:58:23 -05002090 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002091
Nicolas Capensf160b172014-11-26 11:58:23 -05002092 if(context)
2093 {
2094 context->setEnableVertexAttribArray(index, true);
2095 }
John Bauman66b8ab22014-05-06 15:57:45 -04002096}
2097
2098void GL_APIENTRY glEndQueryEXT(GLenum target)
2099{
Nicolas Capensf160b172014-11-26 11:58:23 -05002100 TRACE("GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04002101
Nicolas Capensf160b172014-11-26 11:58:23 -05002102 switch(target)
2103 {
2104 case GL_ANY_SAMPLES_PASSED_EXT:
2105 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
2106 break;
2107 default:
2108 return error(GL_INVALID_ENUM);
2109 }
John Bauman66b8ab22014-05-06 15:57:45 -04002110
Nicolas Capensf160b172014-11-26 11:58:23 -05002111 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002112
Nicolas Capensf160b172014-11-26 11:58:23 -05002113 if(context)
2114 {
2115 context->endQuery(target);
2116 }
John Bauman66b8ab22014-05-06 15:57:45 -04002117}
2118
2119void GL_APIENTRY glFinishFenceNV(GLuint fence)
2120{
Nicolas Capensf160b172014-11-26 11:58:23 -05002121 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002122
Nicolas Capensf160b172014-11-26 11:58:23 -05002123 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002124
Nicolas Capensf160b172014-11-26 11:58:23 -05002125 if(context)
2126 {
2127 es2::Fence* fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002128
Nicolas Capensf160b172014-11-26 11:58:23 -05002129 if(fenceObject == NULL)
2130 {
2131 return error(GL_INVALID_OPERATION);
2132 }
John Bauman66b8ab22014-05-06 15:57:45 -04002133
Nicolas Capensf160b172014-11-26 11:58:23 -05002134 fenceObject->finishFence();
2135 }
John Bauman66b8ab22014-05-06 15:57:45 -04002136}
2137
2138void GL_APIENTRY glFinish(void)
2139{
Nicolas Capensf160b172014-11-26 11:58:23 -05002140 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002141
Nicolas Capensf160b172014-11-26 11:58:23 -05002142 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002143
Nicolas Capensf160b172014-11-26 11:58:23 -05002144 if(context)
2145 {
2146 context->finish();
2147 }
John Bauman66b8ab22014-05-06 15:57:45 -04002148}
2149
2150void GL_APIENTRY glFlush(void)
2151{
Nicolas Capensf160b172014-11-26 11:58:23 -05002152 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002153
Nicolas Capensf160b172014-11-26 11:58:23 -05002154 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002155
Nicolas Capensf160b172014-11-26 11:58:23 -05002156 if(context)
2157 {
2158 context->flush();
2159 }
John Bauman66b8ab22014-05-06 15:57:45 -04002160}
2161
2162void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2163{
Nicolas Capensf160b172014-11-26 11:58:23 -05002164 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
2165 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04002166
Nicolas Capensf160b172014-11-26 11:58:23 -05002167 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
2168 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
2169 {
2170 return error(GL_INVALID_ENUM);
2171 }
John Bauman66b8ab22014-05-06 15:57:45 -04002172
Nicolas Capensf160b172014-11-26 11:58:23 -05002173 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002174
Nicolas Capensf160b172014-11-26 11:58:23 -05002175 if(context)
2176 {
2177 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002178 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002179 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2180 {
2181 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002182 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002183 }
2184 else
2185 {
2186 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002187 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002188 }
John Bauman66b8ab22014-05-06 15:57:45 -04002189
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002190 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capensf160b172014-11-26 11:58:23 -05002191 {
2192 return error(GL_INVALID_OPERATION);
2193 }
John Bauman66b8ab22014-05-06 15:57:45 -04002194
Nicolas Capensf160b172014-11-26 11:58:23 -05002195 switch(attachment)
2196 {
2197 case GL_COLOR_ATTACHMENT0:
2198 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2199 break;
2200 case GL_DEPTH_ATTACHMENT:
2201 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2202 break;
2203 case GL_STENCIL_ATTACHMENT:
2204 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2205 break;
2206 default:
2207 return error(GL_INVALID_ENUM);
2208 }
2209 }
John Bauman66b8ab22014-05-06 15:57:45 -04002210}
2211
2212void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2213{
Nicolas Capensf160b172014-11-26 11:58:23 -05002214 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
2215 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
John Bauman66b8ab22014-05-06 15:57:45 -04002216
Nicolas Capensf160b172014-11-26 11:58:23 -05002217 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2218 {
2219 return error(GL_INVALID_ENUM);
2220 }
John Bauman66b8ab22014-05-06 15:57:45 -04002221
Nicolas Capensf160b172014-11-26 11:58:23 -05002222 switch(attachment)
2223 {
2224 case GL_COLOR_ATTACHMENT0:
2225 case GL_DEPTH_ATTACHMENT:
2226 case GL_STENCIL_ATTACHMENT:
2227 break;
2228 default:
2229 return error(GL_INVALID_ENUM);
2230 }
John Bauman66b8ab22014-05-06 15:57:45 -04002231
Nicolas Capensf160b172014-11-26 11:58:23 -05002232 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002233
Nicolas Capensf160b172014-11-26 11:58:23 -05002234 if(context)
2235 {
2236 if(texture == 0)
2237 {
2238 textarget = GL_NONE;
2239 }
2240 else
2241 {
2242 es2::Texture *tex = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04002243
Nicolas Capensf160b172014-11-26 11:58:23 -05002244 if(tex == NULL)
2245 {
2246 return error(GL_INVALID_OPERATION);
2247 }
John Bauman66b8ab22014-05-06 15:57:45 -04002248
Nicolas Capensf160b172014-11-26 11:58:23 -05002249 if(tex->isCompressed(textarget, level))
2250 {
2251 return error(GL_INVALID_OPERATION);
2252 }
John Bauman66b8ab22014-05-06 15:57:45 -04002253
Nicolas Capensf160b172014-11-26 11:58:23 -05002254 switch(textarget)
2255 {
2256 case GL_TEXTURE_2D:
2257 if(tex->getTarget() != GL_TEXTURE_2D)
2258 {
2259 return error(GL_INVALID_OPERATION);
2260 }
2261 break;
2262 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2263 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2264 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2265 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2266 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2267 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2268 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2269 {
2270 return error(GL_INVALID_OPERATION);
2271 }
2272 break;
2273 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(level != 0)
2278 {
2279 return error(GL_INVALID_VALUE);
2280 }
2281 }
John Bauman66b8ab22014-05-06 15:57:45 -04002282
Nicolas Capensf160b172014-11-26 11:58:23 -05002283 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002284 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002285 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2286 {
2287 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002288 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002289 }
2290 else
2291 {
2292 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002293 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002294 }
John Bauman66b8ab22014-05-06 15:57:45 -04002295
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002296 if(framebufferName == 0 || !framebuffer)
Nicolas Capensf160b172014-11-26 11:58:23 -05002297 {
2298 return error(GL_INVALID_OPERATION);
2299 }
John Bauman66b8ab22014-05-06 15:57:45 -04002300
Nicolas Capensf160b172014-11-26 11:58:23 -05002301 switch(attachment)
2302 {
2303 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2304 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2305 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2306 }
2307 }
John Bauman66b8ab22014-05-06 15:57:45 -04002308}
2309
2310void GL_APIENTRY glFrontFace(GLenum mode)
2311{
Nicolas Capensf160b172014-11-26 11:58:23 -05002312 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04002313
Nicolas Capensf160b172014-11-26 11:58:23 -05002314 switch(mode)
2315 {
2316 case GL_CW:
2317 case GL_CCW:
2318 {
2319 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002320
Nicolas Capensf160b172014-11-26 11:58:23 -05002321 if(context)
2322 {
2323 context->setFrontFace(mode);
2324 }
2325 }
2326 break;
2327 default:
2328 return error(GL_INVALID_ENUM);
2329 }
John Bauman66b8ab22014-05-06 15:57:45 -04002330}
2331
2332void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
2333{
Nicolas Capens4be33702015-04-28 15:13:30 -07002334 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002335
Nicolas Capensf160b172014-11-26 11:58:23 -05002336 if(n < 0)
2337 {
2338 return error(GL_INVALID_VALUE);
2339 }
John Bauman66b8ab22014-05-06 15:57:45 -04002340
Nicolas Capensf160b172014-11-26 11:58:23 -05002341 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002342
Nicolas Capensf160b172014-11-26 11:58:23 -05002343 if(context)
2344 {
2345 for(int i = 0; i < n; i++)
2346 {
2347 buffers[i] = context->createBuffer();
2348 }
2349 }
John Bauman66b8ab22014-05-06 15:57:45 -04002350}
2351
2352void GL_APIENTRY glGenerateMipmap(GLenum target)
2353{
Nicolas Capensf160b172014-11-26 11:58:23 -05002354 TRACE("(GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04002355
Nicolas Capensf160b172014-11-26 11:58:23 -05002356 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002357
Nicolas Capensf160b172014-11-26 11:58:23 -05002358 if(context)
2359 {
Alexis Hetued306182015-04-02 12:02:28 -04002360 es2::Texture *texture = nullptr;
2361
2362 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04002363
Nicolas Capensf160b172014-11-26 11:58:23 -05002364 switch(target)
2365 {
2366 case GL_TEXTURE_2D:
2367 texture = context->getTexture2D();
2368 break;
2369 case GL_TEXTURE_CUBE_MAP:
2370 texture = context->getTextureCubeMap();
2371 break;
Alexis Hetued306182015-04-02 12:02:28 -04002372 case GL_TEXTURE_2D_ARRAY:
2373 if(clientVersion < 3)
2374 {
2375 return error(GL_INVALID_ENUM);
2376 }
2377 else
2378 {
2379 UNIMPLEMENTED();
2380 texture = context->getTexture3D();
2381 break;
2382 }
2383 case GL_TEXTURE_3D_OES:
2384 texture = context->getTexture3D();
2385 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05002386 default:
2387 return error(GL_INVALID_ENUM);
2388 }
John Bauman66b8ab22014-05-06 15:57:45 -04002389
Nicolas Capensf160b172014-11-26 11:58:23 -05002390 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2391 {
2392 return error(GL_INVALID_OPERATION);
2393 }
John Bauman66b8ab22014-05-06 15:57:45 -04002394
Nicolas Capensf160b172014-11-26 11:58:23 -05002395 texture->generateMipmaps();
2396 }
John Bauman66b8ab22014-05-06 15:57:45 -04002397}
2398
2399void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
2400{
Nicolas Capens4be33702015-04-28 15:13:30 -07002401 TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04002402
Nicolas Capensf160b172014-11-26 11:58:23 -05002403 if(n < 0)
2404 {
2405 return error(GL_INVALID_VALUE);
2406 }
John Bauman66b8ab22014-05-06 15:57:45 -04002407
Nicolas Capensf160b172014-11-26 11:58:23 -05002408 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002409
Nicolas Capensf160b172014-11-26 11:58:23 -05002410 if(context)
2411 {
2412 for(int i = 0; i < n; i++)
2413 {
2414 fences[i] = context->createFence();
2415 }
2416 }
John Bauman66b8ab22014-05-06 15:57:45 -04002417}
2418
2419void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2420{
Nicolas Capens4be33702015-04-28 15:13:30 -07002421 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002422
Nicolas Capensf160b172014-11-26 11:58:23 -05002423 if(n < 0)
2424 {
2425 return error(GL_INVALID_VALUE);
2426 }
John Bauman66b8ab22014-05-06 15:57:45 -04002427
Nicolas Capensf160b172014-11-26 11:58:23 -05002428 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002429
Nicolas Capensf160b172014-11-26 11:58:23 -05002430 if(context)
2431 {
2432 for(int i = 0; i < n; i++)
2433 {
2434 framebuffers[i] = context->createFramebuffer();
2435 }
2436 }
John Bauman66b8ab22014-05-06 15:57:45 -04002437}
2438
2439void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
2440{
Nicolas Capens4be33702015-04-28 15:13:30 -07002441 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04002442
Nicolas Capensf160b172014-11-26 11:58:23 -05002443 if(n < 0)
2444 {
2445 return error(GL_INVALID_VALUE);
2446 }
John Bauman66b8ab22014-05-06 15:57:45 -04002447
Nicolas Capensf160b172014-11-26 11:58:23 -05002448 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002449
Nicolas Capensf160b172014-11-26 11:58:23 -05002450 if(context)
2451 {
2452 for(int i = 0; i < n; i++)
2453 {
2454 ids[i] = context->createQuery();
2455 }
2456 }
John Bauman66b8ab22014-05-06 15:57:45 -04002457}
2458
2459void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2460{
Nicolas Capens4be33702015-04-28 15:13:30 -07002461 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002462
Nicolas Capensf160b172014-11-26 11:58:23 -05002463 if(n < 0)
2464 {
2465 return error(GL_INVALID_VALUE);
2466 }
John Bauman66b8ab22014-05-06 15:57:45 -04002467
Nicolas Capensf160b172014-11-26 11:58:23 -05002468 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002469
Nicolas Capensf160b172014-11-26 11:58:23 -05002470 if(context)
2471 {
2472 for(int i = 0; i < n; i++)
2473 {
2474 renderbuffers[i] = context->createRenderbuffer();
2475 }
2476 }
John Bauman66b8ab22014-05-06 15:57:45 -04002477}
2478
2479void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
2480{
Nicolas Capens4be33702015-04-28 15:13:30 -07002481 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04002482
Nicolas Capensf160b172014-11-26 11:58:23 -05002483 if(n < 0)
2484 {
2485 return error(GL_INVALID_VALUE);
2486 }
John Bauman66b8ab22014-05-06 15:57:45 -04002487
Nicolas Capensf160b172014-11-26 11:58:23 -05002488 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002489
Nicolas Capensf160b172014-11-26 11:58:23 -05002490 if(context)
2491 {
2492 for(int i = 0; i < n; i++)
2493 {
2494 textures[i] = context->createTexture();
2495 }
2496 }
John Bauman66b8ab22014-05-06 15:57:45 -04002497}
2498
2499void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
2500{
Nicolas Capens4be33702015-04-28 15:13:30 -07002501 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
2502 "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002503 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002504
Nicolas Capensf160b172014-11-26 11:58:23 -05002505 if(bufsize < 0)
2506 {
2507 return error(GL_INVALID_VALUE);
2508 }
John Bauman66b8ab22014-05-06 15:57:45 -04002509
Nicolas Capensf160b172014-11-26 11:58:23 -05002510 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002511
Nicolas Capensf160b172014-11-26 11:58:23 -05002512 if(context)
2513 {
2514 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002515
Nicolas Capensf160b172014-11-26 11:58:23 -05002516 if(!programObject)
2517 {
2518 if(context->getShader(program))
2519 {
2520 return error(GL_INVALID_OPERATION);
2521 }
2522 else
2523 {
2524 return error(GL_INVALID_VALUE);
2525 }
2526 }
John Bauman66b8ab22014-05-06 15:57:45 -04002527
Nicolas Capensf160b172014-11-26 11:58:23 -05002528 if(index >= (GLuint)programObject->getActiveAttributeCount())
2529 {
2530 return error(GL_INVALID_VALUE);
2531 }
John Bauman66b8ab22014-05-06 15:57:45 -04002532
Nicolas Capensf160b172014-11-26 11:58:23 -05002533 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2534 }
John Bauman66b8ab22014-05-06 15:57:45 -04002535}
2536
2537void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
2538{
Nicolas Capensf160b172014-11-26 11:58:23 -05002539 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07002540 "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002541 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002542
Nicolas Capensf160b172014-11-26 11:58:23 -05002543 if(bufsize < 0)
2544 {
2545 return error(GL_INVALID_VALUE);
2546 }
John Bauman66b8ab22014-05-06 15:57:45 -04002547
Nicolas Capensf160b172014-11-26 11:58:23 -05002548 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002549
Nicolas Capensf160b172014-11-26 11:58:23 -05002550 if(context)
2551 {
2552 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002553
Nicolas Capensf160b172014-11-26 11:58:23 -05002554 if(!programObject)
2555 {
2556 if(context->getShader(program))
2557 {
2558 return error(GL_INVALID_OPERATION);
2559 }
2560 else
2561 {
2562 return error(GL_INVALID_VALUE);
2563 }
2564 }
John Bauman66b8ab22014-05-06 15:57:45 -04002565
Nicolas Capensf160b172014-11-26 11:58:23 -05002566 if(index >= (GLuint)programObject->getActiveUniformCount())
2567 {
2568 return error(GL_INVALID_VALUE);
2569 }
John Bauman66b8ab22014-05-06 15:57:45 -04002570
Nicolas Capensf160b172014-11-26 11:58:23 -05002571 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2572 }
John Bauman66b8ab22014-05-06 15:57:45 -04002573}
2574
2575void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2576{
Nicolas Capens4be33702015-04-28 15:13:30 -07002577 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002578 program, maxcount, count, shaders);
John Bauman66b8ab22014-05-06 15:57:45 -04002579
Nicolas Capensf160b172014-11-26 11:58:23 -05002580 if(maxcount < 0)
2581 {
2582 return error(GL_INVALID_VALUE);
2583 }
John Bauman66b8ab22014-05-06 15:57:45 -04002584
Nicolas Capensf160b172014-11-26 11:58:23 -05002585 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002586
Nicolas Capensf160b172014-11-26 11:58:23 -05002587 if(context)
2588 {
2589 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002590
Nicolas Capensf160b172014-11-26 11:58:23 -05002591 if(!programObject)
2592 {
2593 if(context->getShader(program))
2594 {
2595 return error(GL_INVALID_OPERATION);
2596 }
2597 else
2598 {
2599 return error(GL_INVALID_VALUE);
2600 }
2601 }
John Bauman66b8ab22014-05-06 15:57:45 -04002602
Nicolas Capensf160b172014-11-26 11:58:23 -05002603 return programObject->getAttachedShaders(maxcount, count, shaders);
2604 }
John Bauman66b8ab22014-05-06 15:57:45 -04002605}
2606
2607int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
2608{
Nicolas Capensf160b172014-11-26 11:58:23 -05002609 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002610
Nicolas Capensf160b172014-11-26 11:58:23 -05002611 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002612
Nicolas Capensf160b172014-11-26 11:58:23 -05002613 if(context)
2614 {
John Bauman66b8ab22014-05-06 15:57:45 -04002615
Nicolas Capensf160b172014-11-26 11:58:23 -05002616 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002617
Nicolas Capensf160b172014-11-26 11:58:23 -05002618 if(!programObject)
2619 {
2620 if(context->getShader(program))
2621 {
2622 return error(GL_INVALID_OPERATION, -1);
2623 }
2624 else
2625 {
2626 return error(GL_INVALID_VALUE, -1);
2627 }
2628 }
John Bauman66b8ab22014-05-06 15:57:45 -04002629
Nicolas Capensf160b172014-11-26 11:58:23 -05002630 if(!programObject->isLinked())
2631 {
2632 return error(GL_INVALID_OPERATION, -1);
2633 }
John Bauman66b8ab22014-05-06 15:57:45 -04002634
Nicolas Capensf160b172014-11-26 11:58:23 -05002635 return programObject->getAttributeLocation(name);
2636 }
John Bauman66b8ab22014-05-06 15:57:45 -04002637
Nicolas Capensf160b172014-11-26 11:58:23 -05002638 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04002639}
2640
2641void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
2642{
Nicolas Capens4be33702015-04-28 15:13:30 -07002643 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002644
Nicolas Capensf160b172014-11-26 11:58:23 -05002645 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002646
Nicolas Capensf160b172014-11-26 11:58:23 -05002647 if(context)
2648 {
2649 if(!(context->getBooleanv(pname, params)))
2650 {
2651 GLenum nativeType;
2652 unsigned int numParams = 0;
2653 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2654 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002655
Nicolas Capensf160b172014-11-26 11:58:23 -05002656 if(numParams == 0)
2657 return; // it is known that the pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04002658
Nicolas Capensf160b172014-11-26 11:58:23 -05002659 if(nativeType == GL_FLOAT)
2660 {
2661 GLfloat *floatParams = NULL;
2662 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002663
Nicolas Capensf160b172014-11-26 11:58:23 -05002664 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002665
Nicolas Capensf160b172014-11-26 11:58:23 -05002666 for(unsigned int i = 0; i < numParams; ++i)
2667 {
2668 if(floatParams[i] == 0.0f)
2669 params[i] = GL_FALSE;
2670 else
2671 params[i] = GL_TRUE;
2672 }
John Bauman66b8ab22014-05-06 15:57:45 -04002673
Nicolas Capensf160b172014-11-26 11:58:23 -05002674 delete [] floatParams;
2675 }
2676 else if(nativeType == GL_INT)
2677 {
2678 GLint *intParams = NULL;
2679 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002680
Nicolas Capensf160b172014-11-26 11:58:23 -05002681 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002682
Nicolas Capensf160b172014-11-26 11:58:23 -05002683 for(unsigned int i = 0; i < numParams; ++i)
2684 {
2685 if(intParams[i] == 0)
2686 params[i] = GL_FALSE;
2687 else
2688 params[i] = GL_TRUE;
2689 }
John Bauman66b8ab22014-05-06 15:57:45 -04002690
Nicolas Capensf160b172014-11-26 11:58:23 -05002691 delete [] intParams;
2692 }
2693 }
2694 }
John Bauman66b8ab22014-05-06 15:57:45 -04002695}
2696
2697void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2698{
Nicolas Capens4be33702015-04-28 15:13:30 -07002699 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002700
Nicolas Capensf160b172014-11-26 11:58:23 -05002701 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002702
Nicolas Capensf160b172014-11-26 11:58:23 -05002703 if(context)
2704 {
2705 es2::Buffer *buffer;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -04002706 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -05002707 {
Nicolas Capensf160b172014-11-26 11:58:23 -05002708 return error(GL_INVALID_ENUM);
2709 }
John Bauman66b8ab22014-05-06 15:57:45 -04002710
Nicolas Capensf160b172014-11-26 11:58:23 -05002711 if(!buffer)
2712 {
2713 // A null buffer means that "0" is bound to the requested buffer target
2714 return error(GL_INVALID_OPERATION);
2715 }
John Bauman66b8ab22014-05-06 15:57:45 -04002716
Alexis Hetued306182015-04-02 12:02:28 -04002717 egl::GLint clientVersion = context->getClientVersion();
2718
Nicolas Capensf160b172014-11-26 11:58:23 -05002719 switch(pname)
2720 {
2721 case GL_BUFFER_USAGE:
2722 *params = buffer->usage();
2723 break;
2724 case GL_BUFFER_SIZE:
2725 *params = buffer->size();
2726 break;
Alexis Hetued306182015-04-02 12:02:28 -04002727 case GL_BUFFER_ACCESS_FLAGS:
2728 if(clientVersion >= 3)
2729 {
2730 *params = buffer->access();
2731 break;
2732 }
2733 else return error(GL_INVALID_ENUM);
2734 case GL_BUFFER_MAPPED:
2735 if(clientVersion >= 3)
2736 {
2737 *params = buffer->isMapped();
2738 break;
2739 }
2740 else return error(GL_INVALID_ENUM);
2741 case GL_BUFFER_MAP_LENGTH:
2742 if(clientVersion >= 3)
2743 {
2744 *params = buffer->length();
2745 break;
2746 }
2747 else return error(GL_INVALID_ENUM);
2748 case GL_BUFFER_MAP_OFFSET:
2749 if(clientVersion >= 3)
2750 {
2751 *params = buffer->offset();
2752 break;
2753 }
2754 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05002755 default:
2756 return error(GL_INVALID_ENUM);
2757 }
2758 }
John Bauman66b8ab22014-05-06 15:57:45 -04002759}
2760
2761GLenum GL_APIENTRY glGetError(void)
2762{
Nicolas Capensf160b172014-11-26 11:58:23 -05002763 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002764
Nicolas Capensf160b172014-11-26 11:58:23 -05002765 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002766
Nicolas Capensf160b172014-11-26 11:58:23 -05002767 if(context)
2768 {
2769 return context->getError();
2770 }
John Bauman66b8ab22014-05-06 15:57:45 -04002771
Nicolas Capensf160b172014-11-26 11:58:23 -05002772 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002773}
2774
2775void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2776{
Nicolas Capens4be33702015-04-28 15:13:30 -07002777 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002778
Nicolas Capensf160b172014-11-26 11:58:23 -05002779 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002780
Nicolas Capensf160b172014-11-26 11:58:23 -05002781 if(context)
2782 {
2783 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002784
Nicolas Capensf160b172014-11-26 11:58:23 -05002785 if(fenceObject == NULL)
2786 {
2787 return error(GL_INVALID_OPERATION);
2788 }
John Bauman66b8ab22014-05-06 15:57:45 -04002789
Nicolas Capensf160b172014-11-26 11:58:23 -05002790 fenceObject->getFenceiv(pname, params);
2791 }
John Bauman66b8ab22014-05-06 15:57:45 -04002792}
2793
2794void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
2795{
Nicolas Capens4be33702015-04-28 15:13:30 -07002796 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002797
Nicolas Capensf160b172014-11-26 11:58:23 -05002798 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002799
Nicolas Capensf160b172014-11-26 11:58:23 -05002800 if(context)
2801 {
2802 if(!(context->getFloatv(pname, params)))
2803 {
2804 GLenum nativeType;
2805 unsigned int numParams = 0;
2806 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2807 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002808
Nicolas Capensf160b172014-11-26 11:58:23 -05002809 if(numParams == 0)
2810 return; // it is known that the pname is valid, but that there are no parameters to return.
John Bauman66b8ab22014-05-06 15:57:45 -04002811
Nicolas Capensf160b172014-11-26 11:58:23 -05002812 if(nativeType == GL_BOOL)
2813 {
2814 GLboolean *boolParams = NULL;
2815 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002816
Nicolas Capensf160b172014-11-26 11:58:23 -05002817 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002818
Nicolas Capensf160b172014-11-26 11:58:23 -05002819 for(unsigned int i = 0; i < numParams; ++i)
2820 {
2821 if(boolParams[i] == GL_FALSE)
2822 params[i] = 0.0f;
2823 else
2824 params[i] = 1.0f;
2825 }
John Bauman66b8ab22014-05-06 15:57:45 -04002826
Nicolas Capensf160b172014-11-26 11:58:23 -05002827 delete [] boolParams;
2828 }
2829 else if(nativeType == GL_INT)
2830 {
2831 GLint *intParams = NULL;
2832 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002833
Nicolas Capensf160b172014-11-26 11:58:23 -05002834 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002835
Nicolas Capensf160b172014-11-26 11:58:23 -05002836 for(unsigned int i = 0; i < numParams; ++i)
2837 {
2838 params[i] = (GLfloat)intParams[i];
2839 }
John Bauman66b8ab22014-05-06 15:57:45 -04002840
Nicolas Capensf160b172014-11-26 11:58:23 -05002841 delete [] intParams;
2842 }
2843 }
2844 }
John Bauman66b8ab22014-05-06 15:57:45 -04002845}
2846
2847void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2848{
Nicolas Capens4be33702015-04-28 15:13:30 -07002849 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002850 target, attachment, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002851
Nicolas Capensf160b172014-11-26 11:58:23 -05002852 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002853
Nicolas Capensf160b172014-11-26 11:58:23 -05002854 if(context)
2855 {
2856 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2857 {
2858 return error(GL_INVALID_ENUM);
2859 }
John Bauman66b8ab22014-05-06 15:57:45 -04002860
Nicolas Capensf160b172014-11-26 11:58:23 -05002861 es2::Framebuffer *framebuffer = NULL;
2862 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2863 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002864 if(context->getReadFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002865 {
2866 return error(GL_INVALID_OPERATION);
2867 }
John Bauman66b8ab22014-05-06 15:57:45 -04002868
Nicolas Capensf160b172014-11-26 11:58:23 -05002869 framebuffer = context->getReadFramebuffer();
2870 }
2871 else
2872 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002873 if(context->getDrawFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002874 {
2875 return error(GL_INVALID_OPERATION);
2876 }
John Bauman66b8ab22014-05-06 15:57:45 -04002877
Nicolas Capensf160b172014-11-26 11:58:23 -05002878 framebuffer = context->getDrawFramebuffer();
2879 }
John Bauman66b8ab22014-05-06 15:57:45 -04002880
Nicolas Capensf160b172014-11-26 11:58:23 -05002881 GLenum attachmentType;
2882 GLuint attachmentHandle;
2883 switch(attachment)
2884 {
2885 case GL_COLOR_ATTACHMENT0:
2886 attachmentType = framebuffer->getColorbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002887 attachmentHandle = framebuffer->getColorbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002888 break;
2889 case GL_DEPTH_ATTACHMENT:
2890 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002891 attachmentHandle = framebuffer->getDepthbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002892 break;
2893 case GL_STENCIL_ATTACHMENT:
2894 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002895 attachmentHandle = framebuffer->getStencilbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002896 break;
2897 default:
2898 return error(GL_INVALID_ENUM);
2899 }
John Bauman66b8ab22014-05-06 15:57:45 -04002900
Nicolas Capensf160b172014-11-26 11:58:23 -05002901 GLenum attachmentObjectType; // Type category
2902 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2903 {
2904 attachmentObjectType = attachmentType;
2905 }
2906 else if(es2::IsTextureTarget(attachmentType))
2907 {
2908 attachmentObjectType = GL_TEXTURE;
2909 }
2910 else UNREACHABLE();
John Bauman66b8ab22014-05-06 15:57:45 -04002911
Nicolas Capensf160b172014-11-26 11:58:23 -05002912 switch(pname)
2913 {
2914 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2915 *params = attachmentObjectType;
2916 break;
2917 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2918 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2919 {
2920 *params = attachmentHandle;
2921 }
2922 else
2923 {
2924 return error(GL_INVALID_ENUM);
2925 }
2926 break;
2927 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2928 if(attachmentObjectType == GL_TEXTURE)
2929 {
2930 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2931 }
2932 else
2933 {
2934 return error(GL_INVALID_ENUM);
2935 }
2936 break;
2937 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2938 if(attachmentObjectType == GL_TEXTURE)
2939 {
2940 if(es2::IsCubemapTextureTarget(attachmentType))
2941 {
2942 *params = attachmentType;
2943 }
2944 else
2945 {
2946 *params = 0;
2947 }
2948 }
2949 else
2950 {
2951 return error(GL_INVALID_ENUM);
2952 }
2953 break;
2954 default:
2955 return error(GL_INVALID_ENUM);
2956 }
2957 }
John Bauman66b8ab22014-05-06 15:57:45 -04002958}
2959
2960GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
2961{
Nicolas Capensf160b172014-11-26 11:58:23 -05002962 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002963
Nicolas Capensf160b172014-11-26 11:58:23 -05002964 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002965}
2966
2967void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
2968{
Nicolas Capens4be33702015-04-28 15:13:30 -07002969 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002970
Nicolas Capensf160b172014-11-26 11:58:23 -05002971 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002972
Nicolas Capens7ae353d2015-03-13 17:59:58 -04002973 if(!context)
2974 {
Greg Hartman6074f122015-04-08 09:57:16 -07002975 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
2976 #ifdef __ANDROID__
2977 ALOGI("expected_badness glGetIntegerv() called without current context.");
2978 #else
2979 ERR("glGetIntegerv() called without current context.");
2980 #endif
Nicolas Capens7ae353d2015-03-13 17:59:58 -04002981
2982 // This is not spec compliant! When there is no current GL context, functions should
2983 // have no side effects. Google Maps queries these values before creating a context,
2984 // so we need this as a bug-compatible workaround.
2985 switch(pname)
2986 {
2987 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return;
2988 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return;
2989 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
2990 case GL_STENCIL_BITS: *params = 8; return;
2991 case GL_ALIASED_LINE_WIDTH_RANGE:
2992 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
2993 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
2994 return;
2995 }
2996 }
2997
Nicolas Capensf160b172014-11-26 11:58:23 -05002998 if(context)
2999 {
3000 if(!(context->getIntegerv(pname, params)))
3001 {
3002 GLenum nativeType;
3003 unsigned int numParams = 0;
3004 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3005 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04003006
Nicolas Capensf160b172014-11-26 11:58:23 -05003007 if(numParams == 0)
3008 return; // it is known that pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04003009
Nicolas Capensf160b172014-11-26 11:58:23 -05003010 if(nativeType == GL_BOOL)
3011 {
3012 GLboolean *boolParams = NULL;
3013 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04003014
Nicolas Capensf160b172014-11-26 11:58:23 -05003015 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04003016
Nicolas Capensf160b172014-11-26 11:58:23 -05003017 for(unsigned int i = 0; i < numParams; ++i)
3018 {
Alexis Hetued306182015-04-02 12:02:28 -04003019 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
Nicolas Capensf160b172014-11-26 11:58:23 -05003020 }
John Bauman66b8ab22014-05-06 15:57:45 -04003021
Nicolas Capensf160b172014-11-26 11:58:23 -05003022 delete [] boolParams;
3023 }
3024 else if(nativeType == GL_FLOAT)
3025 {
3026 GLfloat *floatParams = NULL;
3027 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04003028
Nicolas Capensf160b172014-11-26 11:58:23 -05003029 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04003030
Nicolas Capensf160b172014-11-26 11:58:23 -05003031 for(unsigned int i = 0; i < numParams; ++i)
3032 {
3033 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3034 {
Alexis Hetued306182015-04-02 12:02:28 -04003035 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) * 0.5f);
Nicolas Capensf160b172014-11-26 11:58:23 -05003036 }
3037 else
3038 {
3039 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3040 }
3041 }
John Bauman66b8ab22014-05-06 15:57:45 -04003042
Nicolas Capensf160b172014-11-26 11:58:23 -05003043 delete [] floatParams;
3044 }
3045 }
3046 }
John Bauman66b8ab22014-05-06 15:57:45 -04003047}
3048
3049void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3050{
Nicolas Capens4be33702015-04-28 15:13:30 -07003051 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003052
Nicolas Capensf160b172014-11-26 11:58:23 -05003053 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003054
Nicolas Capensf160b172014-11-26 11:58:23 -05003055 if(context)
3056 {
3057 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003058
Nicolas Capensf160b172014-11-26 11:58:23 -05003059 if(!programObject)
3060 {
3061 return error(GL_INVALID_VALUE);
3062 }
John Bauman66b8ab22014-05-06 15:57:45 -04003063
Nicolas Capensf160b172014-11-26 11:58:23 -05003064 switch(pname)
3065 {
3066 case GL_DELETE_STATUS:
3067 *params = programObject->isFlaggedForDeletion();
3068 return;
3069 case GL_LINK_STATUS:
3070 *params = programObject->isLinked();
3071 return;
3072 case GL_VALIDATE_STATUS:
3073 *params = programObject->isValidated();
3074 return;
3075 case GL_INFO_LOG_LENGTH:
3076 *params = programObject->getInfoLogLength();
3077 return;
3078 case GL_ATTACHED_SHADERS:
3079 *params = programObject->getAttachedShadersCount();
3080 return;
3081 case GL_ACTIVE_ATTRIBUTES:
3082 *params = programObject->getActiveAttributeCount();
3083 return;
3084 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
3085 *params = programObject->getActiveAttributeMaxLength();
3086 return;
3087 case GL_ACTIVE_UNIFORMS:
3088 *params = programObject->getActiveUniformCount();
3089 return;
3090 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
3091 *params = programObject->getActiveUniformMaxLength();
3092 return;
3093 default:
3094 return error(GL_INVALID_ENUM);
3095 }
3096 }
John Bauman66b8ab22014-05-06 15:57:45 -04003097}
3098
3099void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3100{
Nicolas Capens4be33702015-04-28 15:13:30 -07003101 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003102 program, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04003103
Nicolas Capensf160b172014-11-26 11:58:23 -05003104 if(bufsize < 0)
3105 {
3106 return error(GL_INVALID_VALUE);
3107 }
John Bauman66b8ab22014-05-06 15:57:45 -04003108
Nicolas Capensf160b172014-11-26 11:58:23 -05003109 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003110
Nicolas Capensf160b172014-11-26 11:58:23 -05003111 if(context)
3112 {
3113 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003114
Nicolas Capensf160b172014-11-26 11:58:23 -05003115 if(!programObject)
3116 {
3117 return error(GL_INVALID_VALUE);
3118 }
John Bauman66b8ab22014-05-06 15:57:45 -04003119
Nicolas Capensf160b172014-11-26 11:58:23 -05003120 programObject->getInfoLog(bufsize, length, infolog);
3121 }
John Bauman66b8ab22014-05-06 15:57:45 -04003122}
3123
3124void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3125{
Nicolas Capens4be33702015-04-28 15:13:30 -07003126 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003127
Nicolas Capensf160b172014-11-26 11:58:23 -05003128 switch(pname)
3129 {
3130 case GL_CURRENT_QUERY_EXT:
3131 break;
3132 default:
3133 return error(GL_INVALID_ENUM);
3134 }
John Bauman66b8ab22014-05-06 15:57:45 -04003135
Nicolas Capensf160b172014-11-26 11:58:23 -05003136 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003137
Nicolas Capensf160b172014-11-26 11:58:23 -05003138 if(context)
3139 {
3140 params[0] = context->getActiveQuery(target);
3141 }
John Bauman66b8ab22014-05-06 15:57:45 -04003142}
3143
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003144void GL_APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04003145{
Nicolas Capens4be33702015-04-28 15:13:30 -07003146 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003147
Nicolas Capensf160b172014-11-26 11:58:23 -05003148 switch(pname)
3149 {
3150 case GL_QUERY_RESULT_EXT:
3151 case GL_QUERY_RESULT_AVAILABLE_EXT:
3152 break;
3153 default:
3154 return error(GL_INVALID_ENUM);
3155 }
John Bauman66b8ab22014-05-06 15:57:45 -04003156
Nicolas Capensf160b172014-11-26 11:58:23 -05003157 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003158
Nicolas Capensf160b172014-11-26 11:58:23 -05003159 if(context)
3160 {
Alexis Hetu8e32f7b2015-04-28 09:59:09 -04003161 es2::Query *queryObject = context->getQuery(name);
John Bauman66b8ab22014-05-06 15:57:45 -04003162
Nicolas Capensf160b172014-11-26 11:58:23 -05003163 if(!queryObject)
3164 {
3165 return error(GL_INVALID_OPERATION);
3166 }
John Bauman66b8ab22014-05-06 15:57:45 -04003167
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003168 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capensf160b172014-11-26 11:58:23 -05003169 {
3170 return error(GL_INVALID_OPERATION);
3171 }
John Bauman66b8ab22014-05-06 15:57:45 -04003172
Nicolas Capensf160b172014-11-26 11:58:23 -05003173 switch(pname)
3174 {
3175 case GL_QUERY_RESULT_EXT:
3176 params[0] = queryObject->getResult();
3177 break;
3178 case GL_QUERY_RESULT_AVAILABLE_EXT:
3179 params[0] = queryObject->isResultAvailable();
3180 break;
3181 default:
3182 ASSERT(false);
3183 }
3184 }
John Bauman66b8ab22014-05-06 15:57:45 -04003185}
3186
3187void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3188{
Nicolas Capens4be33702015-04-28 15:13:30 -07003189 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003190
Nicolas Capensf160b172014-11-26 11:58:23 -05003191 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003192
Nicolas Capensf160b172014-11-26 11:58:23 -05003193 if(context)
3194 {
3195 if(target != GL_RENDERBUFFER)
3196 {
3197 return error(GL_INVALID_ENUM);
3198 }
John Bauman66b8ab22014-05-06 15:57:45 -04003199
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003200 if(context->getRenderbufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05003201 {
3202 return error(GL_INVALID_OPERATION);
3203 }
John Bauman66b8ab22014-05-06 15:57:45 -04003204
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003205 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
John Bauman66b8ab22014-05-06 15:57:45 -04003206
Nicolas Capensf160b172014-11-26 11:58:23 -05003207 switch(pname)
3208 {
3209 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3210 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3211 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
3212 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3213 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3214 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3215 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3216 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3217 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
3218 case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break;
3219 default:
3220 return error(GL_INVALID_ENUM);
3221 }
3222 }
John Bauman66b8ab22014-05-06 15:57:45 -04003223}
3224
3225void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3226{
Nicolas Capens4be33702015-04-28 15:13:30 -07003227 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003228
Nicolas Capensf160b172014-11-26 11:58:23 -05003229 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003230
Nicolas Capensf160b172014-11-26 11:58:23 -05003231 if(context)
3232 {
3233 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003234
Nicolas Capensf160b172014-11-26 11:58:23 -05003235 if(!shaderObject)
3236 {
3237 return error(GL_INVALID_VALUE);
3238 }
John Bauman66b8ab22014-05-06 15:57:45 -04003239
Nicolas Capensf160b172014-11-26 11:58:23 -05003240 switch(pname)
3241 {
3242 case GL_SHADER_TYPE:
3243 *params = shaderObject->getType();
3244 return;
3245 case GL_DELETE_STATUS:
3246 *params = shaderObject->isFlaggedForDeletion();
3247 return;
3248 case GL_COMPILE_STATUS:
3249 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3250 return;
3251 case GL_INFO_LOG_LENGTH:
3252 *params = shaderObject->getInfoLogLength();
3253 return;
3254 case GL_SHADER_SOURCE_LENGTH:
3255 *params = shaderObject->getSourceLength();
3256 return;
3257 default:
3258 return error(GL_INVALID_ENUM);
3259 }
3260 }
John Bauman66b8ab22014-05-06 15:57:45 -04003261}
3262
3263void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3264{
Nicolas Capens4be33702015-04-28 15:13:30 -07003265 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003266 shader, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04003267
Nicolas Capensf160b172014-11-26 11:58:23 -05003268 if(bufsize < 0)
3269 {
3270 return error(GL_INVALID_VALUE);
3271 }
John Bauman66b8ab22014-05-06 15:57:45 -04003272
Nicolas Capensf160b172014-11-26 11:58:23 -05003273 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003274
Nicolas Capensf160b172014-11-26 11:58:23 -05003275 if(context)
3276 {
3277 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003278
Nicolas Capensf160b172014-11-26 11:58:23 -05003279 if(!shaderObject)
3280 {
3281 return error(GL_INVALID_VALUE);
3282 }
John Bauman66b8ab22014-05-06 15:57:45 -04003283
Nicolas Capensf160b172014-11-26 11:58:23 -05003284 shaderObject->getInfoLog(bufsize, length, infolog);
3285 }
John Bauman66b8ab22014-05-06 15:57:45 -04003286}
3287
3288void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3289{
Nicolas Capens4be33702015-04-28 15:13:30 -07003290 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003291 shadertype, precisiontype, range, precision);
John Bauman66b8ab22014-05-06 15:57:45 -04003292
Nicolas Capensf160b172014-11-26 11:58:23 -05003293 switch(shadertype)
3294 {
3295 case GL_VERTEX_SHADER:
3296 case GL_FRAGMENT_SHADER:
3297 break;
3298 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(precisiontype)
3303 {
3304 case GL_LOW_FLOAT:
3305 case GL_MEDIUM_FLOAT:
3306 case GL_HIGH_FLOAT:
3307 // IEEE 754 single-precision
3308 range[0] = 127;
3309 range[1] = 127;
3310 *precision = 23;
3311 break;
3312 case GL_LOW_INT:
3313 case GL_MEDIUM_INT:
3314 case GL_HIGH_INT:
3315 // Single-precision floating-point numbers can accurately represent integers up to +/-16777216
3316 range[0] = 24;
3317 range[1] = 24;
3318 *precision = 0;
3319 break;
3320 default:
3321 return error(GL_INVALID_ENUM);
3322 }
John Bauman66b8ab22014-05-06 15:57:45 -04003323}
3324
3325void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3326{
Nicolas Capens4be33702015-04-28 15:13:30 -07003327 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003328 shader, bufsize, length, source);
John Bauman66b8ab22014-05-06 15:57:45 -04003329
Nicolas Capensf160b172014-11-26 11:58:23 -05003330 if(bufsize < 0)
3331 {
3332 return error(GL_INVALID_VALUE);
3333 }
John Bauman66b8ab22014-05-06 15:57:45 -04003334
Nicolas Capensf160b172014-11-26 11:58:23 -05003335 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003336
Nicolas Capensf160b172014-11-26 11:58:23 -05003337 if(context)
3338 {
3339 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003340
Nicolas Capensf160b172014-11-26 11:58:23 -05003341 if(!shaderObject)
3342 {
3343 return error(GL_INVALID_OPERATION);
3344 }
John Bauman66b8ab22014-05-06 15:57:45 -04003345
Nicolas Capensf160b172014-11-26 11:58:23 -05003346 shaderObject->getSource(bufsize, length, source);
3347 }
John Bauman66b8ab22014-05-06 15:57:45 -04003348}
3349
3350const GLubyte* GL_APIENTRY glGetString(GLenum name)
3351{
Nicolas Capensf160b172014-11-26 11:58:23 -05003352 TRACE("(GLenum name = 0x%X)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04003353
Nicolas Capensf160b172014-11-26 11:58:23 -05003354 switch(name)
3355 {
3356 case GL_VENDOR:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003357 return (GLubyte*)"Google Inc.";
Nicolas Capensf160b172014-11-26 11:58:23 -05003358 case GL_RENDERER:
3359 return (GLubyte*)"SwiftShader";
3360 case GL_VERSION:
3361 return (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3362 case GL_SHADING_LANGUAGE_VERSION:
3363 return (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3364 case GL_EXTENSIONS:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003365 {
3366 es2::Context *context = es2::getContext();
3367 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)NULL;
3368 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003369 default:
3370 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3371 }
John Bauman66b8ab22014-05-06 15:57:45 -04003372}
3373
3374void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3375{
Nicolas Capens4be33702015-04-28 15:13:30 -07003376 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003377
Nicolas Capensf160b172014-11-26 11:58:23 -05003378 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003379
Nicolas Capensf160b172014-11-26 11:58:23 -05003380 if(context)
3381 {
3382 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003383
Alexis Hetued306182015-04-02 12:02:28 -04003384 egl::GLint clientVersion = context->getClientVersion();
3385
Nicolas Capensf160b172014-11-26 11:58:23 -05003386 switch(target)
3387 {
3388 case GL_TEXTURE_2D:
3389 texture = context->getTexture2D();
3390 break;
3391 case GL_TEXTURE_CUBE_MAP:
3392 texture = context->getTextureCubeMap();
3393 break;
3394 case GL_TEXTURE_EXTERNAL_OES:
3395 texture = context->getTextureExternal();
3396 break;
Alexis Hetued306182015-04-02 12:02:28 -04003397 case GL_TEXTURE_2D_ARRAY:
3398 if(clientVersion < 3)
3399 {
3400 return error(GL_INVALID_ENUM);
3401 }
3402 else
3403 {
3404 UNIMPLEMENTED();
3405 texture = context->getTexture3D();
3406 break;
3407 }
3408 case GL_TEXTURE_3D_OES:
3409 texture = context->getTexture3D();
3410 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003411 default:
3412 return error(GL_INVALID_ENUM);
3413 }
John Bauman66b8ab22014-05-06 15:57:45 -04003414
Nicolas Capensf160b172014-11-26 11:58:23 -05003415 switch(pname)
3416 {
3417 case GL_TEXTURE_MAG_FILTER:
3418 *params = (GLfloat)texture->getMagFilter();
3419 break;
3420 case GL_TEXTURE_MIN_FILTER:
3421 *params = (GLfloat)texture->getMinFilter();
3422 break;
3423 case GL_TEXTURE_WRAP_S:
3424 *params = (GLfloat)texture->getWrapS();
3425 break;
3426 case GL_TEXTURE_WRAP_T:
3427 *params = (GLfloat)texture->getWrapT();
3428 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003429 case GL_TEXTURE_WRAP_R_OES:
3430 *params = (GLfloat)texture->getWrapR();
3431 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003432 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3433 *params = texture->getMaxAnisotropy();
3434 break;
3435 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3436 *params = (GLfloat)1;
3437 break;
Alexis Hetued306182015-04-02 12:02:28 -04003438 case GL_TEXTURE_BASE_LEVEL:
3439 if(clientVersion >= 3)
3440 {
3441 *params = (GLfloat)texture->getBaseLevel();
3442 break;
3443 }
3444 else return error(GL_INVALID_ENUM);
3445 case GL_TEXTURE_COMPARE_FUNC:
3446 if(clientVersion >= 3)
3447 {
3448 *params = (GLfloat)texture->getCompareFunc();
3449 break;
3450 }
3451 else return error(GL_INVALID_ENUM);
3452 case GL_TEXTURE_COMPARE_MODE:
3453 if(clientVersion >= 3)
3454 {
3455 *params = (GLfloat)texture->getCompareMode();
3456 break;
3457 }
3458 else return error(GL_INVALID_ENUM);
3459 case GL_TEXTURE_IMMUTABLE_FORMAT:
3460 if(clientVersion >= 3)
3461 {
3462 *params = (GLfloat)texture->getImmutableFormat();
3463 break;
3464 }
3465 else return error(GL_INVALID_ENUM);
3466 case GL_TEXTURE_MAX_LEVEL:
3467 if(clientVersion >= 3)
3468 {
3469 *params = (GLfloat)texture->getMaxLevel();
3470 break;
3471 }
3472 else return error(GL_INVALID_ENUM);
3473 case GL_TEXTURE_MAX_LOD:
3474 if(clientVersion >= 3)
3475 {
3476 *params = texture->getMaxLOD();
3477 break;
3478 }
3479 else return error(GL_INVALID_ENUM);
3480 case GL_TEXTURE_MIN_LOD:
3481 if(clientVersion >= 3)
3482 {
3483 *params = texture->getMinLOD();
3484 break;
3485 }
3486 else return error(GL_INVALID_ENUM);
3487 case GL_TEXTURE_SWIZZLE_R:
3488 if(clientVersion >= 3)
3489 {
3490 *params = (GLfloat)texture->getSwizzleR();
3491 break;
3492 }
3493 else return error(GL_INVALID_ENUM);
3494 case GL_TEXTURE_SWIZZLE_G:
3495 if(clientVersion >= 3)
3496 {
3497 *params = (GLfloat)texture->getSwizzleG();
3498 break;
3499 }
3500 else return error(GL_INVALID_ENUM);
3501 case GL_TEXTURE_SWIZZLE_B:
3502 if(clientVersion >= 3)
3503 {
3504 *params = (GLfloat)texture->getSwizzleB();
3505 break;
3506 }
3507 else return error(GL_INVALID_ENUM);
3508 case GL_TEXTURE_SWIZZLE_A:
3509 if(clientVersion >= 3)
3510 {
3511 *params = (GLfloat)texture->getSwizzleA();
3512 break;
3513 }
3514 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003515 default:
3516 return error(GL_INVALID_ENUM);
3517 }
3518 }
John Bauman66b8ab22014-05-06 15:57:45 -04003519}
3520
3521void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3522{
Nicolas Capens4be33702015-04-28 15:13:30 -07003523 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003524
Nicolas Capensf160b172014-11-26 11:58:23 -05003525 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003526
Nicolas Capensf160b172014-11-26 11:58:23 -05003527 if(context)
3528 {
3529 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003530
Alexis Hetued306182015-04-02 12:02:28 -04003531 egl::GLint clientVersion = context->getClientVersion();
3532
Nicolas Capensf160b172014-11-26 11:58:23 -05003533 switch(target)
3534 {
3535 case GL_TEXTURE_2D:
3536 texture = context->getTexture2D();
3537 break;
3538 case GL_TEXTURE_CUBE_MAP:
3539 texture = context->getTextureCubeMap();
3540 break;
3541 case GL_TEXTURE_EXTERNAL_OES:
3542 texture = context->getTextureExternal();
3543 break;
Alexis Hetued306182015-04-02 12:02:28 -04003544 case GL_TEXTURE_2D_ARRAY:
3545 if(clientVersion < 3)
3546 {
3547 return error(GL_INVALID_ENUM);
3548 }
3549 else
3550 {
3551 UNIMPLEMENTED();
3552 texture = context->getTexture3D();
3553 break;
3554 }
3555 case GL_TEXTURE_3D_OES:
3556 texture = context->getTexture3D();
3557 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003558 default:
3559 return error(GL_INVALID_ENUM);
3560 }
John Bauman66b8ab22014-05-06 15:57:45 -04003561
Nicolas Capensf160b172014-11-26 11:58:23 -05003562 switch(pname)
3563 {
3564 case GL_TEXTURE_MAG_FILTER:
3565 *params = texture->getMagFilter();
3566 break;
3567 case GL_TEXTURE_MIN_FILTER:
3568 *params = texture->getMinFilter();
3569 break;
3570 case GL_TEXTURE_WRAP_S:
3571 *params = texture->getWrapS();
3572 break;
3573 case GL_TEXTURE_WRAP_T:
3574 *params = texture->getWrapT();
3575 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003576 case GL_TEXTURE_WRAP_R_OES:
3577 *params = texture->getWrapR();
3578 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003579 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3580 *params = (GLint)texture->getMaxAnisotropy();
3581 break;
3582 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3583 *params = 1;
3584 break;
Alexis Hetued306182015-04-02 12:02:28 -04003585 case GL_TEXTURE_BASE_LEVEL:
3586 if(clientVersion >= 3)
3587 {
3588 *params = texture->getBaseLevel();
3589 break;
3590 }
3591 else return error(GL_INVALID_ENUM);
3592 case GL_TEXTURE_COMPARE_FUNC:
3593 if(clientVersion >= 3)
3594 {
3595 *params = (GLint)texture->getCompareFunc();
3596 break;
3597 }
3598 else return error(GL_INVALID_ENUM);
3599 case GL_TEXTURE_COMPARE_MODE:
3600 if(clientVersion >= 3)
3601 {
3602 *params = (GLint)texture->getCompareMode();
3603 break;
3604 }
3605 else return error(GL_INVALID_ENUM);
3606 case GL_TEXTURE_IMMUTABLE_FORMAT:
3607 if(clientVersion >= 3)
3608 {
3609 *params = (GLint)texture->getImmutableFormat();
3610 break;
3611 }
3612 else return error(GL_INVALID_ENUM);
3613 case GL_TEXTURE_MAX_LEVEL:
3614 if(clientVersion >= 3)
3615 {
3616 *params = texture->getMaxLevel();
3617 break;
3618 }
3619 else return error(GL_INVALID_ENUM);
3620 case GL_TEXTURE_MAX_LOD:
3621 if(clientVersion >= 3)
3622 {
3623 *params = (GLint)texture->getMaxLOD();
3624 break;
3625 }
3626 else return error(GL_INVALID_ENUM);
3627 case GL_TEXTURE_MIN_LOD:
3628 if(clientVersion >= 3)
3629 {
3630 *params = (GLint)texture->getMinLOD();
3631 break;
3632 }
3633 else return error(GL_INVALID_ENUM);
3634 case GL_TEXTURE_SWIZZLE_R:
3635 if(clientVersion >= 3)
3636 {
3637 *params = (GLint)texture->getSwizzleR();
3638 break;
3639 }
3640 else return error(GL_INVALID_ENUM);
3641 case GL_TEXTURE_SWIZZLE_G:
3642 if(clientVersion >= 3)
3643 {
3644 *params = (GLint)texture->getSwizzleG();
3645 break;
3646 }
3647 else return error(GL_INVALID_ENUM);
3648 case GL_TEXTURE_SWIZZLE_B:
3649 if(clientVersion >= 3)
3650 {
3651 *params = (GLint)texture->getSwizzleB();
3652 break;
3653 }
3654 else return error(GL_INVALID_ENUM);
3655 case GL_TEXTURE_SWIZZLE_A:
3656 if(clientVersion >= 3)
3657 {
3658 *params = (GLint)texture->getSwizzleA();
3659 break;
3660 }
3661 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003662 default:
3663 return error(GL_INVALID_ENUM);
3664 }
3665 }
John Bauman66b8ab22014-05-06 15:57:45 -04003666}
3667
3668void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3669{
Nicolas Capens4be33702015-04-28 15:13:30 -07003670 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003671 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003672
Nicolas Capensf160b172014-11-26 11:58:23 -05003673 if(bufSize < 0)
3674 {
3675 return error(GL_INVALID_VALUE);
3676 }
John Bauman66b8ab22014-05-06 15:57:45 -04003677
Nicolas Capensf160b172014-11-26 11:58:23 -05003678 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003679
Nicolas Capensf160b172014-11-26 11:58:23 -05003680 if(context)
3681 {
3682 if(program == 0)
3683 {
3684 return error(GL_INVALID_VALUE);
3685 }
John Bauman66b8ab22014-05-06 15:57:45 -04003686
Nicolas Capensf160b172014-11-26 11:58:23 -05003687 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003688
Nicolas Capensf160b172014-11-26 11:58:23 -05003689 if(!programObject || !programObject->isLinked())
3690 {
3691 return error(GL_INVALID_OPERATION);
3692 }
John Bauman66b8ab22014-05-06 15:57:45 -04003693
Nicolas Capensf160b172014-11-26 11:58:23 -05003694 if(!programObject->getUniformfv(location, &bufSize, params))
3695 {
3696 return error(GL_INVALID_OPERATION);
3697 }
3698 }
John Bauman66b8ab22014-05-06 15:57:45 -04003699}
3700
3701void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3702{
Nicolas Capens4be33702015-04-28 15:13:30 -07003703 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003704
Nicolas Capensf160b172014-11-26 11:58:23 -05003705 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003706
Nicolas Capensf160b172014-11-26 11:58:23 -05003707 if(context)
3708 {
3709 if(program == 0)
3710 {
3711 return error(GL_INVALID_VALUE);
3712 }
John Bauman66b8ab22014-05-06 15:57:45 -04003713
Nicolas Capensf160b172014-11-26 11:58:23 -05003714 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003715
Nicolas Capensf160b172014-11-26 11:58:23 -05003716 if(!programObject || !programObject->isLinked())
3717 {
3718 return error(GL_INVALID_OPERATION);
3719 }
John Bauman66b8ab22014-05-06 15:57:45 -04003720
Nicolas Capensf160b172014-11-26 11:58:23 -05003721 if(!programObject->getUniformfv(location, NULL, params))
3722 {
3723 return error(GL_INVALID_OPERATION);
3724 }
3725 }
John Bauman66b8ab22014-05-06 15:57:45 -04003726}
3727
3728void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3729{
Nicolas Capens4be33702015-04-28 15:13:30 -07003730 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003731 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003732
Nicolas Capensf160b172014-11-26 11:58:23 -05003733 if(bufSize < 0)
3734 {
3735 return error(GL_INVALID_VALUE);
3736 }
John Bauman66b8ab22014-05-06 15:57:45 -04003737
Nicolas Capensf160b172014-11-26 11:58:23 -05003738 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003739
Nicolas Capensf160b172014-11-26 11:58:23 -05003740 if(context)
3741 {
3742 if(program == 0)
3743 {
3744 return error(GL_INVALID_VALUE);
3745 }
John Bauman66b8ab22014-05-06 15:57:45 -04003746
Nicolas Capensf160b172014-11-26 11:58:23 -05003747 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003748
Nicolas Capensf160b172014-11-26 11:58:23 -05003749 if(!programObject || !programObject->isLinked())
3750 {
3751 return error(GL_INVALID_OPERATION);
3752 }
John Bauman66b8ab22014-05-06 15:57:45 -04003753
Nicolas Capensf160b172014-11-26 11:58:23 -05003754 if(!programObject)
3755 {
3756 return error(GL_INVALID_OPERATION);
3757 }
John Bauman66b8ab22014-05-06 15:57:45 -04003758
Nicolas Capensf160b172014-11-26 11:58:23 -05003759 if(!programObject->getUniformiv(location, &bufSize, params))
3760 {
3761 return error(GL_INVALID_OPERATION);
3762 }
3763 }
John Bauman66b8ab22014-05-06 15:57:45 -04003764}
3765
3766void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
3767{
Nicolas Capens4be33702015-04-28 15:13:30 -07003768 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003769
Nicolas Capensf160b172014-11-26 11:58:23 -05003770 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003771
Nicolas Capensf160b172014-11-26 11:58:23 -05003772 if(context)
3773 {
3774 if(program == 0)
3775 {
3776 return error(GL_INVALID_VALUE);
3777 }
John Bauman66b8ab22014-05-06 15:57:45 -04003778
Nicolas Capensf160b172014-11-26 11:58:23 -05003779 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003780
Nicolas Capensf160b172014-11-26 11:58:23 -05003781 if(!programObject || !programObject->isLinked())
3782 {
3783 return error(GL_INVALID_OPERATION);
3784 }
John Bauman66b8ab22014-05-06 15:57:45 -04003785
Nicolas Capensf160b172014-11-26 11:58:23 -05003786 if(!programObject)
3787 {
3788 return error(GL_INVALID_OPERATION);
3789 }
John Bauman66b8ab22014-05-06 15:57:45 -04003790
Nicolas Capensf160b172014-11-26 11:58:23 -05003791 if(!programObject->getUniformiv(location, NULL, params))
3792 {
3793 return error(GL_INVALID_OPERATION);
3794 }
3795 }
John Bauman66b8ab22014-05-06 15:57:45 -04003796}
3797
3798int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
3799{
Nicolas Capensf160b172014-11-26 11:58:23 -05003800 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04003801
Nicolas Capensf160b172014-11-26 11:58:23 -05003802 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003803
Nicolas Capensf160b172014-11-26 11:58:23 -05003804 if(strstr(name, "gl_") == name)
3805 {
3806 return -1;
3807 }
John Bauman66b8ab22014-05-06 15:57:45 -04003808
Nicolas Capensf160b172014-11-26 11:58:23 -05003809 if(context)
3810 {
3811 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003812
Nicolas Capensf160b172014-11-26 11:58:23 -05003813 if(!programObject)
3814 {
3815 if(context->getShader(program))
3816 {
3817 return error(GL_INVALID_OPERATION, -1);
3818 }
3819 else
3820 {
3821 return error(GL_INVALID_VALUE, -1);
3822 }
3823 }
John Bauman66b8ab22014-05-06 15:57:45 -04003824
Nicolas Capensf160b172014-11-26 11:58:23 -05003825 if(!programObject->isLinked())
3826 {
3827 return error(GL_INVALID_OPERATION, -1);
3828 }
John Bauman66b8ab22014-05-06 15:57:45 -04003829
Nicolas Capensf160b172014-11-26 11:58:23 -05003830 return programObject->getUniformLocation(name);
3831 }
John Bauman66b8ab22014-05-06 15:57:45 -04003832
Nicolas Capensf160b172014-11-26 11:58:23 -05003833 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04003834}
3835
3836void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3837{
Nicolas Capens4be33702015-04-28 15:13:30 -07003838 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003839
Nicolas Capensf160b172014-11-26 11:58:23 -05003840 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003841
Nicolas Capensf160b172014-11-26 11:58:23 -05003842 if(context)
3843 {
3844 if(index >= es2::MAX_VERTEX_ATTRIBS)
3845 {
3846 return error(GL_INVALID_VALUE);
3847 }
John Bauman66b8ab22014-05-06 15:57:45 -04003848
Nicolas Capensf160b172014-11-26 11:58:23 -05003849 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
Alexis Hetued306182015-04-02 12:02:28 -04003850
3851 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04003852
Nicolas Capensf160b172014-11-26 11:58:23 -05003853 switch(pname)
3854 {
3855 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3856 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3857 break;
3858 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3859 *params = (GLfloat)attribState.mSize;
3860 break;
3861 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3862 *params = (GLfloat)attribState.mStride;
3863 break;
3864 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3865 *params = (GLfloat)attribState.mType;
3866 break;
3867 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3868 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3869 break;
3870 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003871 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003872 break;
3873 case GL_CURRENT_VERTEX_ATTRIB:
Nicolas Capensf160b172014-11-26 11:58:23 -05003874 {
Alexis Hetub4d557d2015-04-24 17:25:10 -04003875 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
3876 for(int i = 0; i < 4; ++i)
3877 {
3878 params[i] = attrib.getCurrentValue(i);
3879 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003880 }
3881 break;
Alexis Hetued306182015-04-02 12:02:28 -04003882 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3883 if(clientVersion >= 3)
3884 {
3885 switch(attribState.mType)
3886 {
3887 case GL_BYTE:
3888 case GL_UNSIGNED_BYTE:
3889 case GL_SHORT:
3890 case GL_UNSIGNED_SHORT:
3891 case GL_INT:
3892 case GL_INT_2_10_10_10_REV:
3893 case GL_UNSIGNED_INT:
3894 case GL_FIXED:
3895 *params = (GLfloat)GL_TRUE;
3896 break;
3897 default:
3898 *params = (GLfloat)GL_FALSE;
3899 break;
3900 }
3901 break;
3902 }
3903 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003904 default: return error(GL_INVALID_ENUM);
3905 }
3906 }
John Bauman66b8ab22014-05-06 15:57:45 -04003907}
3908
3909void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3910{
Nicolas Capens4be33702015-04-28 15:13:30 -07003911 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003912
Nicolas Capensf160b172014-11-26 11:58:23 -05003913 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003914
Nicolas Capensf160b172014-11-26 11:58:23 -05003915 if(context)
3916 {
3917 if(index >= es2::MAX_VERTEX_ATTRIBS)
3918 {
3919 return error(GL_INVALID_VALUE);
3920 }
John Bauman66b8ab22014-05-06 15:57:45 -04003921
Nicolas Capensf160b172014-11-26 11:58:23 -05003922 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
John Bauman66b8ab22014-05-06 15:57:45 -04003923
Alexis Hetued306182015-04-02 12:02:28 -04003924 egl::GLint clientVersion = context->getClientVersion();
3925
Nicolas Capensf160b172014-11-26 11:58:23 -05003926 switch(pname)
3927 {
3928 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3929 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3930 break;
3931 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3932 *params = attribState.mSize;
3933 break;
3934 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3935 *params = attribState.mStride;
3936 break;
3937 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3938 *params = attribState.mType;
3939 break;
3940 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3941 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3942 break;
3943 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003944 *params = attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003945 break;
3946 case GL_CURRENT_VERTEX_ATTRIB:
Nicolas Capensf160b172014-11-26 11:58:23 -05003947 {
Alexis Hetub4d557d2015-04-24 17:25:10 -04003948 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
3949 for(int i = 0; i < 4; ++i)
3950 {
3951 float currentValue = attrib.getCurrentValue(i);
3952 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3953 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003954 }
3955 break;
Alexis Hetued306182015-04-02 12:02:28 -04003956 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3957 if(clientVersion >= 3)
3958 {
3959 switch(attribState.mType)
3960 {
3961 case GL_BYTE:
3962 case GL_UNSIGNED_BYTE:
3963 case GL_SHORT:
3964 case GL_UNSIGNED_SHORT:
3965 case GL_INT:
3966 case GL_INT_2_10_10_10_REV:
3967 case GL_UNSIGNED_INT:
3968 case GL_FIXED:
3969 *params = GL_TRUE;
3970 break;
3971 default:
3972 *params = GL_FALSE;
3973 break;
3974 }
3975 break;
3976 }
3977 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003978 default: return error(GL_INVALID_ENUM);
3979 }
3980 }
John Bauman66b8ab22014-05-06 15:57:45 -04003981}
3982
3983void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
3984{
Nicolas Capens4be33702015-04-28 15:13:30 -07003985 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
John Bauman66b8ab22014-05-06 15:57:45 -04003986
Nicolas Capensf160b172014-11-26 11:58:23 -05003987 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003988
Nicolas Capensf160b172014-11-26 11:58:23 -05003989 if(context)
3990 {
3991 if(index >= es2::MAX_VERTEX_ATTRIBS)
3992 {
3993 return error(GL_INVALID_VALUE);
3994 }
John Bauman66b8ab22014-05-06 15:57:45 -04003995
Nicolas Capensf160b172014-11-26 11:58:23 -05003996 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3997 {
3998 return error(GL_INVALID_ENUM);
3999 }
John Bauman66b8ab22014-05-06 15:57:45 -04004000
Nicolas Capensf160b172014-11-26 11:58:23 -05004001 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
4002 }
John Bauman66b8ab22014-05-06 15:57:45 -04004003}
4004
4005void GL_APIENTRY glHint(GLenum target, GLenum mode)
4006{
Nicolas Capensf160b172014-11-26 11:58:23 -05004007 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
John Bauman66b8ab22014-05-06 15:57:45 -04004008
Nicolas Capensf160b172014-11-26 11:58:23 -05004009 switch(mode)
4010 {
4011 case GL_FASTEST:
4012 case GL_NICEST:
4013 case GL_DONT_CARE:
4014 break;
4015 default:
4016 return error(GL_INVALID_ENUM);
4017 }
John Bauman66b8ab22014-05-06 15:57:45 -04004018
Nicolas Capensf160b172014-11-26 11:58:23 -05004019 es2::Context *context = es2::getContext();
4020 switch(target)
4021 {
4022 case GL_GENERATE_MIPMAP_HINT:
4023 if(context) context->setGenerateMipmapHint(mode);
4024 break;
4025 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4026 if(context) context->setFragmentShaderDerivativeHint(mode);
4027 break;
4028 default:
4029 return error(GL_INVALID_ENUM);
4030 }
John Bauman66b8ab22014-05-06 15:57:45 -04004031}
4032
4033GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
4034{
Nicolas Capensf160b172014-11-26 11:58:23 -05004035 TRACE("(GLuint buffer = %d)", buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004036
Nicolas Capensf160b172014-11-26 11:58:23 -05004037 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004038
Nicolas Capensf160b172014-11-26 11:58:23 -05004039 if(context && buffer)
4040 {
4041 es2::Buffer *bufferObject = context->getBuffer(buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004042
Nicolas Capensf160b172014-11-26 11:58:23 -05004043 if(bufferObject)
4044 {
4045 return GL_TRUE;
4046 }
4047 }
John Bauman66b8ab22014-05-06 15:57:45 -04004048
Nicolas Capensf160b172014-11-26 11:58:23 -05004049 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004050}
4051
4052GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
4053{
Nicolas Capensf160b172014-11-26 11:58:23 -05004054 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04004055
Nicolas Capensf160b172014-11-26 11:58:23 -05004056 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004057
Nicolas Capensf160b172014-11-26 11:58:23 -05004058 if(context)
4059 {
4060 switch(cap)
4061 {
4062 case GL_CULL_FACE: return context->isCullFaceEnabled();
4063 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4064 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4065 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4066 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4067 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4068 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4069 case GL_BLEND: return context->isBlendEnabled();
4070 case GL_DITHER: return context->isDitherEnabled();
4071 default:
4072 return error(GL_INVALID_ENUM, false);
4073 }
4074 }
John Bauman66b8ab22014-05-06 15:57:45 -04004075
Nicolas Capensf160b172014-11-26 11:58:23 -05004076 return false;
John Bauman66b8ab22014-05-06 15:57:45 -04004077}
4078
4079GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
4080{
Nicolas Capensf160b172014-11-26 11:58:23 -05004081 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004082
Nicolas Capensf160b172014-11-26 11:58:23 -05004083 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004084
Nicolas Capensf160b172014-11-26 11:58:23 -05004085 if(context)
4086 {
4087 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004088
Nicolas Capensf160b172014-11-26 11:58:23 -05004089 if(fenceObject == NULL)
4090 {
4091 return GL_FALSE;
4092 }
John Bauman66b8ab22014-05-06 15:57:45 -04004093
Nicolas Capensf160b172014-11-26 11:58:23 -05004094 return fenceObject->isFence();
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
4100GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
4101{
Nicolas Capensf160b172014-11-26 11:58:23 -05004102 TRACE("(GLuint framebuffer = %d)", framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004103
Nicolas Capensf160b172014-11-26 11:58:23 -05004104 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004105
Nicolas Capensf160b172014-11-26 11:58:23 -05004106 if(context && framebuffer)
4107 {
4108 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004109
Nicolas Capensf160b172014-11-26 11:58:23 -05004110 if(framebufferObject)
4111 {
4112 return GL_TRUE;
4113 }
4114 }
John Bauman66b8ab22014-05-06 15:57:45 -04004115
Nicolas Capensf160b172014-11-26 11:58:23 -05004116 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004117}
4118
4119GLboolean GL_APIENTRY glIsProgram(GLuint program)
4120{
Nicolas Capensf160b172014-11-26 11:58:23 -05004121 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004122
Nicolas Capensf160b172014-11-26 11:58:23 -05004123 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004124
Nicolas Capensf160b172014-11-26 11:58:23 -05004125 if(context && program)
4126 {
4127 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004128
Nicolas Capensf160b172014-11-26 11:58:23 -05004129 if(programObject)
4130 {
4131 return GL_TRUE;
4132 }
4133 }
John Bauman66b8ab22014-05-06 15:57:45 -04004134
Nicolas Capensf160b172014-11-26 11:58:23 -05004135 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004136}
4137
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004138GLboolean GL_APIENTRY glIsQueryEXT(GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -04004139{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004140 TRACE("(GLuint name = %d)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04004141
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004142 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05004143 {
4144 return GL_FALSE;
4145 }
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 Hetu8e32f7b2015-04-28 09:59:09 -04004151 es2::Query *queryObject = context->getQuery(name);
John Bauman66b8ab22014-05-06 15:57:45 -04004152
Nicolas Capensf160b172014-11-26 11:58:23 -05004153 if(queryObject)
4154 {
4155 return GL_TRUE;
4156 }
4157 }
John Bauman66b8ab22014-05-06 15:57:45 -04004158
Nicolas Capensf160b172014-11-26 11:58:23 -05004159 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004160}
4161
4162GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
4163{
Nicolas Capensf160b172014-11-26 11:58:23 -05004164 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004165
Nicolas Capensf160b172014-11-26 11:58:23 -05004166 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004167
Nicolas Capensf160b172014-11-26 11:58:23 -05004168 if(context && renderbuffer)
4169 {
4170 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004171
Nicolas Capensf160b172014-11-26 11:58:23 -05004172 if(renderbufferObject)
4173 {
4174 return GL_TRUE;
4175 }
4176 }
John Bauman66b8ab22014-05-06 15:57:45 -04004177
Nicolas Capensf160b172014-11-26 11:58:23 -05004178 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004179}
4180
4181GLboolean GL_APIENTRY glIsShader(GLuint shader)
4182{
Nicolas Capensf160b172014-11-26 11:58:23 -05004183 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004184
Nicolas Capensf160b172014-11-26 11:58:23 -05004185 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004186
Nicolas Capensf160b172014-11-26 11:58:23 -05004187 if(context && shader)
4188 {
4189 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004190
Nicolas Capensf160b172014-11-26 11:58:23 -05004191 if(shaderObject)
4192 {
4193 return GL_TRUE;
4194 }
4195 }
John Bauman66b8ab22014-05-06 15:57:45 -04004196
Nicolas Capensf160b172014-11-26 11:58:23 -05004197 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004198}
4199
4200GLboolean GL_APIENTRY glIsTexture(GLuint texture)
4201{
Nicolas Capensf160b172014-11-26 11:58:23 -05004202 TRACE("(GLuint texture = %d)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004203
Nicolas Capensf160b172014-11-26 11:58:23 -05004204 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004205
Nicolas Capensf160b172014-11-26 11:58:23 -05004206 if(context && texture)
4207 {
4208 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004209
Nicolas Capensf160b172014-11-26 11:58:23 -05004210 if(textureObject)
4211 {
4212 return GL_TRUE;
4213 }
4214 }
John Bauman66b8ab22014-05-06 15:57:45 -04004215
Nicolas Capensf160b172014-11-26 11:58:23 -05004216 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004217}
4218
4219void GL_APIENTRY glLineWidth(GLfloat width)
4220{
Nicolas Capensf160b172014-11-26 11:58:23 -05004221 TRACE("(GLfloat width = %f)", width);
John Bauman66b8ab22014-05-06 15:57:45 -04004222
Nicolas Capensf160b172014-11-26 11:58:23 -05004223 if(width <= 0.0f)
4224 {
4225 return error(GL_INVALID_VALUE);
4226 }
John Bauman66b8ab22014-05-06 15:57:45 -04004227
Nicolas Capensf160b172014-11-26 11:58:23 -05004228 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004229
Nicolas Capensf160b172014-11-26 11:58:23 -05004230 if(context)
4231 {
4232 context->setLineWidth(width);
4233 }
John Bauman66b8ab22014-05-06 15:57:45 -04004234}
4235
4236void GL_APIENTRY glLinkProgram(GLuint program)
4237{
Nicolas Capensf160b172014-11-26 11:58:23 -05004238 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004239
Nicolas Capensf160b172014-11-26 11:58:23 -05004240 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004241
Nicolas Capensf160b172014-11-26 11:58:23 -05004242 if(context)
4243 {
4244 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004245
Nicolas Capensf160b172014-11-26 11:58:23 -05004246 if(!programObject)
4247 {
4248 if(context->getShader(program))
4249 {
4250 return error(GL_INVALID_OPERATION);
4251 }
4252 else
4253 {
4254 return error(GL_INVALID_VALUE);
4255 }
4256 }
John Bauman66b8ab22014-05-06 15:57:45 -04004257
Nicolas Capensf160b172014-11-26 11:58:23 -05004258 programObject->link();
4259 }
John Bauman66b8ab22014-05-06 15:57:45 -04004260}
4261
4262void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
4263{
Nicolas Capensf160b172014-11-26 11:58:23 -05004264 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04004265
Nicolas Capensf160b172014-11-26 11:58:23 -05004266 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004267
Nicolas Capensf160b172014-11-26 11:58:23 -05004268 if(context)
4269 {
Alexis Hetued306182015-04-02 12:02:28 -04004270 egl::GLint clientVersion = context->getClientVersion();
4271
Nicolas Capensf160b172014-11-26 11:58:23 -05004272 switch(pname)
4273 {
4274 case GL_UNPACK_ALIGNMENT:
4275 if(param != 1 && param != 2 && param != 4 && param != 8)
4276 {
4277 return error(GL_INVALID_VALUE);
4278 }
4279 context->setUnpackAlignment(param);
4280 break;
4281 case GL_PACK_ALIGNMENT:
4282 if(param != 1 && param != 2 && param != 4 && param != 8)
4283 {
4284 return error(GL_INVALID_VALUE);
4285 }
4286 context->setPackAlignment(param);
4287 break;
Alexis Hetued306182015-04-02 12:02:28 -04004288 case GL_PACK_ROW_LENGTH:
4289 case GL_PACK_SKIP_PIXELS:
4290 case GL_PACK_SKIP_ROWS:
4291 case GL_UNPACK_ROW_LENGTH:
4292 case GL_UNPACK_IMAGE_HEIGHT:
4293 case GL_UNPACK_SKIP_PIXELS:
4294 case GL_UNPACK_SKIP_ROWS:
4295 case GL_UNPACK_SKIP_IMAGES:
4296 if(clientVersion >= 3)
4297 {
4298 UNIMPLEMENTED();
4299 break;
4300 }
4301 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05004302 default:
4303 return error(GL_INVALID_ENUM);
4304 }
4305 }
John Bauman66b8ab22014-05-06 15:57:45 -04004306}
4307
4308void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
4309{
Nicolas Capensf160b172014-11-26 11:58:23 -05004310 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
John Bauman66b8ab22014-05-06 15:57:45 -04004311
Nicolas Capensf160b172014-11-26 11:58:23 -05004312 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004313
Nicolas Capensf160b172014-11-26 11:58:23 -05004314 if(context)
4315 {
4316 context->setPolygonOffsetParams(factor, units);
4317 }
John Bauman66b8ab22014-05-06 15:57:45 -04004318}
4319
4320void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05004321 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
John Bauman66b8ab22014-05-06 15:57:45 -04004322{
Nicolas Capensf160b172014-11-26 11:58:23 -05004323 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004324 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004325 x, y, width, height, format, type, bufSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04004326
Nicolas Capensf160b172014-11-26 11:58:23 -05004327 if(width < 0 || height < 0 || bufSize < 0)
4328 {
4329 return error(GL_INVALID_VALUE);
4330 }
John Bauman66b8ab22014-05-06 15:57:45 -04004331
Nicolas Capensf160b172014-11-26 11:58:23 -05004332 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004333
Nicolas Capensf160b172014-11-26 11:58:23 -05004334 if(context)
4335 {
4336 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4337 }
John Bauman66b8ab22014-05-06 15:57:45 -04004338}
4339
4340void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
4341{
Nicolas Capensf160b172014-11-26 11:58:23 -05004342 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004343 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004344 x, y, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004345
Nicolas Capensf160b172014-11-26 11:58:23 -05004346 if(width < 0 || height < 0)
4347 {
4348 return error(GL_INVALID_VALUE);
4349 }
John Bauman66b8ab22014-05-06 15:57:45 -04004350
Nicolas Capensf160b172014-11-26 11:58:23 -05004351 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004352
Nicolas Capensf160b172014-11-26 11:58:23 -05004353 if(context)
4354 {
4355 context->readPixels(x, y, width, height, format, type, NULL, pixels);
4356 }
John Bauman66b8ab22014-05-06 15:57:45 -04004357}
4358
4359void GL_APIENTRY glReleaseShaderCompiler(void)
4360{
Nicolas Capensf160b172014-11-26 11:58:23 -05004361 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04004362
Nicolas Capensf160b172014-11-26 11:58:23 -05004363 es2::Shader::releaseCompiler();
John Bauman66b8ab22014-05-06 15:57:45 -04004364}
4365
4366void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4367{
Nicolas Capensf160b172014-11-26 11:58:23 -05004368 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4369 target, samples, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004370
Nicolas Capensf160b172014-11-26 11:58:23 -05004371 switch(target)
4372 {
4373 case GL_RENDERBUFFER:
4374 break;
4375 default:
4376 return error(GL_INVALID_ENUM);
4377 }
John Bauman66b8ab22014-05-06 15:57:45 -04004378
Nicolas Capensf160b172014-11-26 11:58:23 -05004379 if(!es2::IsColorRenderable(internalformat) && !es2::IsDepthRenderable(internalformat) && !es2::IsStencilRenderable(internalformat))
4380 {
4381 return error(GL_INVALID_ENUM);
4382 }
John Bauman66b8ab22014-05-06 15:57:45 -04004383
Nicolas Capensf160b172014-11-26 11:58:23 -05004384 if(width < 0 || height < 0 || samples < 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 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4394 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4395 samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4396 {
4397 return error(GL_INVALID_VALUE);
4398 }
John Bauman66b8ab22014-05-06 15:57:45 -04004399
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004400 GLuint handle = context->getRenderbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05004401 if(handle == 0)
4402 {
4403 return error(GL_INVALID_OPERATION);
4404 }
John Bauman66b8ab22014-05-06 15:57:45 -04004405
Nicolas Capensf160b172014-11-26 11:58:23 -05004406 switch(internalformat)
4407 {
4408 case GL_DEPTH_COMPONENT16:
4409 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, samples));
4410 break;
4411 case GL_RGBA4:
4412 case GL_RGB5_A1:
4413 case GL_RGB565:
4414 case GL_RGB8_OES:
4415 case GL_RGBA8_OES:
4416 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4417 break;
4418 case GL_STENCIL_INDEX8:
4419 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4420 break;
4421 case GL_DEPTH24_STENCIL8_OES:
4422 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, samples));
4423 break;
4424 default:
4425 return error(GL_INVALID_ENUM);
4426 }
4427 }
John Bauman66b8ab22014-05-06 15:57:45 -04004428}
4429
4430void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4431{
Nicolas Capensf160b172014-11-26 11:58:23 -05004432 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004433}
4434
4435void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
4436{
Nicolas Capensf160b172014-11-26 11:58:23 -05004437 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
John Bauman66b8ab22014-05-06 15:57:45 -04004438
Nicolas Capensf160b172014-11-26 11:58:23 -05004439 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004440
Nicolas Capensf160b172014-11-26 11:58:23 -05004441 if(context)
4442 {
4443 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4444 }
John Bauman66b8ab22014-05-06 15:57:45 -04004445}
4446
4447void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
4448{
Nicolas Capensf160b172014-11-26 11:58:23 -05004449 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
John Bauman66b8ab22014-05-06 15:57:45 -04004450
Nicolas Capensf160b172014-11-26 11:58:23 -05004451 if(condition != GL_ALL_COMPLETED_NV)
4452 {
4453 return error(GL_INVALID_ENUM);
4454 }
John Bauman66b8ab22014-05-06 15:57:45 -04004455
Nicolas Capensf160b172014-11-26 11:58:23 -05004456 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004457
Nicolas Capensf160b172014-11-26 11:58:23 -05004458 if(context)
4459 {
4460 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004461
Nicolas Capensf160b172014-11-26 11:58:23 -05004462 if(fenceObject == NULL)
4463 {
4464 return error(GL_INVALID_OPERATION);
4465 }
John Bauman66b8ab22014-05-06 15:57:45 -04004466
Nicolas Capensf160b172014-11-26 11:58:23 -05004467 fenceObject->setFence(condition);
4468 }
John Bauman66b8ab22014-05-06 15:57:45 -04004469}
4470
4471void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4472{
Nicolas Capensf160b172014-11-26 11:58:23 -05004473 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004474
Nicolas Capensf160b172014-11-26 11:58:23 -05004475 if(width < 0 || height < 0)
4476 {
4477 return error(GL_INVALID_VALUE);
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 context->setScissorParams(x, y, width, height);
4485 }
John Bauman66b8ab22014-05-06 15:57:45 -04004486}
4487
4488void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4489{
Nicolas Capens4be33702015-04-28 15:13:30 -07004490 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4491 "const GLvoid* binary = %p, GLsizei length = %d)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004492 n, shaders, binaryformat, binary, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004493
Nicolas Capensf160b172014-11-26 11:58:23 -05004494 // No binary shader formats are supported.
4495 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04004496}
4497
Nicolas Capensb0e93552014-10-28 11:54:43 -04004498void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
John Bauman66b8ab22014-05-06 15:57:45 -04004499{
Nicolas Capens4be33702015-04-28 15:13:30 -07004500 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004501 shader, count, string, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004502
Nicolas Capensf160b172014-11-26 11:58:23 -05004503 if(count < 0)
4504 {
4505 return error(GL_INVALID_VALUE);
4506 }
John Bauman66b8ab22014-05-06 15:57:45 -04004507
Nicolas Capensf160b172014-11-26 11:58:23 -05004508 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004509
Nicolas Capensf160b172014-11-26 11:58:23 -05004510 if(context)
4511 {
4512 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004513
Nicolas Capensf160b172014-11-26 11:58:23 -05004514 if(!shaderObject)
4515 {
4516 if(context->getProgram(shader))
4517 {
4518 return error(GL_INVALID_OPERATION);
4519 }
4520 else
4521 {
4522 return error(GL_INVALID_VALUE);
4523 }
4524 }
John Bauman66b8ab22014-05-06 15:57:45 -04004525
Nicolas Capensf160b172014-11-26 11:58:23 -05004526 shaderObject->setSource(count, string, length);
4527 }
John Bauman66b8ab22014-05-06 15:57:45 -04004528}
4529
4530void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
4531{
Nicolas Capensf160b172014-11-26 11:58:23 -05004532 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004533}
4534
4535void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4536{
Nicolas Capensf160b172014-11-26 11:58:23 -05004537 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 -04004538
Nicolas Capensf160b172014-11-26 11:58:23 -05004539 switch(face)
4540 {
4541 case GL_FRONT:
4542 case GL_BACK:
4543 case GL_FRONT_AND_BACK:
4544 break;
4545 default:
4546 return error(GL_INVALID_ENUM);
4547 }
John Bauman66b8ab22014-05-06 15:57:45 -04004548
Nicolas Capensf160b172014-11-26 11:58:23 -05004549 switch(func)
4550 {
4551 case GL_NEVER:
4552 case GL_ALWAYS:
4553 case GL_LESS:
4554 case GL_LEQUAL:
4555 case GL_EQUAL:
4556 case GL_GEQUAL:
4557 case GL_GREATER:
4558 case GL_NOTEQUAL:
4559 break;
4560 default:
4561 return error(GL_INVALID_ENUM);
4562 }
John Bauman66b8ab22014-05-06 15:57:45 -04004563
Nicolas Capensf160b172014-11-26 11:58:23 -05004564 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004565
Nicolas Capensf160b172014-11-26 11:58:23 -05004566 if(context)
4567 {
4568 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4569 {
4570 context->setStencilParams(func, ref, mask);
4571 }
John Bauman66b8ab22014-05-06 15:57:45 -04004572
Nicolas Capensf160b172014-11-26 11:58:23 -05004573 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4574 {
4575 context->setStencilBackParams(func, ref, mask);
4576 }
4577 }
John Bauman66b8ab22014-05-06 15:57:45 -04004578}
4579
4580void GL_APIENTRY glStencilMask(GLuint mask)
4581{
Nicolas Capensf160b172014-11-26 11:58:23 -05004582 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004583}
4584
4585void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
4586{
Nicolas Capensf160b172014-11-26 11:58:23 -05004587 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004588
Nicolas Capensf160b172014-11-26 11:58:23 -05004589 switch(face)
4590 {
4591 case GL_FRONT:
4592 case GL_BACK:
4593 case GL_FRONT_AND_BACK:
4594 break;
4595 default:
4596 return error(GL_INVALID_ENUM);
4597 }
John Bauman66b8ab22014-05-06 15:57:45 -04004598
Nicolas Capensf160b172014-11-26 11:58:23 -05004599 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004600
Nicolas Capensf160b172014-11-26 11:58:23 -05004601 if(context)
4602 {
4603 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4604 {
4605 context->setStencilWritemask(mask);
4606 }
John Bauman66b8ab22014-05-06 15:57:45 -04004607
Nicolas Capensf160b172014-11-26 11:58:23 -05004608 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4609 {
4610 context->setStencilBackWritemask(mask);
4611 }
4612 }
John Bauman66b8ab22014-05-06 15:57:45 -04004613}
4614
4615void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4616{
Nicolas Capensf160b172014-11-26 11:58:23 -05004617 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004618}
4619
4620void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4621{
Nicolas Capensf160b172014-11-26 11:58:23 -05004622 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4623 face, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004624
Nicolas Capensf160b172014-11-26 11:58:23 -05004625 switch(face)
4626 {
4627 case GL_FRONT:
4628 case GL_BACK:
4629 case GL_FRONT_AND_BACK:
4630 break;
4631 default:
4632 return error(GL_INVALID_ENUM);
4633 }
John Bauman66b8ab22014-05-06 15:57:45 -04004634
Nicolas Capensf160b172014-11-26 11:58:23 -05004635 switch(fail)
4636 {
4637 case GL_ZERO:
4638 case GL_KEEP:
4639 case GL_REPLACE:
4640 case GL_INCR:
4641 case GL_DECR:
4642 case GL_INVERT:
4643 case GL_INCR_WRAP:
4644 case GL_DECR_WRAP:
4645 break;
4646 default:
4647 return error(GL_INVALID_ENUM);
4648 }
John Bauman66b8ab22014-05-06 15:57:45 -04004649
Nicolas Capensf160b172014-11-26 11:58:23 -05004650 switch(zfail)
4651 {
4652 case GL_ZERO:
4653 case GL_KEEP:
4654 case GL_REPLACE:
4655 case GL_INCR:
4656 case GL_DECR:
4657 case GL_INVERT:
4658 case GL_INCR_WRAP:
4659 case GL_DECR_WRAP:
4660 break;
4661 default:
4662 return error(GL_INVALID_ENUM);
4663 }
John Bauman66b8ab22014-05-06 15:57:45 -04004664
Nicolas Capensf160b172014-11-26 11:58:23 -05004665 switch(zpass)
4666 {
4667 case GL_ZERO:
4668 case GL_KEEP:
4669 case GL_REPLACE:
4670 case GL_INCR:
4671 case GL_DECR:
4672 case GL_INVERT:
4673 case GL_INCR_WRAP:
4674 case GL_DECR_WRAP:
4675 break;
4676 default:
4677 return error(GL_INVALID_ENUM);
4678 }
John Bauman66b8ab22014-05-06 15:57:45 -04004679
Nicolas Capensf160b172014-11-26 11:58:23 -05004680 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004681
Nicolas Capensf160b172014-11-26 11:58:23 -05004682 if(context)
4683 {
4684 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4685 {
4686 context->setStencilOperations(fail, zfail, zpass);
4687 }
John Bauman66b8ab22014-05-06 15:57:45 -04004688
Nicolas Capensf160b172014-11-26 11:58:23 -05004689 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4690 {
4691 context->setStencilBackOperations(fail, zfail, zpass);
4692 }
4693 }
John Bauman66b8ab22014-05-06 15:57:45 -04004694}
4695
4696GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
4697{
Nicolas Capensf160b172014-11-26 11:58:23 -05004698 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004699
Nicolas Capensf160b172014-11-26 11:58:23 -05004700 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004701
Nicolas Capensf160b172014-11-26 11:58:23 -05004702 if(context)
4703 {
4704 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004705
Nicolas Capensf160b172014-11-26 11:58:23 -05004706 if(fenceObject == NULL)
4707 {
4708 return error(GL_INVALID_OPERATION, GL_TRUE);
4709 }
John Bauman66b8ab22014-05-06 15:57:45 -04004710
Nicolas Capensf160b172014-11-26 11:58:23 -05004711 return fenceObject->testFence();
4712 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05004713
Nicolas Capensf160b172014-11-26 11:58:23 -05004714 return GL_TRUE;
John Bauman66b8ab22014-05-06 15:57:45 -04004715}
4716
4717void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4718 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4719{
Nicolas Capensf160b172014-11-26 11:58:23 -05004720 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004721 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004722 target, level, internalformat, width, height, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004723
Nicolas Capensf160b172014-11-26 11:58:23 -05004724 if(!validImageSize(level, width, height))
4725 {
4726 return error(GL_INVALID_VALUE);
4727 }
John Bauman66b8ab22014-05-06 15:57:45 -04004728
Nicolas Capensf160b172014-11-26 11:58:23 -05004729 es2::Context *context = es2::getContext();
4730
4731 if(context)
4732 {
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004733 if(context->getClientVersion() < 3)
4734 {
4735 if(internalformat != format)
4736 {
4737 return error(GL_INVALID_OPERATION);
4738 }
4739 }
4740
4741 switch(format)
4742 {
4743 case GL_ALPHA:
4744 case GL_LUMINANCE:
4745 case GL_LUMINANCE_ALPHA:
4746 switch(type)
4747 {
4748 case GL_UNSIGNED_BYTE:
4749 case GL_FLOAT:
4750 case GL_HALF_FLOAT_OES:
4751 break;
4752 default:
4753 return error(GL_INVALID_ENUM);
4754 }
4755 break;
Alexis Hetued306182015-04-02 12:02:28 -04004756 case GL_RED:
4757 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004758 {
Alexis Hetued306182015-04-02 12:02:28 -04004759 case GL_R8:
4760 switch(type)
4761 {
4762 case GL_UNSIGNED_BYTE:
4763 break;
4764 default:
4765 return error(GL_INVALID_ENUM);
4766 }
4767 break;
4768 case GL_R8_SNORM:
4769 switch(type)
4770 {
4771 case GL_BYTE:
4772 break;
4773 default:
4774 return error(GL_INVALID_ENUM);
4775 }
4776 break;
4777 case GL_R16F:
4778 switch(type)
4779 {
4780 case GL_FLOAT:
4781 case GL_HALF_FLOAT:
4782 break;
4783 default:
4784 return error(GL_INVALID_ENUM);
4785 }
4786 break;
4787 case GL_R32F:
4788 switch(type)
4789 {
4790 case GL_FLOAT:
4791 break;
4792 default:
4793 return error(GL_INVALID_ENUM);
4794 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004795 break;
4796 default:
Alexis Hetued306182015-04-02 12:02:28 -04004797 return error(GL_INVALID_VALUE);
4798 }
4799 break;
4800 case GL_RED_INTEGER:
4801 switch(internalformat)
4802 {
4803 case GL_R8UI:
4804 switch(type)
4805 {
4806 case GL_UNSIGNED_BYTE:
4807 break;
4808 default:
4809 return error(GL_INVALID_ENUM);
4810 }
4811 break;
4812 case GL_R8I:
4813 switch(type)
4814 {
4815 case GL_BYTE:
4816 break;
4817 default:
4818 return error(GL_INVALID_ENUM);
4819 }
4820 break;
4821 case GL_R16UI:
4822 switch(type)
4823 {
4824 case GL_UNSIGNED_SHORT:
4825 break;
4826 default:
4827 return error(GL_INVALID_ENUM);
4828 }
4829 break;
4830 case GL_R16I:
4831 switch(type)
4832 {
4833 case GL_SHORT:
4834 break;
4835 default:
4836 return error(GL_INVALID_ENUM);
4837 }
4838 break;
4839 case GL_R32UI:
4840 switch(type)
4841 {
4842 case GL_UNSIGNED_INT:
4843 break;
4844 default:
4845 return error(GL_INVALID_ENUM);
4846 }
4847 break;
4848 case GL_R32I:
4849 switch(type)
4850 {
4851 case GL_INT:
4852 break;
4853 default:
4854 return error(GL_INVALID_ENUM);
4855 }
4856 break;
4857 default:
4858 return error(GL_INVALID_VALUE);
4859 }
4860 break;
4861 case GL_RG_INTEGER:
4862 switch(internalformat)
4863 {
4864 case GL_RG8UI:
4865 switch(type)
4866 {
4867 case GL_UNSIGNED_BYTE:
4868 break;
4869 default:
4870 return error(GL_INVALID_ENUM);
4871 }
4872 break;
4873 case GL_RG8I:
4874 switch(type)
4875 {
4876 case GL_BYTE:
4877 break;
4878 default:
4879 return error(GL_INVALID_ENUM);
4880 }
4881 break;
4882 case GL_RG16UI:
4883 switch(type)
4884 {
4885 case GL_UNSIGNED_SHORT:
4886 break;
4887 default:
4888 return error(GL_INVALID_ENUM);
4889 }
4890 break;
4891 case GL_RG16I:
4892 switch(type)
4893 {
4894 case GL_SHORT:
4895 break;
4896 default:
4897 return error(GL_INVALID_ENUM);
4898 }
4899 break;
4900 case GL_RG32UI:
4901 switch(type)
4902 {
4903 case GL_UNSIGNED_INT:
4904 break;
4905 default:
4906 return error(GL_INVALID_ENUM);
4907 }
4908 break;
4909 case GL_RG32I:
4910 switch(type)
4911 {
4912 case GL_INT:
4913 break;
4914 default:
4915 return error(GL_INVALID_ENUM);
4916 }
4917 break;
4918 default:
4919 return error(GL_INVALID_VALUE);
4920 }
4921 break;
4922 case GL_RGB_INTEGER:
4923 switch(internalformat)
4924 {
4925 case GL_RGB8UI:
4926 switch(type)
4927 {
4928 case GL_UNSIGNED_BYTE:
4929 break;
4930 default:
4931 return error(GL_INVALID_ENUM);
4932 }
4933 break;
4934 case GL_RGB8I:
4935 switch(type)
4936 {
4937 case GL_BYTE:
4938 break;
4939 default:
4940 return error(GL_INVALID_ENUM);
4941 }
4942 break;
4943 case GL_RGB16UI:
4944 switch(type)
4945 {
4946 case GL_UNSIGNED_SHORT:
4947 break;
4948 default:
4949 return error(GL_INVALID_ENUM);
4950 }
4951 break;
4952 case GL_RGB16I:
4953 switch(type)
4954 {
4955 case GL_SHORT:
4956 break;
4957 default:
4958 return error(GL_INVALID_ENUM);
4959 }
4960 break;
4961 case GL_RGB32UI:
4962 switch(type)
4963 {
4964 case GL_UNSIGNED_INT:
4965 break;
4966 default:
4967 return error(GL_INVALID_ENUM);
4968 }
4969 break;
4970 case GL_RGB32I:
4971 switch(type)
4972 {
4973 case GL_INT:
4974 break;
4975 default:
4976 return error(GL_INVALID_ENUM);
4977 }
4978 break;
4979 default:
4980 return error(GL_INVALID_VALUE);
4981 }
4982 break;
4983 case GL_RGBA_INTEGER:
4984 switch(internalformat)
4985 {
4986 case GL_RGBA8UI:
4987 switch(type)
4988 {
4989 case GL_UNSIGNED_BYTE:
4990 break;
4991 default:
4992 return error(GL_INVALID_ENUM);
4993 }
4994 break;
4995 case GL_RGBA8I:
4996 switch(type)
4997 {
4998 case GL_BYTE:
4999 break;
5000 default:
5001 return error(GL_INVALID_ENUM);
5002 }
5003 break;
5004 case GL_RGB10_A2UI:
5005 switch(type)
5006 {
5007 case GL_UNSIGNED_INT_2_10_10_10_REV:
5008 break;
5009 default:
5010 return error(GL_INVALID_ENUM);
5011 }
5012 break;
5013 case GL_RGBA16UI:
5014 switch(type)
5015 {
5016 case GL_UNSIGNED_SHORT:
5017 break;
5018 default:
5019 return error(GL_INVALID_ENUM);
5020 }
5021 break;
5022 case GL_RGBA16I:
5023 switch(type)
5024 {
5025 case GL_SHORT:
5026 break;
5027 default:
5028 return error(GL_INVALID_ENUM);
5029 }
5030 break;
5031 case GL_RGBA32UI:
5032 switch(type)
5033 {
5034 case GL_INT:
5035 break;
5036 default:
5037 return error(GL_INVALID_ENUM);
5038 }
5039 break;
5040 case GL_RGBA32I:
5041 switch(type)
5042 {
5043 case GL_UNSIGNED_INT:
5044 break;
5045 default:
5046 return error(GL_INVALID_ENUM);
5047 }
5048 break;
5049 default:
5050 return error(GL_INVALID_VALUE);
5051 }
5052 break;
5053 case GL_RG:
5054 switch(internalformat)
5055 {
5056 case GL_RG8:
5057 switch(type)
5058 {
5059 case GL_UNSIGNED_BYTE:
5060 break;
5061 default:
5062 return error(GL_INVALID_ENUM);
5063 }
5064 break;
5065 case GL_RG8_SNORM:
5066 switch(type)
5067 {
5068 case GL_BYTE:
5069 break;
5070 default:
5071 return error(GL_INVALID_ENUM);
5072 }
5073 break;
5074 case GL_RG16F:
5075 switch(type)
5076 {
5077 case GL_FLOAT:
5078 case GL_HALF_FLOAT:
5079 break;
5080 default:
5081 return error(GL_INVALID_ENUM);
5082 }
5083 break;
5084 case GL_RG32F:
5085 switch(type)
5086 {
5087 case GL_FLOAT:
5088 break;
5089 default:
5090 return error(GL_INVALID_ENUM);
5091 }
5092 break;
5093 default:
5094 return error(GL_INVALID_VALUE);
5095 }
5096 break;
5097 case GL_RGB:
5098 switch(internalformat)
5099 {
5100 case GL_RGB:
5101 switch(type)
5102 {
5103 case GL_UNSIGNED_BYTE:
5104 case GL_UNSIGNED_SHORT_5_6_5:
5105 case GL_FLOAT:
5106 case GL_HALF_FLOAT_OES:
5107 break;
5108 default:
5109 return error(GL_INVALID_ENUM);
5110 }
5111 break;
5112 case GL_RGB8:
5113 switch(type)
5114 {
5115 case GL_UNSIGNED_BYTE:
5116 break;
5117 default:
5118 return error(GL_INVALID_ENUM);
5119 }
5120 break;
5121 case GL_SRGB8:
5122 switch(type)
5123 {
5124 case GL_UNSIGNED_BYTE:
5125 break;
5126 default:
5127 return error(GL_INVALID_ENUM);
5128 }
5129 break;
5130 case GL_RGB565:
5131 switch(type)
5132 {
5133 case GL_UNSIGNED_BYTE:
5134 case GL_UNSIGNED_SHORT_5_6_5:
5135 break;
5136 default:
5137 return error(GL_INVALID_ENUM);
5138 }
5139 break;
5140 case GL_RGB8_SNORM:
5141 switch(type)
5142 {
5143 case GL_BYTE:
5144 break;
5145 default:
5146 return error(GL_INVALID_ENUM);
5147 }
5148 break;
5149 case GL_R11F_G11F_B10F:
5150 switch(type)
5151 {
5152 case GL_UNSIGNED_INT_10F_11F_11F_REV:
5153 case GL_FLOAT:
5154 case GL_HALF_FLOAT:
5155 break;
5156 default:
5157 return error(GL_INVALID_ENUM);
5158 }
5159 break;
5160 case GL_RGB9_E5:
5161 switch(type)
5162 {
5163 case GL_UNSIGNED_INT_5_9_9_9_REV:
5164 case GL_FLOAT:
5165 case GL_HALF_FLOAT:
5166 break;
5167 default:
5168 return error(GL_INVALID_ENUM);
5169 }
5170 break;
5171 case GL_RGB16F:
5172 switch(type)
5173 {
5174 case GL_FLOAT:
5175 case GL_HALF_FLOAT:
5176 break;
5177 default:
5178 return error(GL_INVALID_ENUM);
5179 }
5180 break;
5181 case GL_RGB32F:
5182 switch(type)
5183 {
5184 case GL_FLOAT:
5185 break;
5186 default:
5187 return error(GL_INVALID_ENUM);
5188 }
5189 break;
5190 default:
5191 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005192 }
5193 break;
5194 case GL_RGBA:
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_RGBA:
5198 switch(type)
5199 {
5200 case GL_UNSIGNED_BYTE:
5201 case GL_UNSIGNED_SHORT_4_4_4_4:
5202 case GL_UNSIGNED_SHORT_5_5_5_1:
5203 case GL_FLOAT:
5204 case GL_HALF_FLOAT_OES:
5205 break;
5206 default:
5207 return error(GL_INVALID_ENUM);
5208 }
5209 break;
5210 case GL_RGBA8:
5211 switch(type)
5212 {
5213 case GL_UNSIGNED_BYTE:
5214 break;
5215 default:
5216 return error(GL_INVALID_ENUM);
5217 }
5218 break;
5219 case GL_SRGB8_ALPHA8:
5220 switch(type)
5221 {
5222 case GL_UNSIGNED_BYTE:
5223 break;
5224 default:
5225 return error(GL_INVALID_ENUM);
5226 }
5227 break;
5228 case GL_RGB5_A1:
5229 switch(type)
5230 {
5231 case GL_UNSIGNED_BYTE:
5232 case GL_UNSIGNED_SHORT_5_5_5_1:
5233 case GL_UNSIGNED_INT_2_10_10_10_REV:
5234 break;
5235 default:
5236 return error(GL_INVALID_ENUM);
5237 }
5238 break;
5239 case GL_RGBA8_SNORM:
5240 switch(type)
5241 {
5242 case GL_BYTE:
5243 break;
5244 default:
5245 return error(GL_INVALID_ENUM);
5246 }
5247 break;
5248 case GL_RGBA4:
5249 switch(type)
5250 {
5251 case GL_UNSIGNED_BYTE:
5252 case GL_UNSIGNED_SHORT_4_4_4_4:
5253 break;
5254 default:
5255 return error(GL_INVALID_ENUM);
5256 }
5257 break;
5258 case GL_RGB10_A2:
5259 switch(type)
5260 {
5261 case GL_UNSIGNED_INT_2_10_10_10_REV:
5262 break;
5263 default:
5264 return error(GL_INVALID_ENUM);
5265 }
5266 break;
5267 case GL_RGBA16F:
5268 switch(type)
5269 {
5270 case GL_FLOAT:
5271 case GL_HALF_FLOAT:
5272 break;
5273 default:
5274 return error(GL_INVALID_ENUM);
5275 }
5276 break;
5277 case GL_RGBA32F:
5278 switch(type)
5279 {
5280 case GL_FLOAT:
5281 break;
5282 default:
5283 return error(GL_INVALID_ENUM);
5284 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005285 break;
5286 default:
Alexis Hetued306182015-04-02 12:02:28 -04005287 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005288 }
5289 break;
5290 case GL_BGRA_EXT:
5291 switch(type)
5292 {
5293 case GL_UNSIGNED_BYTE:
5294 break;
5295 default:
5296 return error(GL_INVALID_ENUM);
5297 }
5298 break;
5299 case GL_ETC1_RGB8_OES:
5300 return error(GL_INVALID_OPERATION);
5301 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5302 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5303 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5304 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5305 if(S3TC_SUPPORT)
5306 {
5307 return error(GL_INVALID_OPERATION);
5308 }
5309 else
5310 {
5311 return error(GL_INVALID_ENUM);
5312 }
5313 case GL_DEPTH_COMPONENT:
Alexis Hetued306182015-04-02 12:02:28 -04005314 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005315 {
Alexis Hetued306182015-04-02 12:02:28 -04005316 case GL_DEPTH_COMPONENT:
5317 case GL_DEPTH_COMPONENT16:
5318 switch(type)
5319 {
5320 case GL_UNSIGNED_SHORT:
5321 case GL_UNSIGNED_INT:
5322 break;
5323 default:
5324 return error(GL_INVALID_ENUM);
5325 }
5326 break;
5327 case GL_DEPTH_COMPONENT24:
5328 switch(type)
5329 {
5330 case GL_UNSIGNED_INT:
5331 break;
5332 default:
5333 return error(GL_INVALID_ENUM);
5334 }
5335 break;
5336 case GL_DEPTH_COMPONENT32F:
5337 switch(type)
5338 {
5339 case GL_UNSIGNED_INT:
5340 break;
5341 default:
5342 return error(GL_INVALID_ENUM);
5343 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005344 break;
5345 default:
Alexis Hetued306182015-04-02 12:02:28 -04005346 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005347 }
5348 break;
5349 case GL_DEPTH_STENCIL_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005350 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005351 {
Alexis Hetued306182015-04-02 12:02:28 -04005352 case GL_DEPTH_STENCIL_OES:
5353 case GL_DEPTH24_STENCIL8:
5354 switch(type)
5355 {
5356 case GL_UNSIGNED_INT_24_8_OES:
5357 break;
5358 default:
5359 return error(GL_INVALID_ENUM);
5360 }
5361 break;
5362 case GL_DEPTH32F_STENCIL8:
5363 switch(type)
5364 {
5365 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
5366 break;
5367 default:
5368 return error(GL_INVALID_ENUM);
5369 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005370 break;
5371 default:
Alexis Hetued306182015-04-02 12:02:28 -04005372 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005373 }
5374 break;
5375 default:
5376 return error(GL_INVALID_VALUE);
5377 }
5378
5379 if(border != 0)
5380 {
5381 return error(GL_INVALID_VALUE);
5382 }
5383
Nicolas Capensf160b172014-11-26 11:58:23 -05005384 switch(target)
5385 {
Nicolas Capens22658242014-11-29 00:31:41 -05005386 case GL_TEXTURE_2D:
Nicolas Capensf160b172014-11-26 11:58:23 -05005387 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5388 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
John Bauman66b8ab22014-05-06 15:57:45 -04005389 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005390 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005391 }
5392 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005393 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5394 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5395 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5396 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5397 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5398 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
Nicolas Capensf160b172014-11-26 11:58:23 -05005399 if(width != height)
John Bauman66b8ab22014-05-06 15:57:45 -04005400 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005401 return error(GL_INVALID_VALUE);
5402 }
5403
5404 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5405 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5406 {
5407 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005408 }
5409 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005410 default:
Nicolas Capensf160b172014-11-26 11:58:23 -05005411 return error(GL_INVALID_ENUM);
5412 }
John Bauman66b8ab22014-05-06 15:57:45 -04005413
Nicolas Capensf160b172014-11-26 11:58:23 -05005414 if(target == GL_TEXTURE_2D)
5415 {
5416 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005417
Nicolas Capensf160b172014-11-26 11:58:23 -05005418 if(!texture)
5419 {
5420 return error(GL_INVALID_OPERATION);
5421 }
John Bauman66b8ab22014-05-06 15:57:45 -04005422
Nicolas Capensf160b172014-11-26 11:58:23 -05005423 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
5424 }
5425 else
5426 {
5427 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04005428
Nicolas Capensf160b172014-11-26 11:58:23 -05005429 if(!texture)
5430 {
5431 return error(GL_INVALID_OPERATION);
5432 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005433
Nicolas Capensf160b172014-11-26 11:58:23 -05005434 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
5435 }
5436 }
John Bauman66b8ab22014-05-06 15:57:45 -04005437}
5438
5439void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5440{
Nicolas Capensf160b172014-11-26 11:58:23 -05005441 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005442
Nicolas Capensf160b172014-11-26 11:58:23 -05005443 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005444
Nicolas Capensf160b172014-11-26 11:58:23 -05005445 if(context)
5446 {
5447 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005448
Alexis Hetued306182015-04-02 12:02:28 -04005449 egl::GLint clientVersion = context->getClientVersion();
5450
Nicolas Capensf160b172014-11-26 11:58:23 -05005451 switch(target)
5452 {
5453 case GL_TEXTURE_2D:
5454 texture = context->getTexture2D();
5455 break;
Alexis Hetued306182015-04-02 12:02:28 -04005456 case GL_TEXTURE_2D_ARRAY:
5457 if(clientVersion < 3)
5458 {
5459 return error(GL_INVALID_ENUM);
5460 }
5461 else
5462 {
5463 UNIMPLEMENTED();
5464 texture = context->getTexture3D();
5465 break;
5466 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005467 case GL_TEXTURE_3D_OES:
5468 texture = context->getTexture3D();
5469 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005470 case GL_TEXTURE_CUBE_MAP:
5471 texture = context->getTextureCubeMap();
5472 break;
5473 case GL_TEXTURE_EXTERNAL_OES:
5474 texture = context->getTextureExternal();
5475 break;
5476 default:
5477 return error(GL_INVALID_ENUM);
5478 }
John Bauman66b8ab22014-05-06 15:57:45 -04005479
Nicolas Capensf160b172014-11-26 11:58:23 -05005480 switch(pname)
5481 {
5482 case GL_TEXTURE_WRAP_S:
5483 if(!texture->setWrapS((GLenum)param))
5484 {
5485 return error(GL_INVALID_ENUM);
5486 }
5487 break;
5488 case GL_TEXTURE_WRAP_T:
5489 if(!texture->setWrapT((GLenum)param))
5490 {
5491 return error(GL_INVALID_ENUM);
5492 }
5493 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005494 case GL_TEXTURE_WRAP_R_OES:
5495 if(!texture->setWrapR((GLenum)param))
5496 {
5497 return error(GL_INVALID_ENUM);
5498 }
5499 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005500 case GL_TEXTURE_MIN_FILTER:
5501 if(!texture->setMinFilter((GLenum)param))
5502 {
5503 return error(GL_INVALID_ENUM);
5504 }
5505 break;
5506 case GL_TEXTURE_MAG_FILTER:
5507 if(!texture->setMagFilter((GLenum)param))
5508 {
5509 return error(GL_INVALID_ENUM);
5510 }
5511 break;
5512 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5513 if(!texture->setMaxAnisotropy(param))
5514 {
5515 return error(GL_INVALID_VALUE);
5516 }
5517 break;
Alexis Hetued306182015-04-02 12:02:28 -04005518 case GL_TEXTURE_BASE_LEVEL:
5519 if(clientVersion < 3 || !texture->setBaseLevel((GLint)param))
5520 {
5521 return error(GL_INVALID_VALUE);
5522 }
5523 break;
5524 case GL_TEXTURE_COMPARE_FUNC:
5525 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5526 {
5527 return error(GL_INVALID_VALUE);
5528 }
5529 break;
5530 case GL_TEXTURE_COMPARE_MODE:
5531 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5532 {
5533 return error(GL_INVALID_VALUE);
5534 }
5535 break;
5536 case GL_TEXTURE_IMMUTABLE_FORMAT:
5537 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5538 {
5539 return error(GL_INVALID_VALUE);
5540 }
5541 break;
5542 case GL_TEXTURE_MAX_LEVEL:
5543 if(clientVersion < 3 || !texture->setMaxLevel((GLint)param))
5544 {
5545 return error(GL_INVALID_VALUE);
5546 }
5547 break;
5548 case GL_TEXTURE_MAX_LOD:
5549 if(clientVersion < 3 || !texture->setMaxLOD(param))
5550 {
5551 return error(GL_INVALID_VALUE);
5552 }
5553 break;
5554 case GL_TEXTURE_MIN_LOD:
5555 if(clientVersion < 3 || !texture->setMinLOD(param))
5556 {
5557 return error(GL_INVALID_VALUE);
5558 }
5559 break;
5560 case GL_TEXTURE_SWIZZLE_R:
5561 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5562 {
5563 return error(GL_INVALID_VALUE);
5564 }
5565 break;
5566 case GL_TEXTURE_SWIZZLE_G:
5567 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5568 {
5569 return error(GL_INVALID_VALUE);
5570 }
5571 break;
5572 case GL_TEXTURE_SWIZZLE_B:
5573 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5574 {
5575 return error(GL_INVALID_VALUE);
5576 }
5577 break;
5578 case GL_TEXTURE_SWIZZLE_A:
5579 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5580 {
5581 return error(GL_INVALID_VALUE);
5582 }
5583 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005584 default:
5585 return error(GL_INVALID_ENUM);
5586 }
5587 }
John Bauman66b8ab22014-05-06 15:57:45 -04005588}
5589
5590void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5591{
Nicolas Capensf160b172014-11-26 11:58:23 -05005592 glTexParameterf(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005593}
5594
5595void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
5596{
Nicolas Capensf160b172014-11-26 11:58:23 -05005597 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005598
Nicolas Capensf160b172014-11-26 11:58:23 -05005599 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005600
Nicolas Capensf160b172014-11-26 11:58:23 -05005601 if(context)
5602 {
5603 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005604
Alexis Hetued306182015-04-02 12:02:28 -04005605 egl::GLint clientVersion = context->getClientVersion();
5606
Nicolas Capensf160b172014-11-26 11:58:23 -05005607 switch(target)
5608 {
5609 case GL_TEXTURE_2D:
5610 texture = context->getTexture2D();
5611 break;
Alexis Hetued306182015-04-02 12:02:28 -04005612 case GL_TEXTURE_2D_ARRAY:
5613 if(clientVersion < 3)
5614 {
5615 return error(GL_INVALID_ENUM);
5616 }
5617 else
5618 {
5619 UNIMPLEMENTED();
5620 texture = context->getTexture3D();
5621 break;
5622 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005623 case GL_TEXTURE_3D_OES:
5624 texture = context->getTexture3D();
5625 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005626 case GL_TEXTURE_CUBE_MAP:
5627 texture = context->getTextureCubeMap();
5628 break;
5629 case GL_TEXTURE_EXTERNAL_OES:
Alexis Hetuf7be67f2015-02-11 16:11:07 -05005630 texture = context->getTextureExternal();
5631 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005632 default:
5633 return error(GL_INVALID_ENUM);
5634 }
John Bauman66b8ab22014-05-06 15:57:45 -04005635
Nicolas Capensf160b172014-11-26 11:58:23 -05005636 switch(pname)
5637 {
5638 case GL_TEXTURE_WRAP_S:
5639 if(!texture->setWrapS((GLenum)param))
5640 {
5641 return error(GL_INVALID_ENUM);
5642 }
5643 break;
5644 case GL_TEXTURE_WRAP_T:
5645 if(!texture->setWrapT((GLenum)param))
5646 {
5647 return error(GL_INVALID_ENUM);
5648 }
5649 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005650 case GL_TEXTURE_WRAP_R_OES:
5651 if(!texture->setWrapR((GLenum)param))
5652 {
5653 return error(GL_INVALID_ENUM);
5654 }
5655 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005656 case GL_TEXTURE_MIN_FILTER:
5657 if(!texture->setMinFilter((GLenum)param))
5658 {
5659 return error(GL_INVALID_ENUM);
5660 }
5661 break;
5662 case GL_TEXTURE_MAG_FILTER:
5663 if(!texture->setMagFilter((GLenum)param))
5664 {
5665 return error(GL_INVALID_ENUM);
5666 }
5667 break;
5668 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5669 if(!texture->setMaxAnisotropy((GLfloat)param))
5670 {
5671 return error(GL_INVALID_VALUE);
5672 }
5673 break;
Alexis Hetued306182015-04-02 12:02:28 -04005674 case GL_TEXTURE_BASE_LEVEL:
5675 if(clientVersion < 3 || !texture->setBaseLevel(param))
5676 {
5677 return error(GL_INVALID_VALUE);
5678 }
5679 break;
5680 case GL_TEXTURE_COMPARE_FUNC:
5681 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5682 {
5683 return error(GL_INVALID_VALUE);
5684 }
5685 break;
5686 case GL_TEXTURE_COMPARE_MODE:
5687 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5688 {
5689 return error(GL_INVALID_VALUE);
5690 }
5691 case GL_TEXTURE_IMMUTABLE_FORMAT:
5692 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5693 {
5694 return error(GL_INVALID_VALUE);
5695 }
5696 break;
5697 case GL_TEXTURE_MAX_LEVEL:
5698 if(clientVersion < 3 || !texture->setMaxLevel(param))
5699 {
5700 return error(GL_INVALID_VALUE);
5701 }
5702 break;
5703 case GL_TEXTURE_MAX_LOD:
5704 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5705 {
5706 return error(GL_INVALID_VALUE);
5707 }
5708 break;
5709 case GL_TEXTURE_MIN_LOD:
5710 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5711 {
5712 return error(GL_INVALID_VALUE);
5713 }
5714 break;
5715 case GL_TEXTURE_SWIZZLE_R:
5716 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5717 {
5718 return error(GL_INVALID_VALUE);
5719 }
5720 break;
5721 case GL_TEXTURE_SWIZZLE_G:
5722 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5723 {
5724 return error(GL_INVALID_VALUE);
5725 }
5726 break;
5727 case GL_TEXTURE_SWIZZLE_B:
5728 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5729 {
5730 return error(GL_INVALID_VALUE);
5731 }
5732 break;
5733 case GL_TEXTURE_SWIZZLE_A:
5734 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5735 {
5736 return error(GL_INVALID_VALUE);
5737 }
5738 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005739 default:
5740 return error(GL_INVALID_ENUM);
5741 }
5742 }
John Bauman66b8ab22014-05-06 15:57:45 -04005743}
5744
5745void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5746{
Nicolas Capensf160b172014-11-26 11:58:23 -05005747 glTexParameteri(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005748}
5749
5750void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05005751 GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04005752{
Nicolas Capensf160b172014-11-26 11:58:23 -05005753 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5754 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07005755 "const GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05005756 target, level, xoffset, yoffset, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04005757
Nicolas Capensf160b172014-11-26 11:58:23 -05005758 if(!es2::IsTextureTarget(target))
5759 {
5760 return error(GL_INVALID_ENUM);
5761 }
John Bauman66b8ab22014-05-06 15:57:45 -04005762
Nicolas Capensf160b172014-11-26 11:58:23 -05005763 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5764 {
5765 return error(GL_INVALID_VALUE);
5766 }
John Bauman66b8ab22014-05-06 15:57:45 -04005767
Nicolas Capensf160b172014-11-26 11:58:23 -05005768 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5769 {
5770 return error(GL_INVALID_VALUE);
5771 }
John Bauman66b8ab22014-05-06 15:57:45 -04005772
Nicolas Capensf160b172014-11-26 11:58:23 -05005773 if(!es2::CheckTextureFormatType(format, type))
5774 {
5775 return error(GL_INVALID_ENUM);
5776 }
John Bauman66b8ab22014-05-06 15:57:45 -04005777
Nicolas Capensf160b172014-11-26 11:58:23 -05005778 if(width == 0 || height == 0 || pixels == NULL)
5779 {
5780 return;
5781 }
John Bauman66b8ab22014-05-06 15:57:45 -04005782
Nicolas Capensf160b172014-11-26 11:58:23 -05005783 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005784
Nicolas Capensf160b172014-11-26 11:58:23 -05005785 if(context)
5786 {
Alexis Hetub027aa92015-01-19 15:56:12 -05005787 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05005788 {
5789 return error(GL_INVALID_VALUE);
5790 }
John Bauman66b8ab22014-05-06 15:57:45 -04005791
Nicolas Capensf160b172014-11-26 11:58:23 -05005792 if(target == GL_TEXTURE_2D)
5793 {
5794 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005795
Nicolas Capensf160b172014-11-26 11:58:23 -05005796 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5797 {
5798 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5799 }
5800 }
5801 else if(es2::IsCubemapTextureTarget(target))
5802 {
5803 es2::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens08e90f02014-11-21 12:49:12 -05005804
Nicolas Capensf160b172014-11-26 11:58:23 -05005805 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5806 {
5807 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5808 }
5809 }
5810 else
5811 {
5812 UNREACHABLE();
5813 }
5814 }
John Bauman66b8ab22014-05-06 15:57:45 -04005815}
5816
5817void GL_APIENTRY glUniform1f(GLint location, GLfloat x)
5818{
Nicolas Capensf160b172014-11-26 11:58:23 -05005819 glUniform1fv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005820}
5821
5822void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5823{
Nicolas Capens4be33702015-04-28 15:13:30 -07005824 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005825
Nicolas Capensf160b172014-11-26 11:58:23 -05005826 if(count < 0)
5827 {
5828 return error(GL_INVALID_VALUE);
5829 }
John Bauman66b8ab22014-05-06 15:57:45 -04005830
Nicolas Capensf160b172014-11-26 11:58:23 -05005831 if(location == -1)
5832 {
5833 return;
5834 }
John Bauman66b8ab22014-05-06 15:57:45 -04005835
Nicolas Capensf160b172014-11-26 11:58:23 -05005836 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005837
Nicolas Capensf160b172014-11-26 11:58:23 -05005838 if(context)
5839 {
5840 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005841
Nicolas Capensf160b172014-11-26 11:58:23 -05005842 if(!program)
5843 {
5844 return error(GL_INVALID_OPERATION);
5845 }
John Bauman66b8ab22014-05-06 15:57:45 -04005846
Nicolas Capensf160b172014-11-26 11:58:23 -05005847 if(!program->setUniform1fv(location, count, v))
5848 {
5849 return error(GL_INVALID_OPERATION);
5850 }
5851 }
John Bauman66b8ab22014-05-06 15:57:45 -04005852}
5853
5854void GL_APIENTRY glUniform1i(GLint location, GLint x)
5855{
Nicolas Capensf160b172014-11-26 11:58:23 -05005856 glUniform1iv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005857}
5858
5859void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
5860{
Nicolas Capens4be33702015-04-28 15:13:30 -07005861 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005862
Nicolas Capensf160b172014-11-26 11:58:23 -05005863 if(count < 0)
5864 {
5865 return error(GL_INVALID_VALUE);
5866 }
John Bauman66b8ab22014-05-06 15:57:45 -04005867
Nicolas Capensf160b172014-11-26 11:58:23 -05005868 if(location == -1)
5869 {
5870 return;
5871 }
John Bauman66b8ab22014-05-06 15:57:45 -04005872
Nicolas Capensf160b172014-11-26 11:58:23 -05005873 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005874
Nicolas Capensf160b172014-11-26 11:58:23 -05005875 if(context)
5876 {
5877 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005878
Nicolas Capensf160b172014-11-26 11:58:23 -05005879 if(!program)
5880 {
5881 return error(GL_INVALID_OPERATION);
5882 }
John Bauman66b8ab22014-05-06 15:57:45 -04005883
Nicolas Capensf160b172014-11-26 11:58:23 -05005884 if(!program->setUniform1iv(location, count, v))
5885 {
5886 return error(GL_INVALID_OPERATION);
5887 }
5888 }
John Bauman66b8ab22014-05-06 15:57:45 -04005889}
5890
5891void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
5892{
Nicolas Capensf160b172014-11-26 11:58:23 -05005893 GLfloat xy[2] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005894
Nicolas Capensf160b172014-11-26 11:58:23 -05005895 glUniform2fv(location, 1, (GLfloat*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005896}
5897
5898void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5899{
Nicolas Capens4be33702015-04-28 15:13:30 -07005900 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005901
Nicolas Capensf160b172014-11-26 11:58:23 -05005902 if(count < 0)
5903 {
5904 return error(GL_INVALID_VALUE);
5905 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005906
Nicolas Capensf160b172014-11-26 11:58:23 -05005907 if(location == -1)
5908 {
5909 return;
5910 }
John Bauman66b8ab22014-05-06 15:57:45 -04005911
Nicolas Capensf160b172014-11-26 11:58:23 -05005912 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005913
Nicolas Capensf160b172014-11-26 11:58:23 -05005914 if(context)
5915 {
5916 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005917
Nicolas Capensf160b172014-11-26 11:58:23 -05005918 if(!program)
5919 {
5920 return error(GL_INVALID_OPERATION);
5921 }
John Bauman66b8ab22014-05-06 15:57:45 -04005922
Nicolas Capensf160b172014-11-26 11:58:23 -05005923 if(!program->setUniform2fv(location, count, v))
5924 {
5925 return error(GL_INVALID_OPERATION);
5926 }
5927 }
John Bauman66b8ab22014-05-06 15:57:45 -04005928}
5929
5930void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)
5931{
Nicolas Capensf160b172014-11-26 11:58:23 -05005932 GLint xy[4] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005933
Nicolas Capensf160b172014-11-26 11:58:23 -05005934 glUniform2iv(location, 1, (GLint*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005935}
5936
5937void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
5938{
Nicolas Capens4be33702015-04-28 15:13:30 -07005939 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005940
Nicolas Capensf160b172014-11-26 11:58:23 -05005941 if(count < 0)
5942 {
5943 return error(GL_INVALID_VALUE);
5944 }
John Bauman66b8ab22014-05-06 15:57:45 -04005945
Nicolas Capensf160b172014-11-26 11:58:23 -05005946 if(location == -1)
5947 {
5948 return;
5949 }
John Bauman66b8ab22014-05-06 15:57:45 -04005950
Nicolas Capensf160b172014-11-26 11:58:23 -05005951 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005952
Nicolas Capensf160b172014-11-26 11:58:23 -05005953 if(context)
5954 {
5955 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005956
Nicolas Capensf160b172014-11-26 11:58:23 -05005957 if(!program)
5958 {
5959 return error(GL_INVALID_OPERATION);
5960 }
John Bauman66b8ab22014-05-06 15:57:45 -04005961
Nicolas Capensf160b172014-11-26 11:58:23 -05005962 if(!program->setUniform2iv(location, count, v))
5963 {
5964 return error(GL_INVALID_OPERATION);
5965 }
5966 }
John Bauman66b8ab22014-05-06 15:57:45 -04005967}
5968
5969void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5970{
Nicolas Capensf160b172014-11-26 11:58:23 -05005971 GLfloat xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04005972
Nicolas Capensf160b172014-11-26 11:58:23 -05005973 glUniform3fv(location, 1, (GLfloat*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04005974}
5975
5976void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5977{
Nicolas Capens4be33702015-04-28 15:13:30 -07005978 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005979
Nicolas Capensf160b172014-11-26 11:58:23 -05005980 if(count < 0)
5981 {
5982 return error(GL_INVALID_VALUE);
5983 }
John Bauman66b8ab22014-05-06 15:57:45 -04005984
Nicolas Capensf160b172014-11-26 11:58:23 -05005985 if(location == -1)
5986 {
5987 return;
5988 }
John Bauman66b8ab22014-05-06 15:57:45 -04005989
Nicolas Capensf160b172014-11-26 11:58:23 -05005990 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005991
Nicolas Capensf160b172014-11-26 11:58:23 -05005992 if(context)
5993 {
5994 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005995
Nicolas Capensf160b172014-11-26 11:58:23 -05005996 if(!program)
5997 {
5998 return error(GL_INVALID_OPERATION);
5999 }
John Bauman66b8ab22014-05-06 15:57:45 -04006000
Nicolas Capensf160b172014-11-26 11:58:23 -05006001 if(!program->setUniform3fv(location, count, v))
6002 {
6003 return error(GL_INVALID_OPERATION);
6004 }
6005 }
John Bauman66b8ab22014-05-06 15:57:45 -04006006}
6007
6008void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
6009{
Nicolas Capensf160b172014-11-26 11:58:23 -05006010 GLint xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04006011
Nicolas Capensf160b172014-11-26 11:58:23 -05006012 glUniform3iv(location, 1, (GLint*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04006013}
6014
6015void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
6016{
Nicolas Capens4be33702015-04-28 15:13:30 -07006017 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006018
Nicolas Capensf160b172014-11-26 11:58:23 -05006019 if(count < 0)
6020 {
6021 return error(GL_INVALID_VALUE);
6022 }
John Bauman66b8ab22014-05-06 15:57:45 -04006023
Nicolas Capensf160b172014-11-26 11:58:23 -05006024 if(location == -1)
6025 {
6026 return;
6027 }
John Bauman66b8ab22014-05-06 15:57:45 -04006028
Nicolas Capensf160b172014-11-26 11:58:23 -05006029 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006030
Nicolas Capensf160b172014-11-26 11:58:23 -05006031 if(context)
6032 {
6033 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006034
Nicolas Capensf160b172014-11-26 11:58:23 -05006035 if(!program)
6036 {
6037 return error(GL_INVALID_OPERATION);
6038 }
John Bauman66b8ab22014-05-06 15:57:45 -04006039
Nicolas Capensf160b172014-11-26 11:58:23 -05006040 if(!program->setUniform3iv(location, count, v))
6041 {
6042 return error(GL_INVALID_OPERATION);
6043 }
6044 }
John Bauman66b8ab22014-05-06 15:57:45 -04006045}
6046
6047void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6048{
Nicolas Capensf160b172014-11-26 11:58:23 -05006049 GLfloat xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04006050
Nicolas Capensf160b172014-11-26 11:58:23 -05006051 glUniform4fv(location, 1, (GLfloat*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04006052}
6053
6054void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
6055{
Nicolas Capens4be33702015-04-28 15:13:30 -07006056 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006057
Nicolas Capensf160b172014-11-26 11:58:23 -05006058 if(count < 0)
6059 {
6060 return error(GL_INVALID_VALUE);
6061 }
John Bauman66b8ab22014-05-06 15:57:45 -04006062
Nicolas Capensf160b172014-11-26 11:58:23 -05006063 if(location == -1)
6064 {
6065 return;
6066 }
John Bauman66b8ab22014-05-06 15:57:45 -04006067
Nicolas Capensf160b172014-11-26 11:58:23 -05006068 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006069
Nicolas Capensf160b172014-11-26 11:58:23 -05006070 if(context)
6071 {
6072 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006073
Nicolas Capensf160b172014-11-26 11:58:23 -05006074 if(!program)
6075 {
6076 return error(GL_INVALID_OPERATION);
6077 }
John Bauman66b8ab22014-05-06 15:57:45 -04006078
Nicolas Capensf160b172014-11-26 11:58:23 -05006079 if(!program->setUniform4fv(location, count, v))
6080 {
6081 return error(GL_INVALID_OPERATION);
6082 }
6083 }
John Bauman66b8ab22014-05-06 15:57:45 -04006084}
6085
6086void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
6087{
Nicolas Capensf160b172014-11-26 11:58:23 -05006088 GLint xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04006089
Nicolas Capensf160b172014-11-26 11:58:23 -05006090 glUniform4iv(location, 1, (GLint*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04006091}
6092
6093void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
6094{
Nicolas Capens4be33702015-04-28 15:13:30 -07006095 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006096
Nicolas Capensf160b172014-11-26 11:58:23 -05006097 if(count < 0)
6098 {
6099 return error(GL_INVALID_VALUE);
6100 }
John Bauman66b8ab22014-05-06 15:57:45 -04006101
Nicolas Capensf160b172014-11-26 11:58:23 -05006102 if(location == -1)
6103 {
6104 return;
6105 }
John Bauman66b8ab22014-05-06 15:57:45 -04006106
Nicolas Capensf160b172014-11-26 11:58:23 -05006107 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006108
Nicolas Capensf160b172014-11-26 11:58:23 -05006109 if(context)
6110 {
6111 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006112
Nicolas Capensf160b172014-11-26 11:58:23 -05006113 if(!program)
6114 {
6115 return error(GL_INVALID_OPERATION);
6116 }
John Bauman66b8ab22014-05-06 15:57:45 -04006117
Nicolas Capensf160b172014-11-26 11:58:23 -05006118 if(!program->setUniform4iv(location, count, v))
6119 {
6120 return error(GL_INVALID_OPERATION);
6121 }
6122 }
John Bauman66b8ab22014-05-06 15:57:45 -04006123}
6124
6125void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6126{
Nicolas Capens4be33702015-04-28 15:13:30 -07006127 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006128 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006129
Nicolas Capensf160b172014-11-26 11:58:23 -05006130 if(count < 0 || transpose != GL_FALSE)
6131 {
6132 return error(GL_INVALID_VALUE);
6133 }
John Bauman66b8ab22014-05-06 15:57:45 -04006134
Nicolas Capensf160b172014-11-26 11:58:23 -05006135 if(location == -1)
6136 {
6137 return;
6138 }
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 *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006145
Nicolas Capensf160b172014-11-26 11:58:23 -05006146 if(!program)
6147 {
6148 return error(GL_INVALID_OPERATION);
6149 }
John Bauman66b8ab22014-05-06 15:57:45 -04006150
Nicolas Capensf160b172014-11-26 11:58:23 -05006151 if(!program->setUniformMatrix2fv(location, count, value))
6152 {
6153 return error(GL_INVALID_OPERATION);
6154 }
6155 }
John Bauman66b8ab22014-05-06 15:57:45 -04006156}
6157
6158void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6159{
Nicolas Capens4be33702015-04-28 15:13:30 -07006160 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006161 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006162
Nicolas Capensf160b172014-11-26 11:58:23 -05006163 if(count < 0 || transpose != GL_FALSE)
6164 {
6165 return error(GL_INVALID_VALUE);
6166 }
John Bauman66b8ab22014-05-06 15:57:45 -04006167
Nicolas Capensf160b172014-11-26 11:58:23 -05006168 if(location == -1)
6169 {
6170 return;
6171 }
John Bauman66b8ab22014-05-06 15:57:45 -04006172
Nicolas Capensf160b172014-11-26 11:58:23 -05006173 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006174
Nicolas Capensf160b172014-11-26 11:58:23 -05006175 if(context)
6176 {
6177 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006178
Nicolas Capensf160b172014-11-26 11:58:23 -05006179 if(!program)
6180 {
6181 return error(GL_INVALID_OPERATION);
6182 }
John Bauman66b8ab22014-05-06 15:57:45 -04006183
Nicolas Capensf160b172014-11-26 11:58:23 -05006184 if(!program->setUniformMatrix3fv(location, count, value))
6185 {
6186 return error(GL_INVALID_OPERATION);
6187 }
6188 }
John Bauman66b8ab22014-05-06 15:57:45 -04006189}
6190
6191void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6192{
Nicolas Capens4be33702015-04-28 15:13:30 -07006193 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006194 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006195
Nicolas Capensf160b172014-11-26 11:58:23 -05006196 if(count < 0 || transpose != GL_FALSE)
6197 {
6198 return error(GL_INVALID_VALUE);
6199 }
John Bauman66b8ab22014-05-06 15:57:45 -04006200
Nicolas Capensf160b172014-11-26 11:58:23 -05006201 if(location == -1)
6202 {
6203 return;
6204 }
John Bauman66b8ab22014-05-06 15:57:45 -04006205
Nicolas Capensf160b172014-11-26 11:58:23 -05006206 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006207
Nicolas Capensf160b172014-11-26 11:58:23 -05006208 if(context)
6209 {
6210 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006211
Nicolas Capensf160b172014-11-26 11:58:23 -05006212 if(!program)
6213 {
6214 return error(GL_INVALID_OPERATION);
6215 }
John Bauman66b8ab22014-05-06 15:57:45 -04006216
Nicolas Capensf160b172014-11-26 11:58:23 -05006217 if(!program->setUniformMatrix4fv(location, count, value))
6218 {
6219 return error(GL_INVALID_OPERATION);
6220 }
6221 }
John Bauman66b8ab22014-05-06 15:57:45 -04006222}
6223
6224void GL_APIENTRY glUseProgram(GLuint program)
6225{
Nicolas Capensf160b172014-11-26 11:58:23 -05006226 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006227
Nicolas Capensf160b172014-11-26 11:58:23 -05006228 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006229
Nicolas Capensf160b172014-11-26 11:58:23 -05006230 if(context)
6231 {
6232 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006233
Nicolas Capensf160b172014-11-26 11:58:23 -05006234 if(!programObject && program != 0)
6235 {
6236 if(context->getShader(program))
6237 {
6238 return error(GL_INVALID_OPERATION);
6239 }
6240 else
6241 {
6242 return error(GL_INVALID_VALUE);
6243 }
6244 }
John Bauman66b8ab22014-05-06 15:57:45 -04006245
Nicolas Capensf160b172014-11-26 11:58:23 -05006246 if(program != 0 && !programObject->isLinked())
6247 {
6248 return error(GL_INVALID_OPERATION);
6249 }
John Bauman66b8ab22014-05-06 15:57:45 -04006250
Nicolas Capensf160b172014-11-26 11:58:23 -05006251 context->useProgram(program);
6252 }
John Bauman66b8ab22014-05-06 15:57:45 -04006253}
6254
6255void GL_APIENTRY glValidateProgram(GLuint program)
6256{
Nicolas Capensf160b172014-11-26 11:58:23 -05006257 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006258
Nicolas Capensf160b172014-11-26 11:58:23 -05006259 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006260
Nicolas Capensf160b172014-11-26 11:58:23 -05006261 if(context)
6262 {
6263 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006264
Nicolas Capensf160b172014-11-26 11:58:23 -05006265 if(!programObject)
6266 {
6267 if(context->getShader(program))
6268 {
6269 return error(GL_INVALID_OPERATION);
6270 }
6271 else
6272 {
6273 return error(GL_INVALID_VALUE);
6274 }
6275 }
John Bauman66b8ab22014-05-06 15:57:45 -04006276
Nicolas Capensf160b172014-11-26 11:58:23 -05006277 programObject->validate();
6278 }
John Bauman66b8ab22014-05-06 15:57:45 -04006279}
6280
6281void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
6282{
Nicolas Capensf160b172014-11-26 11:58:23 -05006283 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
John Bauman66b8ab22014-05-06 15:57:45 -04006284
Nicolas Capensf160b172014-11-26 11:58:23 -05006285 if(index >= es2::MAX_VERTEX_ATTRIBS)
6286 {
6287 return error(GL_INVALID_VALUE);
6288 }
John Bauman66b8ab22014-05-06 15:57:45 -04006289
Nicolas Capensf160b172014-11-26 11:58:23 -05006290 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006291
Nicolas Capensf160b172014-11-26 11:58:23 -05006292 if(context)
6293 {
6294 GLfloat vals[4] = { x, 0, 0, 1 };
6295 context->setVertexAttrib(index, vals);
6296 }
John Bauman66b8ab22014-05-06 15:57:45 -04006297}
6298
6299void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
6300{
Nicolas Capens4be33702015-04-28 15:13:30 -07006301 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006302
Nicolas Capensf160b172014-11-26 11:58:23 -05006303 if(index >= es2::MAX_VERTEX_ATTRIBS)
6304 {
6305 return error(GL_INVALID_VALUE);
6306 }
John Bauman66b8ab22014-05-06 15:57:45 -04006307
Nicolas Capensf160b172014-11-26 11:58:23 -05006308 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006309
Nicolas Capensf160b172014-11-26 11:58:23 -05006310 if(context)
6311 {
6312 GLfloat vals[4] = { values[0], 0, 0, 1 };
6313 context->setVertexAttrib(index, vals);
6314 }
John Bauman66b8ab22014-05-06 15:57:45 -04006315}
6316
6317void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6318{
Nicolas Capensf160b172014-11-26 11:58:23 -05006319 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
John Bauman66b8ab22014-05-06 15:57:45 -04006320
Nicolas Capensf160b172014-11-26 11:58:23 -05006321 if(index >= es2::MAX_VERTEX_ATTRIBS)
6322 {
6323 return error(GL_INVALID_VALUE);
6324 }
John Bauman66b8ab22014-05-06 15:57:45 -04006325
Nicolas Capensf160b172014-11-26 11:58:23 -05006326 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006327
Nicolas Capensf160b172014-11-26 11:58:23 -05006328 if(context)
6329 {
6330 GLfloat vals[4] = { x, y, 0, 1 };
6331 context->setVertexAttrib(index, vals);
6332 }
John Bauman66b8ab22014-05-06 15:57:45 -04006333}
6334
6335void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
6336{
Nicolas Capens4be33702015-04-28 15:13:30 -07006337 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006338
Nicolas Capensf160b172014-11-26 11:58:23 -05006339 if(index >= es2::MAX_VERTEX_ATTRIBS)
6340 {
6341 return error(GL_INVALID_VALUE);
6342 }
John Bauman66b8ab22014-05-06 15:57:45 -04006343
Nicolas Capensf160b172014-11-26 11:58:23 -05006344 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006345
Nicolas Capensf160b172014-11-26 11:58:23 -05006346 if(context)
6347 {
6348 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6349 context->setVertexAttrib(index, vals);
6350 }
John Bauman66b8ab22014-05-06 15:57:45 -04006351}
6352
6353void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6354{
Nicolas Capensf160b172014-11-26 11:58:23 -05006355 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
John Bauman66b8ab22014-05-06 15:57:45 -04006356
Nicolas Capensf160b172014-11-26 11:58:23 -05006357 if(index >= es2::MAX_VERTEX_ATTRIBS)
6358 {
6359 return error(GL_INVALID_VALUE);
6360 }
John Bauman66b8ab22014-05-06 15:57:45 -04006361
Nicolas Capensf160b172014-11-26 11:58:23 -05006362 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006363
Nicolas Capensf160b172014-11-26 11:58:23 -05006364 if(context)
6365 {
6366 GLfloat vals[4] = { x, y, z, 1 };
6367 context->setVertexAttrib(index, vals);
6368 }
John Bauman66b8ab22014-05-06 15:57:45 -04006369}
6370
6371void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
6372{
Nicolas Capens4be33702015-04-28 15:13:30 -07006373 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006374
Nicolas Capensf160b172014-11-26 11:58:23 -05006375 if(index >= es2::MAX_VERTEX_ATTRIBS)
6376 {
6377 return error(GL_INVALID_VALUE);
6378 }
John Bauman66b8ab22014-05-06 15:57:45 -04006379
Nicolas Capensf160b172014-11-26 11:58:23 -05006380 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006381
Nicolas Capensf160b172014-11-26 11:58:23 -05006382 if(context)
6383 {
6384 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6385 context->setVertexAttrib(index, vals);
6386 }
John Bauman66b8ab22014-05-06 15:57:45 -04006387}
6388
6389void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6390{
Nicolas Capensf160b172014-11-26 11:58:23 -05006391 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 -04006392
Nicolas Capensf160b172014-11-26 11:58:23 -05006393 if(index >= es2::MAX_VERTEX_ATTRIBS)
6394 {
6395 return error(GL_INVALID_VALUE);
6396 }
John Bauman66b8ab22014-05-06 15:57:45 -04006397
Nicolas Capensf160b172014-11-26 11:58:23 -05006398 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006399
Nicolas Capensf160b172014-11-26 11:58:23 -05006400 if(context)
6401 {
6402 GLfloat vals[4] = { x, y, z, w };
6403 context->setVertexAttrib(index, vals);
6404 }
John Bauman66b8ab22014-05-06 15:57:45 -04006405}
6406
6407void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
6408{
Nicolas Capens4be33702015-04-28 15:13:30 -07006409 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006410
Nicolas Capensf160b172014-11-26 11:58:23 -05006411 if(index >= es2::MAX_VERTEX_ATTRIBS)
6412 {
6413 return error(GL_INVALID_VALUE);
6414 }
John Bauman66b8ab22014-05-06 15:57:45 -04006415
Nicolas Capensf160b172014-11-26 11:58:23 -05006416 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006417
Nicolas Capensf160b172014-11-26 11:58:23 -05006418 if(context)
6419 {
6420 context->setVertexAttrib(index, values);
6421 }
John Bauman66b8ab22014-05-06 15:57:45 -04006422}
6423
6424void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
6425{
Nicolas Capensf160b172014-11-26 11:58:23 -05006426 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006427 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006428 index, size, type, normalized, stride, ptr);
John Bauman66b8ab22014-05-06 15:57:45 -04006429
Nicolas Capensf160b172014-11-26 11:58:23 -05006430 if(index >= es2::MAX_VERTEX_ATTRIBS)
6431 {
6432 return error(GL_INVALID_VALUE);
6433 }
John Bauman66b8ab22014-05-06 15:57:45 -04006434
Nicolas Capensf160b172014-11-26 11:58:23 -05006435 if(size < 1 || size > 4)
6436 {
6437 return error(GL_INVALID_VALUE);
6438 }
John Bauman66b8ab22014-05-06 15:57:45 -04006439
Alexis Hetued306182015-04-02 12:02:28 -04006440 egl::GLint clientVersion = egl::getClientVersion();
6441
Nicolas Capensf160b172014-11-26 11:58:23 -05006442 switch(type)
6443 {
6444 case GL_BYTE:
6445 case GL_UNSIGNED_BYTE:
6446 case GL_SHORT:
6447 case GL_UNSIGNED_SHORT:
6448 case GL_FIXED:
6449 case GL_FLOAT:
6450 break;
Alexis Hetued306182015-04-02 12:02:28 -04006451 case GL_INT_2_10_10_10_REV:
6452 case GL_UNSIGNED_INT_2_10_10_10_REV:
6453 if(clientVersion >= 3)
6454 {
6455 if(size != 4)
6456 {
6457 return error(GL_INVALID_OPERATION);
6458 }
6459 break;
6460 }
6461 else return error(GL_INVALID_ENUM);
6462 case GL_INT:
6463 case GL_UNSIGNED_INT:
6464 case GL_HALF_FLOAT:
6465 if(clientVersion >= 3)
6466 {
6467 break;
6468 }
6469 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05006470 default:
6471 return error(GL_INVALID_ENUM);
6472 }
John Bauman66b8ab22014-05-06 15:57:45 -04006473
Nicolas Capensf160b172014-11-26 11:58:23 -05006474 if(stride < 0)
6475 {
6476 return error(GL_INVALID_VALUE);
6477 }
John Bauman66b8ab22014-05-06 15:57:45 -04006478
Nicolas Capensf160b172014-11-26 11:58:23 -05006479 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006480
Nicolas Capensf160b172014-11-26 11:58:23 -05006481 if(context)
6482 {
6483 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6484 }
John Bauman66b8ab22014-05-06 15:57:45 -04006485}
6486
6487void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6488{
Nicolas Capensf160b172014-11-26 11:58:23 -05006489 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04006490
Nicolas Capensf160b172014-11-26 11:58:23 -05006491 if(width < 0 || height < 0)
6492 {
6493 return error(GL_INVALID_VALUE);
6494 }
John Bauman66b8ab22014-05-06 15:57:45 -04006495
Nicolas Capensf160b172014-11-26 11:58:23 -05006496 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006497
Nicolas Capensf160b172014-11-26 11:58:23 -05006498 if(context)
6499 {
6500 context->setViewportParams(x, y, width, height);
6501 }
John Bauman66b8ab22014-05-06 15:57:45 -04006502}
6503
Alexis Hetue9233fb2015-02-11 10:31:58 -05006504void 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 -04006505{
Nicolas Capensf160b172014-11-26 11:58:23 -05006506 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6507 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6508 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6509 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
John Bauman66b8ab22014-05-06 15:57:45 -04006510
Nicolas Capensf160b172014-11-26 11:58:23 -05006511 switch(filter)
6512 {
6513 case GL_NEAREST:
6514 break;
6515 default:
6516 return error(GL_INVALID_ENUM);
6517 }
John Bauman66b8ab22014-05-06 15:57:45 -04006518
Nicolas Capensf160b172014-11-26 11:58:23 -05006519 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6520 {
6521 return error(GL_INVALID_VALUE);
6522 }
John Bauman66b8ab22014-05-06 15:57:45 -04006523
Nicolas Capensf160b172014-11-26 11:58:23 -05006524 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006525
Nicolas Capensf160b172014-11-26 11:58:23 -05006526 if(context)
6527 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006528 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capensf160b172014-11-26 11:58:23 -05006529 {
6530 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6531 return error(GL_INVALID_OPERATION);
6532 }
John Bauman66b8ab22014-05-06 15:57:45 -04006533
Nicolas Capensf160b172014-11-26 11:58:23 -05006534 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6535 }
John Bauman66b8ab22014-05-06 15:57:45 -04006536}
6537
Alexis Hetue9233fb2015-02-11 10:31:58 -05006538void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6539 GLbitfield mask, GLenum filter)
6540{
6541 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6542 {
6543 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6544 return error(GL_INVALID_OPERATION);
6545 }
6546
6547 glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6548}
6549
John Bauman66b8ab22014-05-06 15:57:45 -04006550void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Nicolas Capensf160b172014-11-26 11:58:23 -05006551 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04006552{
Nicolas Capensf160b172014-11-26 11:58:23 -05006553 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6554 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006555 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006556 target, level, internalformat, width, height, depth, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04006557
Alexis Hetub027aa92015-01-19 15:56:12 -05006558 switch(target)
6559 {
6560 case GL_TEXTURE_3D_OES:
6561 switch(format)
6562 {
6563 case GL_DEPTH_COMPONENT:
6564 case GL_DEPTH_STENCIL_OES:
6565 return error(GL_INVALID_OPERATION);
6566 default:
6567 break;
6568 }
6569 break;
6570 default:
6571 return error(GL_INVALID_ENUM);
6572 }
6573
6574 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6575 {
6576 return error(GL_INVALID_ENUM);
6577 }
6578
6579 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6580 {
6581 return error(GL_INVALID_VALUE);
6582 }
6583
6584 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6585 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6586 {
6587 return error(GL_INVALID_VALUE);
6588 }
6589
6590 if(border != 0)
6591 {
6592 return error(GL_INVALID_VALUE);
6593 }
6594
6595 if(!ValidateInternalFormat3D(internalformat, format, type))
6596 {
6597 return error(GL_INVALID_OPERATION);
6598 }
6599
6600 es2::Context *context = es2::getContext();
6601
6602 if(context)
6603 {
6604 es2::Texture3D *texture = context->getTexture3D();
6605
6606 if(!texture)
6607 {
6608 return error(GL_INVALID_OPERATION);
6609 }
6610
6611 texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackAlignment(), pixels);
6612 }
John Bauman66b8ab22014-05-06 15:57:45 -04006613}
6614
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006615void 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)
6616{
Alexis Hetub027aa92015-01-19 15:56:12 -05006617 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6618 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006619 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006620 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
6621
Alexis Hetub027aa92015-01-19 15:56:12 -05006622 switch(target)
6623 {
6624 case GL_TEXTURE_3D_OES:
6625 break;
6626 default:
6627 return error(GL_INVALID_ENUM);
6628 }
6629
6630 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6631 {
6632 return error(GL_INVALID_ENUM);
6633 }
6634
6635 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6636 {
6637 return error(GL_INVALID_VALUE);
6638 }
6639
6640 if((width < 0) || (height < 0) || (depth < 0))
6641 {
6642 return error(GL_INVALID_VALUE);
6643 }
6644
6645 es2::Context *context = es2::getContext();
6646
6647 if(context)
6648 {
6649 es2::Texture3D *texture = context->getTexture3D();
6650
6651 if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))
6652 {
6653 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackAlignment(), pixels);
6654 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006655 }
6656}
6657
6658void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
6659{
Alexis Hetub027aa92015-01-19 15:56:12 -05006660 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6661 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006662 target, level, xoffset, yoffset, zoffset, x, y, width, height);
6663
Alexis Hetub027aa92015-01-19 15:56:12 -05006664 switch(target)
6665 {
6666 case GL_TEXTURE_3D_OES:
6667 break;
6668 default:
6669 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006670 }
6671
Alexis Hetub027aa92015-01-19 15:56:12 -05006672 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6673 {
6674 return error(GL_INVALID_VALUE);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006675 }
6676
Alexis Hetub027aa92015-01-19 15:56:12 -05006677 es2::Context *context = es2::getContext();
6678
6679 if(context)
6680 {
6681 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6682
6683 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
6684 {
6685 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6686 }
6687
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006688 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Alexis Hetub027aa92015-01-19 15:56:12 -05006689 {
6690 return error(GL_INVALID_OPERATION);
6691 }
6692
6693 es2::Renderbuffer *source = framebuffer->getColorbuffer();
6694 GLenum colorbufferFormat = source->getFormat();
6695 es2::Texture3D *texture = context->getTexture3D();
6696
6697 if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))
6698 {
6699 return;
6700 }
6701
6702 GLenum textureFormat = texture->getFormat(target, level);
6703
6704 if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
6705 {
6706 return;
6707 }
6708
6709 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006710 }
6711}
6712
6713void GL_APIENTRY glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
6714{
Alexis Hetub027aa92015-01-19 15:56:12 -05006715 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006716 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
Alexis Hetub027aa92015-01-19 15:56:12 -05006717 target, level, internalformat, width, height, depth, border, imageSize, data);
6718
6719 switch(target)
6720 {
6721 case GL_TEXTURE_3D_OES:
6722 break;
6723 default:
6724 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006725 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006726
6727 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6728 {
6729 return error(GL_INVALID_VALUE);
6730 }
6731
6732 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6733 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6734 {
6735 return error(GL_INVALID_VALUE);
6736 }
6737
6738 switch(internalformat)
6739 {
6740 case GL_ETC1_RGB8_OES:
6741 break;
6742 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6743 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6744 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6745 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6746 if(!S3TC_SUPPORT)
6747 {
6748 return error(GL_INVALID_ENUM);
6749 }
6750 break;
6751 case GL_DEPTH_COMPONENT:
6752 case GL_DEPTH_COMPONENT16:
6753 case GL_DEPTH_COMPONENT32_OES:
6754 case GL_DEPTH_STENCIL_OES:
6755 case GL_DEPTH24_STENCIL8_OES:
6756 return error(GL_INVALID_OPERATION);
6757 default:
6758 return error(GL_INVALID_ENUM);
6759 }
6760
Nicolas Capensdeda34b2015-04-28 15:21:53 -07006761 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
Alexis Hetub027aa92015-01-19 15:56:12 -05006762 {
6763 return error(GL_INVALID_VALUE);
6764 }
6765
6766 es2::Context *context = es2::getContext();
6767
6768 if(context)
6769 {
6770 es2::Texture3D *texture = context->getTexture3D();
6771
6772 if(!texture)
6773 {
6774 return error(GL_INVALID_OPERATION);
6775 }
6776
6777 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006778 }
6779}
6780
6781void 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)
6782{
Alexis Hetub027aa92015-01-19 15:56:12 -05006783 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6784 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006785 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006786 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6787
Alexis Hetub027aa92015-01-19 15:56:12 -05006788 switch(target)
6789 {
6790 case GL_TEXTURE_3D_OES:
6791 break;
6792 default:
6793 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006794 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006795
6796 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6797 {
6798 return error(GL_INVALID_VALUE);
6799 }
6800
6801 switch(format)
6802 {
6803 case GL_ETC1_RGB8_OES:
6804 break;
6805 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6806 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6807 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6808 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6809 if(!S3TC_SUPPORT)
6810 {
6811 return error(GL_INVALID_ENUM);
6812 }
6813 break;
6814 default:
6815 return error(GL_INVALID_ENUM);
6816 }
6817
6818 if(width == 0 || height == 0 || depth == 0 || data == NULL)
6819 {
6820 return;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006821 }
6822
Alexis Hetub027aa92015-01-19 15:56:12 -05006823 es2::Context *context = es2::getContext();
6824
6825 if(context)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006826 {
Alexis Hetub027aa92015-01-19 15:56:12 -05006827 es2::Texture3D *texture = context->getTexture3D();
6828
6829 if(!texture)
6830 {
6831 return error(GL_INVALID_OPERATION);
6832 }
6833
6834 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6835 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006836}
6837
6838void GL_APIENTRY glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
6839{
Alexis Hetub027aa92015-01-19 15:56:12 -05006840 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6841 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6842
6843 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
6844 {
6845 return error(GL_INVALID_ENUM);
6846 }
6847
6848 switch(attachment)
6849 {
6850 case GL_COLOR_ATTACHMENT0:
6851 case GL_DEPTH_ATTACHMENT:
6852 case GL_STENCIL_ATTACHMENT:
6853 break;
6854 default:
6855 return error(GL_INVALID_ENUM);
6856 }
6857
6858 es2::Context *context = es2::getContext();
6859
6860 if(context)
6861 {
6862 if(texture == 0)
6863 {
6864 textarget = GL_NONE;
6865 }
6866 else
6867 {
6868 es2::Texture *tex = context->getTexture(texture);
6869
6870 if(tex == NULL)
6871 {
6872 return error(GL_INVALID_OPERATION);
6873 }
6874
6875 if(tex->isCompressed(textarget, level))
6876 {
6877 return error(GL_INVALID_OPERATION);
6878 }
6879
6880 switch(textarget)
6881 {
6882 case GL_TEXTURE_3D_OES:
6883 if(tex->getTarget() != GL_TEXTURE_3D_OES)
6884 {
6885 return error(GL_INVALID_OPERATION);
6886 }
6887 break;
6888 default:
6889 return error(GL_INVALID_ENUM);
6890 }
6891
6892 if(level != 0)
6893 {
6894 return error(GL_INVALID_VALUE);
6895 }
6896 }
6897
6898 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006899 GLuint framebufferName = 0;
Alexis Hetub027aa92015-01-19 15:56:12 -05006900 if(target == GL_READ_FRAMEBUFFER_ANGLE)
6901 {
6902 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006903 framebufferName = context->getReadFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006904 }
6905 else
6906 {
6907 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006908 framebufferName = context->getDrawFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006909 }
6910
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006911 if(framebufferName == 0 || !framebuffer)
Alexis Hetub027aa92015-01-19 15:56:12 -05006912 {
6913 return error(GL_INVALID_OPERATION);
6914 }
6915
6916 switch(attachment)
6917 {
6918 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
6919 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
6920 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6921 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006922 }
6923}
Alexis Hetub027aa92015-01-19 15:56:12 -05006924
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006925void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
6926{
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006927 if(egl::getClientVersion() == 1)
6928 {
Nicolas Capensa2308052015-04-15 16:50:21 -04006929 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006930 }
6931
Nicolas Capens4be33702015-04-28 15:13:30 -07006932 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006933
Nicolas Capensf160b172014-11-26 11:58:23 -05006934 switch(target)
6935 {
6936 case GL_TEXTURE_2D:
6937 case GL_TEXTURE_EXTERNAL_OES:
6938 break;
6939 default:
6940 return error(GL_INVALID_ENUM);
6941 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006942
Nicolas Capensf160b172014-11-26 11:58:23 -05006943 if(!image)
6944 {
6945 return error(GL_INVALID_OPERATION);
6946 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006947
Nicolas Capensf160b172014-11-26 11:58:23 -05006948 es2::Context *context = es2::getContext();
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006949
Nicolas Capensf160b172014-11-26 11:58:23 -05006950 if(context)
6951 {
6952 es2::Texture2D *texture = 0;
Nicolas Capens08e90f02014-11-21 12:49:12 -05006953
Nicolas Capensf160b172014-11-26 11:58:23 -05006954 switch(target)
6955 {
6956 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
6957 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
6958 default: UNREACHABLE();
6959 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006960
Nicolas Capensf160b172014-11-26 11:58:23 -05006961 if(!texture)
6962 {
6963 return error(GL_INVALID_OPERATION);
6964 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006965
Nicolas Capensf160b172014-11-26 11:58:23 -05006966 egl::Image *glImage = static_cast<egl::Image*>(image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006967
Nicolas Capensf160b172014-11-26 11:58:23 -05006968 texture->setImage(glImage);
6969 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006970}
6971
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006972void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
6973{
Nicolas Capens4be33702015-04-28 15:13:30 -07006974 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006975
6976 UNIMPLEMENTED();
6977}
6978
Nicolas Capensa2308052015-04-15 16:50:21 -04006979__eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
John Bauman66b8ab22014-05-06 15:57:45 -04006980{
Nicolas Capensf160b172014-11-26 11:58:23 -05006981 struct Extension
6982 {
6983 const char *name;
6984 __eglMustCastToProperFunctionPointerType address;
6985 };
John Bauman66b8ab22014-05-06 15:57:45 -04006986
Nicolas Capensf160b172014-11-26 11:58:23 -05006987 static const Extension glExtensions[] =
6988 {
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006989 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6990
Nicolas Capensf160b172014-11-26 11:58:23 -05006991 EXTENSION(glTexImage3DOES),
6992 EXTENSION(glBlitFramebufferANGLE),
Alexis Hetue9233fb2015-02-11 10:31:58 -05006993 EXTENSION(glBlitFramebufferNV),
Nicolas Capensf160b172014-11-26 11:58:23 -05006994 EXTENSION(glRenderbufferStorageMultisampleANGLE),
6995 EXTENSION(glDeleteFencesNV),
6996 EXTENSION(glGenFencesNV),
6997 EXTENSION(glIsFenceNV),
6998 EXTENSION(glTestFenceNV),
6999 EXTENSION(glGetFenceivNV),
7000 EXTENSION(glFinishFenceNV),
7001 EXTENSION(glSetFenceNV),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007002 EXTENSION(glGetGraphicsResetStatusEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05007003 EXTENSION(glReadnPixelsEXT),
7004 EXTENSION(glGetnUniformfvEXT),
7005 EXTENSION(glGetnUniformivEXT),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007006 EXTENSION(glGenQueriesEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05007007 EXTENSION(glDeleteQueriesEXT),
7008 EXTENSION(glIsQueryEXT),
7009 EXTENSION(glBeginQueryEXT),
7010 EXTENSION(glEndQueryEXT),
7011 EXTENSION(glGetQueryivEXT),
7012 EXTENSION(glGetQueryObjectuivEXT),
7013 EXTENSION(glEGLImageTargetTexture2DOES),
Nicolas Capens7e12ac62014-11-05 17:07:53 -05007014 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
Alexis Hetue8af6d12015-04-17 16:58:45 -04007015 EXTENSION(glDrawElementsInstancedEXT),
7016 EXTENSION(glDrawArraysInstancedEXT),
7017 EXTENSION(glVertexAttribDivisorEXT),
Nicolas Capens0416e5c2015-04-28 15:30:28 -07007018 EXTENSION(glDrawArraysInstancedANGLE),
7019 EXTENSION(glDrawElementsInstancedANGLE),
Alexis Hetub4d557d2015-04-24 17:25:10 -04007020 EXTENSION(glVertexAttribDivisorANGLE),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007021
7022 #undef EXTENSION
Nicolas Capensf160b172014-11-26 11:58:23 -05007023 };
John Bauman66b8ab22014-05-06 15:57:45 -04007024
Nicolas Capensf160b172014-11-26 11:58:23 -05007025 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
7026 {
7027 if(strcmp(procname, glExtensions[ext].name) == 0)
7028 {
7029 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
7030 }
7031 }
John Bauman66b8ab22014-05-06 15:57:45 -04007032
Nicolas Capensf160b172014-11-26 11:58:23 -05007033 return NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04007034}
7035
John Baumand4ae8632014-05-06 16:18:33 -04007036void GL_APIENTRY Register(const char *licenseKey)
7037{
7038 RegisterLicenseKey(licenseKey);
7039}
7040
John Bauman66b8ab22014-05-06 15:57:45 -04007041}